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 1krqHC-0000Jx-T8 for psycopg@arkaria.postgresql.org; Tue, 22 Dec 2020 22:37:07 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1krqHB-0000NR-3E for psycopg@arkaria.postgresql.org; Tue, 22 Dec 2020 22:37:05 +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 1krqHA-0000NJ-R3 for psycopg@lists.postgresql.org; Tue, 22 Dec 2020 22:37:04 +0000 Received: from mail-lf1-x135.google.com ([2a00:1450:4864:20::135]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1krqH8-0000Lp-9E for psycopg@postgresql.org; Tue, 22 Dec 2020 22:37:03 +0000 Received: by mail-lf1-x135.google.com with SMTP id b26so26134713lff.9 for ; Tue, 22 Dec 2020 14:37:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=XGuemwYMEukV7YmWuOl3RxiS50JK6Z9YS6GSaO/TbGE=; b=N0BICSfu9xMB/sgbXtpA4u37DoiIYo8oZJ9rDxSskPzLzH11uPVvI67Yx162JM2WnG CV/tjvmnu+/iCavTlvIhSfifOEH2/rXToFlGazFlJ/byucHv4kZb75A9Nsgz2iMp8wdI 1XodGVj3W/p7xbyay+MfW11toXU2cdBCKiat2IPJDw30T2FOMeZzLaJL29gjEsUtD7t4 paEo/M5W8HvnNV0XtVAOeVO8PakNh4q14h0fhqsuhgZOFO7lLAe3OXZZLUej043NGYV9 tag6PuT7pjc0QaV8eE6MUIXkYeWCFWy6xu+tXYHBbTnb2k5qQzasthfn78iW59zm2GEB 9ZnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=XGuemwYMEukV7YmWuOl3RxiS50JK6Z9YS6GSaO/TbGE=; b=XgDL5x8h5Mf3R5jnoHbE0ryEc65jTdMtnvBGOZVeE7HC31U+1Sz/tssTt13ulaDDSr JLvqMSNO1ycvS0WkLyef3g81DgKhJFhm5ZoyoB67jAOyJOhghPqejNRBLTe5mdAvrPfb GnWVa9vO/0I2mfu5ygmkxxzzZhoZoyEGiOruwnfRhPRzcr1vIgPkzMTj++irSwyMFyTw BuVUSUdL+/TqBzGpfstBIEVJ+QglwwJellxsVy9EddKo7OZWPZxDdGkK3GKqECzeqM4Q SJ6Nlu15Mu28bqJ9HBmxLFMddr01l9T8l8PVV0Wa9qN69fNhncD1wJ6h83uv4NqFsPc1 QJiQ== X-Gm-Message-State: AOAM533Fvp6cSIcNuonU3q77YKZW4tFeO9WyAOXt9ZmjEx5GoQoRtd4n FswxDAtaxSrZ2PhMBIlUXiOWfvvwo3AhFZd/njg= X-Google-Smtp-Source: ABdhPJwm9qq3jhFcKPhtPBmoK1JM4hzThYjFGxjLIHGaoz10UA7RW3wb2SzZbiG4R/Bv0fGSzRDRgmkMx4cvBNE+DFw= X-Received: by 2002:a05:6512:2103:: with SMTP id q3mr9590825lfr.404.1608676619887; Tue, 22 Dec 2020 14:36:59 -0800 (PST) MIME-Version: 1.0 References: <25a137a0-9ad3-bb9f-b008-263dcc81a645@aklaver.com> <331f273f-fc13-8d80-b209-c94c0960268b@aklaver.com> In-Reply-To: From: Daniele Varrazzo Date: Tue, 22 Dec 2020 22:36:48 +0000 Message-ID: Subject: Re: psycopg3, prepared statements To: Vladimir Ryabtsev Cc: Adrian Klaver , psycopg@postgresql.org Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Tue, 22 Dec 2020 at 05:39, Vladimir Ryabtsev wrote: > > > it's a moment in your > > program's lifetime where you know the query to run and the arguments: > > most likely now you want to run the query too, not only to prepare it. > > I am just thinking about type issues in some edge cases... > What if the data is such that in the first row it has some small integers, > but on subsequent rows it has larger numbers that do not fit into "integer"? > There are probably other cases similar to this, including "None" values > on the moment you want to capture types... Maybe it is more reliable to > oblige the user, who knows their data better, to explicitly supply the types > for preparation... Will any type inference work in case of types mismatch? > If yes, to what extent? The only case I have thought where this can happen is with None vs. not None, in which case the oid info would be missing. Oid selection is based only on the Python type, not on the specific values (for instance Python datetime is always passed as timestamptz, never timestamp, even if the tezinfo is missing, and it relies on Postgres cast): I have avoided so far to make a choice based on the values exactly to avoid to find ourselves in this type of situations. I don't have in mind a case where a missing value would make a difference but that doesn't mean that they don't exist. What I think is that if in a certain context a NULL is acceptable and Python can pass either a None or e.g. a date, preparing witn unknown or date oid shouldn't make a difference. Of course it is possible to trigger ambiguities: trivially the query `SELECT %s` could be prepared with a date and then you can throw it a string that will make it fail. But if a placeholder is part of an expression or target for an insert I believe (but will test too) that preparing with unknown types will be equivalent. I am interested in real cases in which a prepared statement is definitely undesirable. My current idea is to make the feature automatic but with the possibility to disable it at global, connection, statement level. If there is evidence that the feature is dangerous we can leave it disabled by default and leave the possibility to enable it in the same contexts. -- Daniele > > Generally I think that automatic preparation is a great idea, but if it is achieved > by sacrificing reliability to any extent, I would prefer to have such a feature > switched off by default. > > > - if more than `connection.prepared_number` queries are prepared, the > > one used least recently is deallocated and evicted from the cache > > (proposed default: 100). > > Why do you need such logic? Why not just keep some limited number of > prepared statements? Is it a problem if a PS is in cache but rarely used? > > -- > Vlad > > > On Mon, 21 Dec 2020 at 13:55, Adrian Klaver wrote: >> >> On 12/21/20 12:26 PM, Daniele Varrazzo wrote: >> > On Mon, 21 Dec 2020 at 16:02, Adrian Klaver wrote: >> > >> >> > >> > I mistakenly replied Adrian privately. Following, his reply. >> > >> >> > I think so. Personally, I prefer the two step approach as I am becoming >> > less and less enthusiastic about hidden 'magic'. To that end a >> > global(maybe connection) setting that would disable prepare would be nice. >> > >> > ---- >> > >> > To which, 1) thank you very much, Adrian, for the plpython pointer, >> > I'll take a look at it. >> > >> > 2) About disabling the automatic prepare: the mechanism I have in mind >> > is to set prepare_threshold to None on the connection instance; >> >> So the above is something the user would have to do on each connection? >> >> > however we could make sure to have the default attribute defined on >> > the class: this way who really hates the idea of prepared statements >> > can be cheeky and set `psycopg3.Connection.prepare_threshold = None` >> >> I could get behind that. This all may be premature optimization on my >> part. As long as there is some way to turn it off at some level I could >> live with it. >> >> > instead of `myconn.prepare_threshold`... More seriously, if there is a >> > large base of people who think that something can go wrong with >> > prepared statement we can either provide a better interface to control >> > it globally or to have the feature opt-in. >> > >> > >> > -- Daniele >> > >> >> >> -- >> Adrian Klaver >> adrian.klaver@aklaver.com >> >>