/ Check-in [6071b7cc]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When closing a connection, avoid tripping active cursors belonging to a different shared-cache client. Also, if sqlite3_close() is called while there are still active statements belonging to the connection, return SQLITE_BUSY and do not roll back any active transaction. Proposed fix for ticket [e636a050b709].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | shared-cache-fixes
Files: files | file ages | folders
SHA1: 6071b7cce067c807e040283fc4b7449dc6eca498
User & Date: dan 2013-05-15 10:21:50
Original Comment: When closing a connection, avoid tripping active cursors belonging to a different shared-cache client. Also, if sqlite3_close() is called while there are still active statements belonging to the connection, return SQLITE_BUSY and do not roll back any active transaction.
Context
2013-05-15
15:42
Merge latest trunk changes with this branch. check-in: 47dd65a8 user: dan tags: shared-cache-fixes
10:21
When closing a connection, avoid tripping active cursors belonging to a different shared-cache client. Also, if sqlite3_close() is called while there are still active statements belonging to the connection, return SQLITE_BUSY and do not roll back any active transaction. Proposed fix for ticket [e636a050b709]. check-in: 6071b7cc user: dan tags: shared-cache-fixes
2013-05-14
23:13
Merge together the fork in this branch. check-in: 164e3d4d user: drh tags: shared-cache-fixes
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/main.c.

832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849






850
851
852
853
854
855
856
  /* If a transaction is open, the disconnectAllVtab() call above
  ** will not have called the xDisconnect() method on any virtual
  ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
  ** call will do so. We need to do this before the check for active
  ** SQL statements below, as the v-table implementation may be storing
  ** some prepared statements internally.
  */
  sqlite3RollbackAll(db, SQLITE_ABORT);

  /* Legacy behavior (sqlite3_close() behavior) is to return
  ** SQLITE_BUSY if the connection can not be closed immediately.
  */
  if( !forceZombie && connectionIsBusy(db) ){
    sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
       "statements or unfinished backups");
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_BUSY;
  }







#ifdef SQLITE_ENABLE_SQLLOG
  if( sqlite3GlobalConfig.xSqllog ){
    /* Closing the handle. Fourth parameter is passed the value 2. */
    sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
  }
#endif







|










>
>
>
>
>
>







832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
  /* If a transaction is open, the disconnectAllVtab() call above
  ** will not have called the xDisconnect() method on any virtual
  ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
  ** call will do so. We need to do this before the check for active
  ** SQL statements below, as the v-table implementation may be storing
  ** some prepared statements internally.
  */
  sqlite3VtabRollback(db);

  /* Legacy behavior (sqlite3_close() behavior) is to return
  ** SQLITE_BUSY if the connection can not be closed immediately.
  */
  if( !forceZombie && connectionIsBusy(db) ){
    sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
       "statements or unfinished backups");
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_BUSY;
  }

  /* If a transaction is open, roll it back. This also ensures that if
  ** any database schemas have been modified by the current transaction
  ** they are reset. And that the required b-tree mutex is held to make
  ** the the pager rollback and schema reset an atomic operation. */
  sqlite3RollbackAll(db, SQLITE_OK);

#ifdef SQLITE_ENABLE_SQLLOG
  if( sqlite3GlobalConfig.xSqllog ){
    /* Closing the handle. Fourth parameter is passed the value 2. */
    sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
  }
#endif

Changes to test/misuse.test.

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
do_test misuse-4.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      set r [sqlite3_close $::DB]
    }
  } msg]
  lappend v $msg $r
} {1 {callback requested query abort} SQLITE_BUSY}
do_test misuse-4.4 {
  # Flush the TCL statement cache here, otherwise the sqlite3_close() will
  # fail because there are still un-finalized() VDBEs.
  db cache flush
  sqlite3_close $::DB
  catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}







|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
do_test misuse-4.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      set r [sqlite3_close $::DB]
    }
  } msg]
  lappend v $msg $r
} {0 {} SQLITE_BUSY}
do_test misuse-4.4 {
  # Flush the TCL statement cache here, otherwise the sqlite3_close() will
  # fail because there are still un-finalized() VDBEs.
  db cache flush
  sqlite3_close $::DB
  catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}