/ Check-in [b59f7bcb]
Login

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

Overview
Comment:Simplify the vdbeHalt logic slightly. (CVS 4459)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b59f7bcbabcccde9d2519e10e65e121343f2af7a
User & Date: drh 2007-10-03 18:45:04
Context
2007-10-03
20:15
Update documentation to talk about the response to errors within an explicit transaction. (CVS 4460) check-in: 84616a13 user: drh tags: trunk
18:45
Simplify the vdbeHalt logic slightly. (CVS 4459) check-in: b59f7bcb user: drh tags: trunk
15:30
Rollback the transaction if an SQLITE_FULL error is encountered. This is a preliminary fix for ticket #2686. More testing and analysis is needed before we close the ticket. (CVS 4458) check-in: 0fb6d5a5 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/vdbeaux.c.

1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
      **
      ** We could do something more elegant than this static analysis (i.e.
      ** store the type of query as part of the compliation phase), but 
      ** handling malloc() or IO failure is a fairly obscure edge case so 
      ** this is probably easier. Todo: Might be an opportunity to reduce 
      ** code size a very small amount though...
      */
      int isReadOnly = 1;
      int isStatement = 0;
      assert(p->aOp || p->nOp==0);
      for(i=0; i<p->nOp; i++){ 
        switch( p->aOp[i].opcode ){
          case OP_Transaction:
            /* This is a bit strange. If we hit a malloc() or IO error and
            ** the statement did not open a statement transaction, we will
            ** rollback any active transaction and abort all other active
            ** statements. Or, if this is an SQLITE_INTERRUPT error, we
            ** will only rollback if the interrupted statement was a write.
            **
            ** It could be argued that read-only statements should never
            ** rollback anything. But careful analysis is required before
            ** making this change
            */
            if( p->aOp[i].p2 || mrc!=SQLITE_INTERRUPT ){
              isReadOnly = 0;
            }
            break;
          case OP_Statement:
            isStatement = 1;
            break;
        }
      }

   
      /* If the query was read-only, we need do no rollback at all. Otherwise,
      ** proceed with the special handling.
      */
      if( !isReadOnly ){
        if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){
          xFunc = sqlite3BtreeRollbackStmt;
          p->rc = SQLITE_BUSY;
        } else if( (p->rc==SQLITE_NOMEM || p->rc==SQLITE_FULL) && isStatement ){
          xFunc = sqlite3BtreeRollbackStmt;
        }else{
          /* We are forced to roll back the active transaction. Before doing
          ** so, abort any other statements this handle currently has active.
          */
          invalidateCursorsOnModifiedBtrees(db);
          sqlite3RollbackAll(db);







|





<
<
<
<
<
<
<
<
<
<
<
|
<











|



|







1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406











1407

1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
      **
      ** We could do something more elegant than this static analysis (i.e.
      ** store the type of query as part of the compliation phase), but 
      ** handling malloc() or IO failure is a fairly obscure edge case so 
      ** this is probably easier. Todo: Might be an opportunity to reduce 
      ** code size a very small amount though...
      */
      int notReadOnly = 0;
      int isStatement = 0;
      assert(p->aOp || p->nOp==0);
      for(i=0; i<p->nOp; i++){ 
        switch( p->aOp[i].opcode ){
          case OP_Transaction:











            notReadOnly |= p->aOp[i].p2;

            break;
          case OP_Statement:
            isStatement = 1;
            break;
        }
      }

   
      /* If the query was read-only, we need do no rollback at all. Otherwise,
      ** proceed with the special handling.
      */
      if( notReadOnly || mrc!=SQLITE_INTERRUPT ){
        if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){
          xFunc = sqlite3BtreeRollbackStmt;
          p->rc = SQLITE_BUSY;
        } else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && isStatement ){
          xFunc = sqlite3BtreeRollbackStmt;
        }else{
          /* We are forced to roll back the active transaction. Before doing
          ** so, abort any other statements this handle currently has active.
          */
          invalidateCursorsOnModifiedBtrees(db);
          sqlite3RollbackAll(db);