/ Check-in [31199db0]
Login

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

Overview
Comment:Fix another test problem and some instances where an OOM may cause a segfault.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 31199db0f77cf4b32d5589a29abd9535b155164b
User & Date: dan 2009-08-31 05:23:33
Context
2009-08-31
05:39
Merge with main branch. check-in: 6e09e287 user: dan tags: trunk
05:23
Fix another test problem and some instances where an OOM may cause a segfault. check-in: 31199db0 user: dan tags: trunk
2009-08-30
11:42
Fixes for new triggers scheme. check-in: 9eb91efd user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/trigger.c.

839
840
841
842
843
844
845
846


847
848
849
850
851
852
853
...
855
856
857
858
859
860
861

862

863
864
865
866
867
868
869
    );
#endif

    if( pTrigger->pWhen ){
      /* Code the WHEN clause. If it evaluates to false (or NULL) the 
      ** sub-vdbe is immediately halted.  */
      pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
      if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) ){


        iEndTrigger = sqlite3VdbeMakeLabel(v);
        sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
      }
      sqlite3ExprDelete(db, pWhen);
    }

    /* Code the trigger program into the sub-vdbe. */
................................................................................
    if( iEndTrigger ){
      sqlite3VdbeResolveLabel(v, iEndTrigger);
    }
    sqlite3VdbeAddOp0(v, OP_Halt);
    VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));

    transferParseError(pParse, pSubParse);

    pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pParse->nArg);

    pProgram->nMem = pSubParse->nMem;
    pProgram->nCsr = pSubParse->nTab;
    pProgram->token = (void *)pTrigger;
    pC->oldmask = pSubParse->oldmask;
    pC->newmask = pSubParse->newmask;
    sqlite3VdbeDelete(v);








|
>
>







 







>
|
>







839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
...
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
    );
#endif

    if( pTrigger->pWhen ){
      /* Code the WHEN clause. If it evaluates to false (or NULL) the 
      ** sub-vdbe is immediately halted.  */
      pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
      if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) 
       && db->mallocFailed==0 
      ){
        iEndTrigger = sqlite3VdbeMakeLabel(v);
        sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
      }
      sqlite3ExprDelete(db, pWhen);
    }

    /* Code the trigger program into the sub-vdbe. */
................................................................................
    if( iEndTrigger ){
      sqlite3VdbeResolveLabel(v, iEndTrigger);
    }
    sqlite3VdbeAddOp0(v, OP_Halt);
    VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));

    transferParseError(pParse, pSubParse);
    if( db->mallocFailed==0 ){
      pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pParse->nArg);
    }
    pProgram->nMem = pSubParse->nMem;
    pProgram->nCsr = pSubParse->nTab;
    pProgram->token = (void *)pTrigger;
    pC->oldmask = pSubParse->oldmask;
    pC->newmask = pSubParse->newmask;
    sqlite3VdbeDelete(v);

Changes to src/vdbeaux.c.

337
338
339
340
341
342
343

344
345
346
347
348
349
350
...
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
....
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363


1364
1365
1366
1367
1368
1369
1370


1371

1372
1373
1374
1375
1376
1377
1378
....
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->magic==VDBE_MAGIC_INIT );
  return p->nOp;
}

VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
  VdbeOp *aOp = p->aOp;

  resolveP2Values(p, pnMaxArg);
  *pnOp = p->nOp;
  p->aOp = 0;
  return aOp;
}

