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 1tJOFx-002hFg-7F for psycopg@arkaria.postgresql.org; Fri, 06 Dec 2024 02:39:49 +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 1tJOFu-009ars-1A for psycopg@arkaria.postgresql.org; Fri, 06 Dec 2024 02:39:47 +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 1tJOFt-009ark-Qh for psycopg@lists.postgresql.org; Fri, 06 Dec 2024 02:39:47 +0000 Received: from mail-yb1-xb2d.google.com ([2607:f8b0:4864:20::b2d]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1tJOFs-001HUl-5M for psycopg@lists.postgresql.org; Fri, 06 Dec 2024 02:39:45 +0000 Received: by mail-yb1-xb2d.google.com with SMTP id 3f1490d57ef6-e388503c0d7so1703236276.0 for ; Thu, 05 Dec 2024 18:39:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1733452783; x=1734057583; 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=TGj5aiBPEBTuyh/u59aYDCYslms8EGQWpN+AxYP0/jM=; b=Ifmty354MU1De3Wc2PG79yEkuBGInDGYuopTLwvjmHTK9kbIg1PEsJVQld0cvpVXqs J69L8LHUJ7p2revOX0ad5c5C4Uu1FIiRkOT0iVA4DBUSrGnsVyDcJ5nxfCasgO2scTdJ fBdUx0jILZmhAQXDr8mrBf6fFxd/ZaAfntNk06LUsKraDexswQgkdqsfyRnLERxBJJjA aODqZk0cW91/VRV77MUi3Swflb/vVwCrNmHTl1FedsiNbhiPeIAMElVVzyotDbgAm3LL /EuM+/dNsllPThcth85VVUp75SV+hMa2MquIUq/TP7jhe0Vj2j8JJ3ni6KewAUR/Ntx/ pRMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733452783; x=1734057583; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=TGj5aiBPEBTuyh/u59aYDCYslms8EGQWpN+AxYP0/jM=; b=QI4wG6O12lu+IhuYfmHm/HeUUGfJHX6uOLEFoVnM/o1tnAifE4zjPz+uc7kjeJ1djf wQdRSsNxdpBETRXzxjCqGSmnQjNdf1mNutFlbljt8yyL3qQjrvNswJVpTHf4lpGxD2ut LVa1tK6/QrWwctE4vTOvxzEiKvrAA6aAhrH0HaW+GA3h7QdcKCwA+xJBJZSLXey/gM2Q NXK6vm9Fu+DfHTC483Nh5FMIB/bBdjVK8UasMYfvHOAlB+59IHtJ05Wk3cDgERR7ZO8P +vyEreOUyqGDsfw5YAVM1qL8NvP4eOAvO6txmokjnEIgLq0VprS1kSBN212nY/YZx5Sq IG+A== X-Gm-Message-State: AOJu0Yx+2itGNiR76Uo7VvX1MJ+cFnkCOopcoJrB4KW7dY+wxCGZF0AT 2FWiMsKoiLxM2hDkRaChJaC54MQjkfjHhYT+037X3fOaJNRGfDw8qVFJ2VXcEhbqwgU+FWAWa1n SGHErsCBojFcAgUdW03v1nadgwGDBMUbV X-Gm-Gg: ASbGncv+B2Y91WlUCNwnuvb2Ompw/Eh1TojsyBAaaDUzpPZNP99IxY2tFNuC8JAv8N9 3sILf0Is+byfwR58oxKPeq+A5Qklnees= X-Google-Smtp-Source: AGHT+IHfQxf5kbiqLB8+1MKB1sPDWlTeQDuFnKNEcpKj+UNcH6NM9fYUpjt45qDj1jBV1b9W8s4By0PpIRIzBcpc3yI= X-Received: by 2002:a05:6902:2202:b0:e39:8cfe:9d36 with SMTP id 3f1490d57ef6-e3a0b0c8440mr1601882276.20.1733452783361; Thu, 05 Dec 2024 18:39:43 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Daniele Varrazzo Date: Fri, 6 Dec 2024 03:39:31 +0100 Message-ID: Subject: Re: Parameter in SQL query being misinterpreted To: Daniel Johnson Cc: psycopg@lists.postgresql.org 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, 6 Dec 2024 at 02:27, Daniel Johnson wrote: > > Good day! I've run into a quirk executing an SQL statement and am not > sure if it's a fundamental issue with my query or a bug in psycopg3. It's a mix of an issue with your query, postgres being too forgiving in parsing the interval, and psycopg 3 behaving very differently from psycopg 2. Your query assumes a literal replacement of the placeholder in the query, which was true in psycopg 2, but in psycopg 3 uses real placeholders. However it doesn't parse the query to check if a placeholder is in a string or not (arguably it shouldn't touch the ones in the strings, but no, we don't parse queries). So the %s as you have seen becomes a $4, but postgres will not replace that parameter with a value, because it will surely parse the query and will not touch the string. Arguably, Postgres should complain about a malformed interval literal, but this behaviour was probably designed in times in which the principle "be conservative in what you do, be liberal in what you accept from others" was still considered a good idea and fixing it would kill too many dinosaurs. Adrian has already provided a few workarounds for the problem you report - thank you very much!. The one I prefer is however the following, because it does without string operations: it makes use of the possibility to multiply an interval by a scalar: >>> cur.execute("select now(), now() + %s * '1 second'::interval", (10,)).fetchone() (datetime.datetime(2024, 12, 6, 2, 33, 32, 117134, tzinfo=zoneinfo.ZoneInfo(key='Europe/London')), datetime.datetime(2024, 12, 6, 2, 33, 42, 117134, tzinfo=zoneinfo.ZoneInfo(key='Europe/London'))) cheers -- Daniele