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

Overview
Comment:Remove the OP_Destroy opcode. Add an implementation for OP_Clear.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 15cf832dfc3fea91da2f13b50abfa6a7024d9614
User & Date: drh 2012-02-22 02:44:13.890
Context
2012-02-22
13:15
CREATE INDEX runs, though index queries does not work yet so there is no way to test that the index was correctly created. check-in: 70f15a5352 user: drh tags: trunk
02:44
Remove the OP_Destroy opcode. Add an implementation for OP_Clear. check-in: 15cf832dfc user: drh tags: trunk
00:11
Remove the OP_CreateTable and OP_CreateIndex opcodes, which are not required with the key/value backend. check-in: 31b1faa995 user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
** Write code to erase the table with root-page iTable from database iDb.
** Also write code to modify the sqlite_master table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/ 
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  Vdbe *v = sqlite4GetVdbe(pParse);
  int r1 = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
  sqlite4MayAbort(pParse);
  sqlite4ReleaseTempReg(pParse, r1);
}

/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).







<
|

<







1840
1841
1842
1843
1844
1845
1846

1847
1848

1849
1850
1851
1852
1853
1854
1855
** Write code to erase the table with root-page iTable from database iDb.
** Also write code to modify the sqlite_master table and internal schema
** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/ 
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  Vdbe *v = sqlite4GetVdbe(pParse);

  sqlite4VdbeAddOp2(v, OP_Clear, iTable, iDb);
  sqlite4MayAbort(pParse);

}

/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
Changes to src/vdbe.c.
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715






3716















3717
3718
3719
3720
3721
3722
3723
*/
case OP_IdxLT:          /* jump */
case OP_IdxGE: {        /* jump */
  assert( 0 );
  break;
}

/* Opcode: Destroy P1 P2 P3 * *
**
** Delete an entire database table or index whose root page in the database
** file is given by P1.
**
** The table being destroyed is in the main database file if P3==0.  If
** P3==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** See also: Clear
*/
case OP_Destroy: {     /* out2-prerelease */
  assert( 0 );
  break;
}

/* Opcode: Clear P1 P2 P3
**
** Delete all contents of the database table or index whose root page
** in the database file is given by P1.  But, unlike Destroy, do not
** remove the table or index from the database file.
**
** The table being clear is in the main database file if P2==0.  If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** If the P3 value is non-zero, then the table referred to must be an
** intkey table (an SQL table, not an index). In this case the row change 
** count is incremented by the number of rows in the table being cleared. 
** If P3 is greater than zero, then the value stored in register P3 is
** also incremented by the number of rows in the table being cleared.
**
** See also: Destroy
*/
case OP_Clear: {






  assert( 0 );















  break;
}


/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
<














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







3674
3675
3676
3677
3678
3679
3680
















3681
3682
3683
3684

3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
*/
case OP_IdxLT:          /* jump */
case OP_IdxGE: {        /* jump */
  assert( 0 );
  break;
}

















/* Opcode: Clear P1 P2 P3
**
** Delete all contents of the database table or index whose table number
** in the database file is given by P1.  

**
** The table being clear is in the main database file if P2==0.  If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** If the P3 value is non-zero, then the table referred to must be an
** intkey table (an SQL table, not an index). In this case the row change 
** count is incremented by the number of rows in the table being cleared. 
** If P3 is greater than zero, then the value stored in register P3 is
** also incremented by the number of rows in the table being cleared.
**
** See also: Destroy
*/
case OP_Clear: {
  sqlite4_uint64 cnt;
  KVCursor *pCur;
  KVByteArray *aKey;
  KVSize nKey;
  KVSize nProbe;
  KVByteArray aProbe[12];

  nProbe = sqlite4PutVarint64(aProbe, pOp->p1);
  rc = sqlite4KVStoreOpenCursor(db->aDb[pOp->p2].pKV, &pCur);
  if( rc ) break;
  rc = sqlite4KVCursorSeek(pCur, aProbe, nProbe, +1);
  while( rc!=SQLITE_NOTFOUND ){
    rc = sqlite4KVCursorKey(pCur, &aKey, &nKey);
    if( rc!=SQLITE_OK ) break;
    if( nKey<nProbe ){ rc = SQLITE_CORRUPT; break; }
    if( memcmp(aKey, aProbe, nProbe)!=0 ) break;
    rc = sqlite4KVCursorDelete(pCur);
    if( rc ) break;
    rc = sqlite4KVCursorNext(pCur);
  }
  sqlite4KVCursorClose(pCur);
  if( rc==SQLITE_NOTFOUND) rc = SQLITE_OK;
  break;
}


/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
Changes to src/vdbeaux.c.
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
** Check if the program stored in the VM associated with pParse may
** throw an ABORT exception (causing the statement, but not entire transaction
** to be rolled back). This condition is true if the main program or any
** sub-programs contains any of the following:
**
**   *  OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_Destroy
**   *  OP_VUpdate
**   *  OP_VRename
**   *  OP_FkCounter with P2==0 (immediate foreign key constraint)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
** match, or false otherwise. This function is intended to be used as
** part of an assert statement in the compiler. Similar to:
**
**   assert( sqlite4VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
*/
int sqlite4VdbeAssertMayAbort(Vdbe *v, int mayAbort){
  int hasAbort = 0;
  Op *pOp;
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
#ifndef SQLITE_OMIT_FOREIGN_KEY
     || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) 
#endif
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;







<




















|







350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
** Check if the program stored in the VM associated with pParse may
** throw an ABORT exception (causing the statement, but not entire transaction
** to be rolled back). This condition is true if the main program or any
** sub-programs contains any of the following:
**
**   *  OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.

**   *  OP_VUpdate
**   *  OP_VRename
**   *  OP_FkCounter with P2==0 (immediate foreign key constraint)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
** match, or false otherwise. This function is intended to be used as
** part of an assert statement in the compiler. Similar to:
**
**   assert( sqlite4VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
*/
int sqlite4VdbeAssertMayAbort(Vdbe *v, int mayAbort){
  int hasAbort = 0;
  Op *pOp;
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_VUpdate || opcode==OP_VRename 
#ifndef SQLITE_OMIT_FOREIGN_KEY
     || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) 
#endif
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;