Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -3069,17 +3069,22 @@ ** already been [sqlite3_finalize | finalized] or on one that had ** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could ** be the case that the same database connection is being used by two or ** more threads at the same moment in time. ** -** For all versions of SQLite up to and including 3.6.23.1, it was required +** For all versions of SQLite prior to 3.7.0, it was required ** after sqlite3_step() returned anything other than [SQLITE_ROW] that ** [sqlite3_reset()] be called before any subsequent invocation of ** sqlite3_step(). Failure to invoke [sqlite3_reset()] in this way would -** result in an [SQLITE_MISUSE] return from sqlite3_step(). But after -** version 3.6.23.1, sqlite3_step() began calling [sqlite3_reset()] -** automatically in this circumstance rather than returning [SQLITE_MISUSE]. +** result in an [SQLITE_MISUSE] return from sqlite3_step(). Beginning +** with version 3.7.0, sqlite3_step() began calling [sqlite3_reset()] +** automatically in this circumstance rather than returning [SQLITE_MISUSE]. +** This changed again in version 3.7.5 such that [sqlite3_reset()] is +** only invoked after an [SQLITE_BUSY] or [SQLITE_LOCKED] error return +** and in all other cases sqlite3_step() will return [SQLITE_MISUSE] if +** it is not manually reset following [SQLITE_DONE] or any error other +** than [SQLITE_BUSY] and [SQLITE_LOCKED]. ** ** Goofy Interface Alert: In the legacy interface, the sqlite3_step() ** API always returns a generic error code, [SQLITE_ERROR], following any ** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call ** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the Index: src/vdbeapi.c ================================================================== --- src/vdbeapi.c +++ src/vdbeapi.c @@ -342,16 +342,22 @@ sqlite3 *db; int rc; assert(p); if( p->magic!=VDBE_MAGIC_RUN ){ - /* We used to require that sqlite3_reset() be called before retrying - ** sqlite3_step() after any error. But after 3.6.23, we changed this - ** so that sqlite3_reset() would be called automatically instead of - ** throwing the error. - */ - sqlite3_reset((sqlite3_stmt*)p); + if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){ + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error. But after 3.6.23, we changed this + ** so that sqlite3_reset() would be called automatically instead of + ** throwing the error. Then for 3.7.5 we change it again so that + ** sqlite3_reset() would be automatically called only after BUSY and + ** LOCKED errors. + */ + sqlite3_reset((sqlite3_stmt*)p); + }else{ + return SQLITE_MISUSE_BKPT; + } } /* Check that malloc() has not failed. If it has, return early. */ db = p->db; if( db->mallocFailed ){ Index: test/capi2.test ================================================================== --- test/capi2.test +++ test/capi2.test @@ -69,16 +69,13 @@ sqlite3_step $VM } {SQLITE_DONE} do_test capi2-1.7 { list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM] } {2 {} {name rowid text INTEGER}} - -# This used to be SQLITE_MISUSE. But now we automatically reset prepared -# statements. do_test capi2-1.8 { sqlite3_step $VM -} {SQLITE_ROW} +} {SQLITE_MISUSE} # Update: In v2, once SQLITE_MISUSE is returned the statement handle cannot # be interrogated for more information. However in v3, since the column # count, names and types are determined at compile time, these are still # accessible after an SQLITE_MISUSE error. Index: test/fkey2.test ================================================================== --- test/fkey2.test +++ test/fkey2.test @@ -1414,11 +1414,11 @@ set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy] sqlite3_step $STMT } {SQLITE_CONSTRAINT} do_test fkey2-17.1.3 { sqlite3_step $STMT -} {SQLITE_CONSTRAINT} +} {SQLITE_MISUSE} do_test fkey2-17.1.4 { sqlite3_finalize $STMT } {SQLITE_CONSTRAINT} do_test fkey2-17.1.5 { execsql {