[plt-scheme] sqlite:finalize statement throws unexpectedly

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Mon Oct 12 17:27:31 EDT 2009

On Mon, Oct 12, 2009 at 3:19 PM, David Storrs <david.storrs at gmail.com> wrote:
> On Mon, Oct 12, 2009 at 5:07 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>> The contract for finalize specifies #2.
> No, I got that.  I was just surprised.  It would be nice if the
> contract was (-> statement? void?) instead of (-> open-statement?
> void?).

It can cause a core dump if you finalize twice. This contract avoids
that problem without hiding the error from the programmer. There may
be other ways to avoid it in the implementation... but I prefer
exposing errors like this to programmer... just my philosophy I guess.

>> Re: #3 --- SQLite's sqlite3_finalize returns a status. I uniformly
>> turn these status values into exns. My attitude is that the C API
>> allows you to forget to handle errors but the Scheme API should never
>> fail without warning.
> Agreed, absolutely.  My thought was only that, in practice, the author
> *must* have already dealt with this error, because an exception would
> have been thrown when he tried to execute the statement in the first
> place.  The finalize is re-raising an already-dealt-with error.  For
> example:
> ;;    Assume the users table has a UNIQUE constraint on username
> (let ((stmt (prepare db "insert into users (username, password) values
> (?, ?)")))
>  (with-handlers ((sqlite:exn? (finalize stmt) (void)))
>    (run stmt 'Joe' 'pass1') ; executes fine, row is inserted
>    (run stmt 'Joe' 'pass1') ; => exn:sqlite.  This user already exists
> )
> This is a simplified version of what I was just debugging.  It took me
> a while to realize that the with-handlers was working fine; it's
> simply that the handler function was re-raising the error, when I
> expected it to ensure that the statement was finalized and then eat
> the exception.
> The way the sqlite module is currently written, one needs to wrap a
> with-handlers around every call to finalize, just in case the
> statement had problems when it was run.  That seems redundant.

I agree that it is silly that SQLite errors in this situation. I am
worried that removing the possibility of error on finalize will hide
real errors. I am not an expert on its implementation, so I trust the
API they've developed. FWIW, you can define your own finalize* that is
implicitly in a with-handlers.


> --Dks

Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University

"The glory of God is Intelligence" - D&C 93

Posted on the users mailing list.