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 1tCiik-00BR33-IW for pgsql-general@arkaria.postgresql.org; Sun, 17 Nov 2024 17:05:58 +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 1tCiii-000Tgc-0V for pgsql-general@arkaria.postgresql.org; Sun, 17 Nov 2024 17:05:56 +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.94.2) (envelope-from ) id 1tCiig-000TgT-Bt for pgsql-general@lists.postgresql.org; Sun, 17 Nov 2024 17:05:56 +0000 Received: from fhigh-b4-smtp.messagingengine.com ([202.12.124.155]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tCiid-002NiD-Fl for pgsql-general@lists.postgresql.org; Sun, 17 Nov 2024 17:05:53 +0000 Received: from phl-compute-02.internal (phl-compute-02.phl.internal [10.202.2.42]) by mailfhigh.stl.internal (Postfix) with ESMTP id 6AB2125400D7; Sun, 17 Nov 2024 12:05:50 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Sun, 17 Nov 2024 12:05:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aklaver.com; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm2; t=1731863150; x=1731949550; bh=OUAEcSBWLv6E64vNQt7mbRWxUHP0SXo3FdO5cXzQDxU=; b= GRy0smXwxbTRm/Hc8KP2xr1/fKtmVUI7FBgKFdiKJmasvBN66L6345Em3fswHKU0 cLxqrm9FFtkZNj9VwCUfgGZwJ/vRslxQCZhqvmLIJGCD2ct8C4CnDwz0YKRH8a27 rDkcGmkE4nN6JQ0LCJQemzKE883dRsjXmckQc/Wt2L/N6DJOefp8aYAqP5vcO5Jd Iw1EB2QNWwF+6wDJyiIYg7+Zrphhd0Hbi8Q/NP0G9SxHf5XHirSs4LOTeQ+xUnct kFNim7j/owu+YUlur4z4xnsCpyYF2eMVh9q4nUwhqpZprkB1VnRZJ5b1GpvDKNOT TSUhn5ki9qSsyatL7TSLKA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1731863150; x= 1731949550; bh=OUAEcSBWLv6E64vNQt7mbRWxUHP0SXo3FdO5cXzQDxU=; b=m d5x0s3kORVFp0f95kcQ7eMkBGEh0HyTIudOIL2MYCFQrN3zw+hsD1s0RX6jrFbFX csnaQCc+BfGNpZd2t9Pi86lGBbXNGg32Zm39GvWqbnsMyQv6RwA5DRLlL+JWvurG hQ7nH9T3B7JVMeZZUzl4hlJNwNPte40z7KoBRytZ4EXG1mEOZxfQwpkT2B27b7Ah A3FBe8HRpQ3f4ixiaA4BaJvsT1DNIHmOlBuq/G6kjDGuVijls+VD762bWkSByvJi iSqzXf4rT192XHBDYKIX02A1Ulcrk7UR1T+skWBcwv03PYhEXQNzLKT+5SzGsURN UHyIlgg0UwVhSmMELOWSw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrvdekgdeliecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnth hsucdlqddutddtmdenucfjughrpefkffggfgfuvfevfhfhjggtgfesthekredttddvjeen ucfhrhhomheptegurhhirghnucfmlhgrvhgvrhcuoegrughrihgrnhdrkhhlrghvvghrse grkhhlrghvvghrrdgtohhmqeenucggtffrrghtthgvrhhnpeekffduvdetkeejjeevfedu keegfeffuedvhfetudduteevhfehteejffehgfeifeenucffohhmrghinhepphhshigtoh hpghdrohhrghenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhr ohhmpegrughrihgrnhdrkhhlrghvvghrsegrkhhlrghvvghrrdgtohhmpdhnsggprhgtph htthhopeegpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehulhhiughtkhhosehg mhgrihhlrdgtohhmpdhrtghpthhtohepthhglhesshhsshdrphhghhdrphgrrdhushdprh gtphhtthhopegrrdhmrghnthiiihhoshestghlohhuugdrghgrthgvfigrhihnvghtrdgt ohhmpdhrtghpthhtohepphhgshhqlhdqghgvnhgvrhgrlheslhhishhtshdrphhoshhtgh hrvghsqhhlrdhorhhg X-ME-Proxy: Feedback-ID: i76984098:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun, 17 Nov 2024 12:05:47 -0500 (EST) Message-ID: Date: Sun, 17 Nov 2024 09:05:46 -0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Getting error 42P02, despite query parameter being sent To: Max Ulidtko , Tom Lane , Achilleas Mantzios Cc: pgsql-general@lists.postgresql.org References: <40d8beef-ff67-4c6c-828c-2941ca30fdef@cloud.gatewaynet.com> <2757246.1731775878@sss.pgh.pa.us> Content-Language: en-US From: Adrian Klaver In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 11/17/24 02:09, Max Ulidtko wrote: > Thanks for replies! I understand now. > > Just to clarify user-side motivation: I'm taught that concatenating data > into SQL query strings is bad practice and should be avoided. I know how > to do it safely in my particular case; but apparently the author of this > client library was taught the same, and so their query-builder doesn't Why not name the client? > provide the "raw" quoted-interpolation substitution (the analogue to > sql.Literal from Adrian example). Instead this query-builder relies on > the parameters mechanism. Per the docs: https://www.psycopg.org/psycopg3/docs/api/sql.html " class psycopg.sql.Literal(obj: Any) A Composable representing an SQL value to include in a query. Usually you will want to include placeholders in the query and pass values as execute() arguments. If however you really really need to include a literal value in the query you can use this object. The string returned by as_string() follows the normal adaptation rules for Python objects. Example: s1 = sql.Literal("fo'o") s2 = sql.Literal(42) s3 = sql.Literal(date(2000, 1, 1)) print(sql.SQL(', ').join([s1, s2, s3]).as_string(conn)) 'fo''o', 42, '2000-01-01'::date Changed in version 3.1: Add a type cast to the representation if useful in ambiguous context (e.g. '2000-01-01'::date) " It is meant to pass in a value not something else, say an identifier which is covered by sql.Identifier. The purpose of the sql module is to build dynamic SQL safely. > > Hence, this limitation forces me to rewrite my query into raw SQL, with > hand-quoting of parameter and query string concatenation. > > > if CREATE VIEW stores the Param as a Param > > This makes zero sense to me... I assumed that $1 would get substituted > *at query time*, resulting in effectively VALUES ('md5', > 'test-param-value') -- not persisted into the view definition. Which is > yes, the former option, Tom; it is sane because that's what $1 does in > every other query type. > > If I stare into the abyss regardless, and consider the latter option, > the one that makes no sense to me... I don't see how could it possibly > ever work. > > With substitution at some "later time" (expressly not CREATE VIEW query > time), how could this ever work? > > CREATE VIEW foobar_view (alg, hash) AS VALUES ('md5', $1); -- suppose > the Param is persisted into view (?!?) > > SELECT * from foobar_view where alg = $1; > — is this a 1- or 2-parameter query? > — what do both $1's refer to exactly? > * there's $1 in select query referring to values in column alg, and > * there's $1 supposedly persisted into VALUES of view definition, > referring to a different column with potentially different type. > > This makes no sense to me. > > So I'm a bit surprised that the (IMO) straightforward semantics of > substitution-at-query-time is not supported. > > Nevertheless, acknowledging the "patches welcome" status quo sentiment. > This is helpful; thanks again. > > Max > > On сб, лис 16 2024 at 11:51:18 -05:00:00, Tom Lane > wrote: >> Achilleas Mantzios > > writes: >> >> Στις 16/11/24 12:55, ο/η Max Ulidtko έγραψε: >> >> The issue I'm hitting with it is exemplified by server logs >> like this: 2024-11-16 10:28:19.928 UTC [46] LOG: execute >> : CREATE VIEW public.foobar (alg, hash) AS VALUES >> ('md5', $1); 2024-11-16 10:28:19.928 UTC [46] DETAIL: >> parameters: $1 = 'test-param-value' 2024-11-16 10:28:19.928 >> UTC [46] ERROR: there is no parameter $1 at character 57 >> >> At least for SQL level prepared statements the statement has to be >> one of : |SELECT|, |INSERT|, |UPDATE|, |DELETE|, |MERGE|, or >> |VALUES| |so CREATE is not valid, and I guess the extended >> protocol prepared statements aint no different in this regard. >> >> Indeed. To some extent this is an implementation limitation: the >> parameter is received (and printed if you have logging enabled), but >> it's not passed down to utility statements such as CREATE VIEW. But >> the reason nobody's been in a hurry to lift that restriction is that >> doing so would open a large can of semantic worms. In a case like >> CREATE VIEW, exactly what is this statement supposed to mean? I assume >> you were hoping that it would result in replacement of the Param by a >> Const representing the CREATE-time value of the parameter, but why is >> that a sane definition? It's certainly not what a Param normally does. >> On the other hand, if CREATE VIEW stores the Param as a Param (which >> is what I think would happen if we just extended the parameter-passing >> plumbing), that's unlikely to lead to a good outcome either. There >> might not be any $1 available when the view is used, and if there is >> one it's not necessarily of the right data type. So, pending some >> defensible design for what should happen and a patch implementing >> that, we've just left it at the status quo, which is that Params are >> only available to the DML statements Achilleas mentioned. regards, tom >> lane -- Adrian Klaver adrian.klaver@aklaver.com