Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n5A5p-0003zE-Ji for pgsql-interfaces@arkaria.postgresql.org; Wed, 05 Jan 2022 17:28:57 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1n5A5o-0004Hg-CX for pgsql-interfaces@arkaria.postgresql.org; Wed, 05 Jan 2022 17:28:56 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n5A5n-0004HQ-VH for pgsql-interfaces@lists.postgresql.org; Wed, 05 Jan 2022 17:28:56 +0000 Received: from mail-qt1-x82c.google.com ([2607:f8b0:4864:20::82c]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1n5A5g-0002Z5-Vu for pgsql-interfaces@lists.postgresql.org; Wed, 05 Jan 2022 17:28:54 +0000 Received: by mail-qt1-x82c.google.com with SMTP id bp39so37982005qtb.6 for ; Wed, 05 Jan 2022 09:28:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=ktha6qhuXVw8kurp2In4Xk1tZ4nXecAw3alaVyibYZs=; b=o0AkdqGEa0ZsmLR+MtIzfEJC6fxnswEltFNlQJJ6j/xob75aWD7t3Gd22mdzEGRuUY DExGGG8bazV7pLsoCNERfN7QnTSWEzpW08lod320LH4ZzWwQwybWr4racEAheKgr0UjB TLA7OJuCGyMzyanlcKuou6FBhQebwpnBGF33k8CkaGh560snhlUBi8pi0i3K1CUbfEur tyjzL8Clb7/tghNKxC1E8fCpuUnI7bJ150Hx8GEmc0aIAzvDiucNq7F4YDvX2cGiIGvy UBS+i1uwMLVDQXiA/Icss/bfFZQBpfIqyv16K9HC0GMwLOms+SK8LjeQnvwfW3TKZaLq etGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=ktha6qhuXVw8kurp2In4Xk1tZ4nXecAw3alaVyibYZs=; b=IVg/gKDiAMNGglGLHjtxliO4f2tyG2j4gbjNkLDBCnHR2rFAHz3mBhF2KjJfutMGW6 D2Wm1frxqtqt5qTUudCKeYtG+PvMxV4sy+9n/c4l9Z6RynhMVH8ZhILp+l+axj8dQ7h7 9bknmmTKamQ6fqAVGiFhoMtxqP+OfYcFzTg7PNasjtvN7XF8twSHMpGBXmPz9vLvlD4g PYXXWBVccJjP0R5LzzcDE8u7VNGv5i0+AhEQCgDglUU4RAwexsoWSNhmzzT86RI1FamY jnqDflhrtzLL5t+GpKRQelP7uQEfMKkyJ0EoWWhFLNa07JkfS0tULQue7gmie7NvdZlF 4RQg== X-Gm-Message-State: AOAM531tr5ldcP5sP44TMyL5vebvwXaGfiZlMftTPi7FQyu06+GIVUjz fnXZuUkdgZNvrWqd2AgSpjsL3j0B8CoRxO+PaG4= X-Google-Smtp-Source: ABdhPJyv1xkDGH/rkTFIhD0BOwfD9SKM1BYMhmx7EYlGv+bbLV7zrChQhy8HpdNCHuf2Eb9rUq0zvEAQue3QxDGSOOI= X-Received: by 2002:a05:622a:ca:: with SMTP id p10mr49261340qtw.89.1641403727921; Wed, 05 Jan 2022 09:28:47 -0800 (PST) MIME-Version: 1.0 References: <303861.1641402467@sss.pgh.pa.us> In-Reply-To: From: Les Date: Wed, 5 Jan 2022 18:28:37 +0100 Message-ID: Subject: Re: psycopg3 - parameters cannot be used for DDL commands? To: Dmitry Igrishin Cc: Tom Lane , pgsql-interfaces@lists.postgresql.org Content-Type: multipart/alternative; boundary="00000000000022c73005d4d91650" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000022c73005d4d91650 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Well okay, I'm obviously using python. psycopg3 does not have an escape function, they try to avoid this at all costs. Actually their documentation is very funny, at https://www.psycopg.org/psycopg3/docs/basic/params.html there are these warnings: - Don=E2=80=99t manually merge values to a query: hackers from a foreign c= ountry will break into your computer and steal not only your disks, but also yo= ur cds, leaving you only with the three most embarrassing records you ever bought. On cassette tapes. - If you use the % operator to merge values to a query, con artists will seduce your cat, who will run away taking your credit card and your sunglasses with them. - If you use + to merge a textual value to a string, bad guys in balaclava will find their way to your fridge, drink all your beer, and leave your toilet sit up and your toilet paper in the wrong orientation. - You don=E2=80=99t want to manually merge values to a query: use the prov= ided methods instead. I think I'll open an issue because it looks like manual string quoting cannot be avoided in some cases. Laszlo Dmitry Igrishin ezt =C3=ADrta (id=C5=91pont: 2022. jan.= 5., Sze, 18:19): > =D1=81=D1=80, 5 =D1=8F=D0=BD=D0=B2. 2022 =D0=B3. =D0=B2 20:07, Tom Lane <= tgl@sss.pgh.pa.us>: > > > > Les writes: > > > PostgreSQL server log: > > > > > 2022-01-05 17:35:25.831 CET [58] ERROR: syntax error at or near "$1" > at > > > character 35 > > > 2022-01-05 17:35:25.831 CET [58] STATEMENT: ALTER USER postgres WITH > > > PASSWORD $1 > > > > Yeah, as a general rule parameters can only be used in DML commands > > (SELECT/INSERT/UPDATE/DELETE). Utility commands don't support them > > because they don't have expression-evaluation capability. > > > > (Perhaps this will change someday, but don't hold your breath.) > > > > > Passwords can also contain special characters. If I can't use > parameters to > > > do this, then how should I quote them in a safe way? > > > > Most client libraries should have a function to convert an arbitrary > > string into a safely-quoted SQL literal that you can embed into the > > command. I don't know psycopg3, so I don't know what it has for that. > My C++ library, - Pgfe, - can convert any named parameter into an > arbitrary part of SQL expression by using Sql_string::replace() > method. For example: > update :foo > could be replaced to > update foo set bar =3D 'baz' where id =3D 1 > by using > s.replace("foo", R"(set bar=3D'baz' where id =3D 1)"). > --00000000000022c73005d4d91650 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Well okay, I'm obviously using python. psycopg3 d= oes not have an escape function, they try to avoid this at all costs.
=

Actually their documentation is very funny, at https://www.ps= ycopg.org/psycopg3/docs/basic/params.html there are these warnings:

  • Don=E2=80=99t manua= lly merge values to a query: hackers from a foreign country will break into your computer and steal not only your disks, but also your cds, leaving you only with the three most embarrassing records you ever bought. On cassette tapes.

  • If you use the % operator to merge values to a query, con artists will seduce your cat, who will run away taking your credit card and your sunglasses with them.

  • If you use + to merge a textual value to a string, bad guys in balaclava will find their way to your fridge, drink all your beer, and leave your toilet sit up and your toilet paper in the wrong orientation.

  • You don=E2=80=99t want to manually merge values to a query: use the provided methods instead.


I think I'll open an issue because it looks like manual string quoting= cannot be avoided in some cases.

=C2=A0=C2=A0 Las= zlo

Dmitry Igrishin <dmiti= gr@gmail.com> ezt =C3=ADrta (id=C5=91pont: 2022. jan. 5., Sze, 18:19= ):
=D1=81=D1=80,= 5 =D1=8F=D0=BD=D0=B2. 2022 =D0=B3. =D0=B2 20:07, Tom Lane <tgl@sss.pgh.pa.us>:
>
> Les <nagylzs= @gmail.com> writes:
> > PostgreSQL server log:
>
> > 2022-01-05 17:35:25.831 CET [58] ERROR:=C2=A0 syntax error at or = near "$1" at
> > character 35
> > 2022-01-05 17:35:25.831 CET [58] STATEMENT:=C2=A0 ALTER USER post= gres WITH
> > PASSWORD $1
>
> Yeah, as a general rule parameters can only be used in DML commands > (SELECT/INSERT/UPDATE/DELETE).=C2=A0 Utility commands don't suppor= t them
> because they don't have expression-evaluation capability.
>
> (Perhaps this will change someday, but don't hold your breath.) >
> > Passwords can also contain special characters. If I can't use= parameters to
> > do this, then how should I quote them in a safe way?
>
> Most client libraries should have a function to convert an arbitrary > string into a safely-quoted SQL literal that you can embed into the > command.=C2=A0 I don't know psycopg3, so I don't know what it = has for that.
My C++ library, - Pgfe, - can convert any named parameter into an
arbitrary part of SQL expression by using Sql_string::replace()
method. For example:
=C2=A0 update :foo
could be replaced to
=C2=A0 update foo set bar =3D 'baz' where id =3D 1
by using
=C2=A0 s.replace("foo", R"(set bar=3D'baz' where id = =3D 1)").
--00000000000022c73005d4d91650--