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.94.2) (envelope-from ) id 1srqsp-004ubK-SB for pgsql-general@arkaria.postgresql.org; Sat, 21 Sep 2024 03:34:09 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1srqsm-00Dx2Y-Un for pgsql-general@arkaria.postgresql.org; Sat, 21 Sep 2024 03:34:06 +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.94.2) (envelope-from ) id 1srqsl-00Dx2K-WC for pgsql-general@lists.postgresql.org; Sat, 21 Sep 2024 03:34:05 +0000 Received: from mail-4323.proton.ch ([185.70.43.23]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1srqsi-000I1o-7U for pgsql-general@lists.postgresql.org; Sat, 21 Sep 2024 03:34:04 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kortschak.io; s=protonmail; t=1726889640; x=1727148840; bh=pMnzyjz8Cvx0yCfqd9VEOQNwTsSgsqVdC7jWxxr4lsg=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=GUCyvW8kA66j/5XX0tMY5hwxzIz1dG1mI1Kqac0BozitY1UmT43AxnWe+npNCzkvA +4pqLZGiXeT7ipRaKc7Hd1zZTkzFqdDMdqJvMyi5z5A6LiBvv2MF9GGSmnWYx7DaNl HZ6gBYbOZ1c9NPx8c4D28Cv04cGi/Lw5sLnhasvZZ9KB7jzpOmj6fFKo8DTVDc+YPQ ZPW+tHNXQAhdJ1W6wbTo+zXvqH7OuEJSmpfwxrJd0jCgmTd3O5a1jwRPOB+MdD3agQ zsNEiW+61QMb/lxfUUh/43iqbXQpkk4R8J0RSiRPo+oGF21YMWsS5wuxsehWzmBj0g hH5eKfG4NIzXw== Date: Sat, 21 Sep 2024 03:33:55 +0000 To: Willow Chargin , Alban Hertroys From: Dan Kortschak Cc: pgsql-general@lists.postgresql.org Subject: Re: re-novice coming back to pgsql: porting an SQLite update statement to postgres Message-ID: <8772eb2d72658c21cce576edc1cc26cd7962c895.camel@kortschak.io> In-Reply-To: References: <1aea530e4c96109b91fdde53a29e38beb625dc77.camel@kortschak.io> <735913e4c9601a2a7ad57d2253d74451c42ba899.camel@kortschak.io> <21078220628bcebca0395a52d42b558ed965bbc0.camel@kortschak.io> <5c86256a4e83b1af73da22faab54889564e93129.camel@kortschak.io> <7320B905-E950-4035-9A13-8C9447AB52EC@gmail.com> <48019d21fd7c669afb83161337f7e007ae619534.camel@kortschak.io> <93c6b90cd39ae5fdf49cbd698e8de0c6b6f9bf3f.camel@kortschak.io> <90CC4567-4C9E-4F83-902C-A3CE5C3C74E5@gmail.com> Feedback-ID: 18519778:user:proton X-Pm-Message-ID: 3ecf1f22065389ebe0b93ba231c7234826af8f82 MIME-Version: 1.0 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 Thank you both. This has been extremely helpful. I still have more work to do but this has made it possible to start playing with something, and reading about it when it doesn't work. On Sun, 2024-09-15 at 10:13 -0700, Willow Chargin wrote: > On Sun, Sep 15, 2024 at 4:23=E2=80=AFAM Alban Hertroys > wrote: > >=20 > > The drawback is that you have to specify all fields and types, but > > you don=E2=80=99t need to cast the values all the time either. >=20 > Here is a variant of Alban's first method that does not require > specifying all fields and types, and so works with heterogeneous > values: >=20 > =C2=A0=C2=A0=C2=A0 WITH t AS ( > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 SELECT= jsonb($$[ > =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 {"a": 1, "b": -3, "c": 1}, > =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 {"a": 2, "b": -2, "c": 2}, > =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 {"a": 3, "b": -1, "c": 3}, > =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 {"a": 3, "b": -3, "c": 4} > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ]$$) a= rr > =C2=A0=C2=A0=C2=A0 ) > =C2=A0=C2=A0=C2=A0 SELECT > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 jsonb_agg(new_element ORDER BY= idx) new_arr > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FROM t, LATERAL ( > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 SELECT= idx, jsonb_object_agg(key, CASE > =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 WHEN key =3D 'a' > =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 THEN least(old_value::numeric= , 2)::text::jsonb > =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 WHEN key =3D 'b' > =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 THEN greatest(old_value::nume= ric, - > 2)::text::jsonb > =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 ELSE old_value > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 END) > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FROM > =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 jsonb_array_elements(arr) > =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 WITH ORDINALITY old_elements(= old_element, idx), > =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 jsonb_each(old_element) each(key, old_value) > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 GROUP = BY idx > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ) new_elements(idx, new_elemen= t) >=20 > I also took the liberties of using `least` / `greatest` to simplify > the > clamping operations, and using `WITH ORDINALITY` / `ORDER BY` on the > array scan and re-aggregation to make the element ordering explicit > rather than relying on the query engine to not re-order the rows. >=20 > https://www.postgresql.org/docs/16/functions-conditional.html#FUNCTIONS-G= REATEST-LEAST > https://www.postgresql.org/docs/16/queries-table-expressions.html#QUERIES= -TABLEFUNCTIONS I found that I needed to old_value::text::numeric to get Willow's code to work, but I imagine this is due to the ancientness of the postgresql I am using. thanks Dan