marijnh / Postmodern

A Common Lisp PostgreSQL programming interface
http://marijnhaverbeke.nl/postmodern
Other
400 stars 90 forks source link

Prepared statements unusable for the first time in a transaction? #357

Closed myrkraverk closed 3 months ago

myrkraverk commented 3 months ago

Hi,

As far as I can tell, prepared statements are unusable for the first time inside transactions, because the function is hardcoded to drop a prepared statement that doesn't exist. For the record, I'm using Quicklisp Postmodern, but code inspection indicates it's also a problem in GH.

This is how I reproduce it.

(connect-toplevel db nm pw hn :port 5432 :use-binary t)
(setf one-fn (prepare "select 1" :single))
(with-transaction () (funcall one-fn))

This results in a 25P02 error, because something previously inside the transaction failed [the aforementioned drop prepared statement]. Obviously, this works if I do the funcall outside a transaction, and also inside a transaction if I've done the funcall once prior.

Is this expected behaviour? Or a way to fix it in client code?

sabracrolleton commented 3 months ago

Does the following work for you?

(setf *allow-overwriting-prepared-statements* nil)

(with-connection '(db nm pw hn)
    (defprepared 'dp1 "select 1" :single)
    (with-transaction () 
      (funcall 'dp1)))
sabracrolleton commented 3 months ago

Or, more similar to what you were doing:

(setf *allow-overwriting-prepared-statements* nil)

(with-connection '(db nm pw hn)
    (let ((one-fn (prepare "select 1" :single)))
         (with-transaction ()
              (funcall one-fn))))
sabracrolleton commented 3 months ago

Have now committed a change such that the function generate-prepared will only call drop-prepared-statement when that prepared statement exists. See file Postmodern/postmodern/prepare.lisp. Let us know if this does not solve your problem.

myrkraverk commented 3 months ago

Yes, that is working for me; I never tested the workarounds from earlier, and as of commit #358 everything seems to be working fine.

Thank you.