/*
................................................................................
#endif     
    }
  }
  sqlite3DbFree(db, aOp);
}

void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){

  assert( p->nRef>0 );
  if( freeop || p->nRef==1 ){
    Op *aOp = p->aOp;
    p->aOp = 0;
    vdbeFreeOpArray(db, aOp, p->nOp);
    p->nOp = 0;
  }
  p->nRef--;
  if( p->nRef==0 ){
    sqlite3DbFree(db, p);

  }
}


/*
** Change N opcodes starting at addr to No-ops.
*/
................................................................................
**
** Also release any dynamic memory held by the VM in the Vdbe.aMem memory 
** cell array. This is necessary as the memory cell array may contain
** pointers to VdbeFrame objects, which may in turn contain pointers to
** open cursors.
*/
static void closeAllCursors(Vdbe *p){
  int i;
  /* if( p->apCsr==0 ) return; */

  if( p->pFrame ){
    VdbeFrame *pFrame = p->pFrame;
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    sqlite3VdbeFrameRestore(pFrame);
  }
  p->pFrame = 0;
  p->nFrame = 0;



  for(i=0; i<p->nCursor; i++){
    VdbeCursor *pC = p->apCsr[i];
    if( pC ){
      sqlite3VdbeFreeCursor(p, pC);
      p->apCsr[i] = 0;
    }
  }


  releaseMemArray(&p->aMem[1], p->nMem);

}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
................................................................................
static void Cleanup(Vdbe *p){
  sqlite3 *db = p->db;

#ifdef SQLITE_DEBUG
  /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
  ** Vdbe.aMem[] arrays have already been cleaned up.  */
  int i;
  for(i=0; i<p->nCursor; i++){ assert( p->apCsr[i]==0 ); }
  for(i=1; i<=p->nMem; i++){ assert( p->aMem[i].flags==MEM_Null ); }
#endif

  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = 0;
  p->pResultSet = 0;
}








>







 







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







 







<
<
<








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







 







|
|







337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
...
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
....
1349
1350
1351
1352
1353
1354
1355



1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
....
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->magic==VDBE_MAGIC_INIT );
  return p->nOp;
}

VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
  VdbeOp *aOp = p->aOp;
  assert( aOp && !p->db->mallocFailed );
  resolveP2Values(p, pnMaxArg);
  *pnOp = p->nOp;
  p->aOp = 0;
  return aOp;
}

/*
................................................................................
#endif     
    }
  }
  sqlite3DbFree(db, aOp);
}

void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){
  if( p ){
    assert( p->nRef>0 );
    if( freeop || p->nRef==1 ){
      Op *aOp = p->aOp;
      p->aOp = 0;
      vdbeFreeOpArray(db, aOp, p->nOp);
      p->nOp = 0;
    }
    p->nRef--;
    if( p->nRef==0 ){
      sqlite3DbFree(db, p);
    }
  }
}


/*
** Change N opcodes starting at addr to No-ops.
*/
................................................................................
**
** Also release any dynamic memory held by the VM in the Vdbe.aMem memory 
** cell array. This is necessary as the memory cell array may contain
** pointers to VdbeFrame objects, which may in turn contain pointers to
** open cursors.
*/
static void closeAllCursors(Vdbe *p){



  if( p->pFrame ){
    VdbeFrame *pFrame = p->pFrame;
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    sqlite3VdbeFrameRestore(pFrame);
  }
  p->pFrame = 0;
  p->nFrame = 0;

  if( p->apCsr ){
    int i;
    for(i=0; i<p->nCursor; i++){
      VdbeCursor *pC = p->apCsr[i];
      if( pC ){
        sqlite3VdbeFreeCursor(p, pC);
        p->apCsr[i] = 0;
      }
    }
  }
  if( p->aMem ){
    releaseMemArray(&p->aMem[1], p->nMem);
  }
}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
................................................................................
static void Cleanup(Vdbe *p){
  sqlite3 *db = p->db;

#ifdef SQLITE_DEBUG
  /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
  ** Vdbe.aMem[] arrays have already been cleaned up.  */
  int i;
  for(i=0; i<p->nCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 );
  for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null );
#endif

  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = 0;
  p->pResultSet = 0;
}

Changes to test/attach3.test.

18
19
20
21
22
23
24





25
26
27
28
29
30
31
set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !attach {
  finish_test
  return
}






# Create tables t1 and t2 in the main database
execsql {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);
}








>
>
>
>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !attach {
  finish_test
  return
}

# The tests in this file were written before SQLite supported recursive
# trigger invocation, and some tests depend on that to pass. So disable
# recursive triggers for this file.
catchsql { pragma disable_recursive_triggers = 1 } 

# Create tables t1 and t2 in the main database
execsql {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);
}