summaryrefslogtreecommitdiff
path: root/lang/sql/adapter/sqlite-patches/16_bdb_deadlock.patch
blob: 52771eb271b4ef014b516adc608ec54a9846828d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
--- src/vdbe.c
+++ src/vdbe.c
@@ -1215,7 +1215,10 @@
   ** The statement transaction is never a top-level transaction.  Hence
   ** the RELEASE call below can never fail.
   */
-  assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
+  /* assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
+   * This assert does not hold true when  read/write incrblobs are used with
+   * Berkeley DB because p->iStatement is set to true in order to create a
+   * statement transaction that is donated to the incrblob cursor. BDB */
   rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
   if( NEVER(rc!=SQLITE_OK) ){
     break;
@@ -3001,7 +3004,7 @@
       goto abort_due_to_error;
     }
 
-    if( pOp->p2 && p->usesStmtJournal 
+    if( pOp->p2 && (!db->aVTrans || p->usesStmtJournal) 
      && (db->autoCommit==0 || db->nVdbeRead>1) 
     ){
       assert( sqlite3BtreeIsInTrans(pBt) );
@@ -6273,6 +6276,14 @@
   testcase( sqlite3GlobalConfig.xLog!=0 );
   sqlite3_log(rc, "statement aborts at %d: [%s] %s", 
                    pc, p->zSql, p->zErrMsg);
+  /* Force a rollback if a locked or busy error happens. BDBSQL*/
+  if ( p->rc == SQLITE_LOCKED || p->rc == SQLITE_BUSY ) {
+	p->errorAction = OE_Abort;
+	if (p->readOnly) {
+	  db->nStatement++;
+	  p->iStatement = db->nStatement + db->nSavepoint;
+	}
+  }
   sqlite3VdbeHalt(p);
   if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
   rc = SQLITE_ERROR;
--- src/vdbeblob.c
+++ src/vdbeblob.c
@@ -156,6 +156,7 @@
   Table *pTab;
   Parse *pParse = 0;
   Incrblob *pBlob = 0;
+  int iDb;
 
   flags = !!flags;                /* flags = (flags ? 1 : 0); */
   *ppBlob = 0;
@@ -259,7 +260,7 @@
     assert( pBlob->pStmt || db->mallocFailed );
     if( pBlob->pStmt ){
       Vdbe *v = (Vdbe *)pBlob->pStmt;
-      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+      iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
 
       sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
 
@@ -307,6 +308,10 @@
         pParse->nTab = 1;
         sqlite3VdbeMakeReady(v, pParse);
       }
+      /* This will prevent the statement transaction from being committed,
+       * which would invalidate the incrblob cursor. BDB */
+      if( flags )
+        v->iStatement = db->nSavepoint + 1;
     }
    
     pBlob->flags = flags;