curl -X POST --data-binary test23 http://localhost:8080/create # success
curl -X POST --data-binary test23 http://localhost:8080/create # Failed to execute insert: constraint failed
curl -X POST --data-binary test1234 http://localhost:8080/create # Failed to bind uuid: library routine called out of sequence
curl -X POST --data-binary test12345 http://localhost:8080/create # Failed to bind uuid: library routine called out of sequence
…
It looks like regardless of the return value of sqlite3_step and sqlite3_bind, you always need to call sqlite3_reset on the prepared statement, which is not what currently happens in any handler on error. This prevents that statement from being reused for the remainder of pandabin's lifetime.
Speculation: even in SERIALIZED mode, it should be possible to trigger SQLITE_MISUSE by racing multiple threads on the same prepared statement. I think the only safe way to handle this case is to not share prepared statements and database handles between threads.
Sample reproduction:
It looks like regardless of the return value of
sqlite3_step
andsqlite3_bind
, you always need to callsqlite3_reset
on the prepared statement, which is not what currently happens in any handler on error. This prevents that statement from being reused for the remainder of pandabin's lifetime.Speculation: even in
SERIALIZED
mode, it should be possible to triggerSQLITE_MISUSE
by racing multiple threads on the same prepared statement. I think the only safe way to handle this case is to not share prepared statements and database handles between threads.