/ Check-in [8063197e]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Ensure that if a deferred FK constraint is violated by a statement that creates its own implicit transaction, the statement is not an "active-write" after sqlite3_step() returns.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | deferred-fk-quirk
Files: files | file ages | folders
SHA1: 8063197ef141c0c62ba710efdd2b3421fbee4e5d
User & Date: dan 2011-01-24 16:00:59
Context
2011-02-04
05:47
If a deferred foreign key constraint fails on a statement that is not part of a larger transation, make sure that the statement fully ends so that subsequent invocations of the same statement will not pass the constraint because they think the transaction is not closed. This is a merge of the deferred-fk-quirk branch together with a test case. check-in: 2f94d462 user: drh tags: trunk
2011-01-24
16:00
Ensure that if a deferred FK constraint is violated by a statement that creates its own implicit transaction, the statement is not an "active-write" after sqlite3_step() returns. Closed-Leaf check-in: 8063197e user: dan tags: deferred-fk-quirk
2011-01-22
13:32
Modify the trace callback mechanism so that SQL commands executed from within virtual table or user function callbacks are passed to the trace callback without parameter expansion and enclosed in SQL comments. check-in: a764915b user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

2104
2105
2106
2107
2108
2109
2110
2111


2112
2113
2114


2115
2116
2117
2118
2119

2120
2121
2122
2123
2124
2125
2126
2127
....
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
    ** above has occurred. 
    */
    if( !sqlite3VtabInSync(db) 
     && db->autoCommit 
     && db->writeVdbeCnt==(p->readOnly==0) 
    ){
      if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
        if( sqlite3VdbeCheckFk(p, 1) ){


          sqlite3BtreeMutexArrayLeave(&p->aMutex);
          return SQLITE_ERROR;
        }


        /* The auto-commit flag is true, the vdbe program was successful 
        ** or hit an 'OR FAIL' constraint and there are no deferred foreign
        ** key constraints to hold up the transaction. This means a commit 
        ** is required.  */
        rc = vdbeCommit(db, p);

        if( rc==SQLITE_BUSY ){
          sqlite3BtreeMutexArrayLeave(&p->aMutex);
          return SQLITE_BUSY;
        }else if( rc!=SQLITE_OK ){
          p->rc = rc;
          sqlite3RollbackAll(db);
        }else{
          db->nDeferredCons = 0;
................................................................................
  ** to invoke any required unlock-notify callbacks.
  */
  if( db->autoCommit ){
    sqlite3ConnectionUnlocked(db);
  }

  assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
  return SQLITE_OK;
}


/*
** Each VDBE holds the result of the most recent sqlite3_step() call
** in p->rc.  This routine sets that result back to SQLITE_OK.
*/







|
>
>
|
|
|
>
>
|
|
|
|
|
>
|







 







|







2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
....
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
    ** above has occurred. 
    */
    if( !sqlite3VtabInSync(db) 
     && db->autoCommit 
     && db->writeVdbeCnt==(p->readOnly==0) 
    ){
      if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
        rc = sqlite3VdbeCheckFk(p, 1);
        if( rc!=SQLITE_OK ){
          if( p->readOnly ){
            sqlite3BtreeMutexArrayLeave(&p->aMutex);
            return SQLITE_ERROR;
          }
          rc = SQLITE_CONSTRAINT;
        }else{ 
          /* The auto-commit flag is true, the vdbe program was successful 
          ** or hit an 'OR FAIL' constraint and there are no deferred foreign
          ** key constraints to hold up the transaction. This means a commit 
          ** is required. */
          rc = vdbeCommit(db, p);
        }
        if( rc==SQLITE_BUSY && p->readOnly ){
          sqlite3BtreeMutexArrayLeave(&p->aMutex);
          return SQLITE_BUSY;
        }else if( rc!=SQLITE_OK ){
          p->rc = rc;
          sqlite3RollbackAll(db);
        }else{
          db->nDeferredCons = 0;
................................................................................
  ** to invoke any required unlock-notify callbacks.
  */
  if( db->autoCommit ){
    sqlite3ConnectionUnlocked(db);
  }

  assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
  return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
}


/*
** Each VDBE holds the result of the most recent sqlite3_step() call
** in p->rc.  This routine sets that result back to SQLITE_OK.
*/