File: 16_bdb_deadlock.patch

package info (click to toggle)
db5.3 5.3.28%2Bdfsg1-0.5
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 158,360 kB
  • sloc: ansic: 448,411; java: 111,824; tcl: 80,544; sh: 44,326; cs: 33,697; cpp: 21,604; perl: 14,557; xml: 10,799; makefile: 4,077; yacc: 1,003; awk: 965; sql: 801; erlang: 342; python: 216; php: 24; asm: 14
file content (74 lines) | stat: -rw-r--r-- 2,704 bytes parent folder | download | duplicates (7)
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
69
70
71
72
73
74
--- src/vdbe.c
+++ src/vdbe.c
@@ -1112,7 +1112,10 @@ case OP_ResultRow: {
   ** 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;
@@ -2786,9 +2781,12 @@ case OP_Transaction: {
       goto abort_due_to_error;
     }
 
-    if( pOp->p2 && p->usesStmtJournal 
+    /*if( pOp->p2 && p->usesStmtJournal 
      && (db->autoCommit==0 || db->activeVdbeCnt>1) 
-    ){
+    ){*/
+    /* In Berkeley DB create a statement transaction for every update 
+     * statement.  BDB */
+    if ( pOp->p2 && (db->autoCommit==0 || db->activeVdbeCnt>1)) {
       assert( sqlite3BtreeIsInTrans(pBt) );
       if( p->iStatement==0 ){
         assert( db->nStatement>=0 && db->nSavepoint>=0 );
@@ -5907,6 +5913,14 @@ vdbe_error_halt:
   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
@@ -155,6 +155,7 @@ int sqlite3_blob_open(
   Table *pTab;
   Parse *pParse = 0;
   Incrblob *pBlob = 0;
+  int iDb;
 
   flags = !!flags;                /* flags = (flags ? 1 : 0); */
   *ppBlob = 0;
@@ -254,7 +255,7 @@ int sqlite3_blob_open(
     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);
 
@@ -298,6 +299,10 @@ int sqlite3_blob_open(
       if( !db->mallocFailed ){
         sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0);
       }
+      /* 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;