/ Check-in [010f7b78]
Login

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

Overview
Comment:Additional test coverage improvements. Test coverage now stands at 98.73%. (CVS 4731)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:010f7b780cb9c8f21af9ce810494fbd2be98a13f
User & Date: drh 2008-01-19 23:50:26
Context
2008-01-20
23:19
Add the RTRIM collating sequence. Only implemented for UTF8. Still considered experimental and may be removed if we find adverse impact elsewhere in the system. (CVS 4732) check-in: 0bf4e7fe user: drh tags: trunk
2008-01-19
23:50
Additional test coverage improvements. Test coverage now stands at 98.73%. (CVS 4731) check-in: 010f7b78 user: drh tags: trunk
20:11
Miscellaneous code simplifications and cleanup and test coverage enhancements. (CVS 4730) check-in: af129b6d user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1743
1744
1745
1746
1747
1748
1749


1750
1751
1752
1753
1754
1755

1756
1757
1758
1759
1760
1761
1762
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.436 2008/01/02 11:50:51 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(BtShared *pBt){
  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
    if( sqlite3PagerRefcount(pBt->pPager)>=1 ){


      if( pBt->pPage1->aData==0 ){
        MemPage *pPage = pBt->pPage1;
        pPage->aData = sqlite3PagerGetData(pPage->pDbPage);
        pPage->pBt = pBt;
        pPage->pgno = 1;
      }

      releasePage(pBt->pPage1);
    }
    pBt->pPage1 = 0;
    pBt->inStmt = 0;
  }
}








|







 







>
>






>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.437 2008/01/19 23:50:26 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(BtShared *pBt){
  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
    if( sqlite3PagerRefcount(pBt->pPager)>=1 ){
      assert( pBt->pPage1->aData );
#if 0
      if( pBt->pPage1->aData==0 ){
        MemPage *pPage = pBt->pPage1;
        pPage->aData = sqlite3PagerGetData(pPage->pDbPage);
        pPage->pBt = pBt;
        pPage->pgno = 1;
      }
#endif
      releasePage(pBt->pPage1);
    }
    pBt->pPage1 = 0;
    pBt->inStmt = 0;
  }
}

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236

1237
1238

1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
....
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440

2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.350 2008/01/18 14:08:24 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
  }

  /*
  ** cnt==0 means there was not match.  cnt>1 means there were two or
  ** more matches.  Either way, we have an error.
  */
  if( cnt!=1 ){
    char *z = 0;
    char *zErr;
    zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
    if( zDb ){
      sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0);

    }else if( zTab ){
      sqlite3SetString(&z, zTab, ".", zCol, (char*)0);

    }else{
      z = sqlite3StrDup(zCol);

    }
    if( z ){
      sqlite3ErrorMsg(pParse, zErr, z);
      sqlite3_free(z);
      pTopNC->nErr++;
    }else{
      db->mallocFailed = 1;
    }
  }

  /* If a column from a table in pSrcList is referenced, then record
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  If the
  ** column number is greater than the number of bits in the bitmask
  ** then set the high-order bit of the bitmask.
................................................................................
    sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
  }
  return target;
}

/*
** Generate code that evalutes the given expression and puts the result
** in register target.  If target==-1, then allocate a temporary register
** in which to store the result.  In either case, return the register
** number where the result is stored.
**
** Also make a copy of the expression results into another "cache" register
** and modify the expression so that the next time it is evaluated,
** the result is a copy of the cache register.
**
** This routine is used for expressions that are used multiple 
** times.  They are evaluated once and the results of the expression
** are reused.
*/
int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
  Vdbe *v = pParse->pVdbe;
  int inReg;
  inReg = sqlite3ExprCode(pParse, pExpr, target);

  if( pExpr->op!=TK_REGISTER ){  
    int iMem;
    if( target<0 ){
      iMem = inReg;
    }else{
      iMem = ++pParse->nMem;
      sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
    }
    pExpr->iTable = iMem;
    pExpr->op = TK_REGISTER;
  }
  return inReg;
}









|







 







<
|
|

<
>

<
>

<
>

<
<
<
|
<
<
<







 







|
<
<













>


<
<
<
|
|
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232

1233
1234

1235
1236

1237
1238



1239



1240
1241
1242
1243
1244
1245
1246
....
2411
2412
2413
2414
2415
2416
2417
2418


2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434



2435
2436

2437
2438
2439
2440
2441
2442
2443
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.351 2008/01/19 23:50:26 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
  }

  /*
  ** cnt==0 means there was not match.  cnt>1 means there were two or
  ** more matches.  Either way, we have an error.
  */
  if( cnt!=1 ){

    const char *zErr;
    zErr = cnt==0 ? "no such column" : "ambiguous column name";
    if( zDb ){

      sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
    }else if( zTab ){

      sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
    }else{

      sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
    }



    pTopNC->nErr++;



  }

  /* If a column from a table in pSrcList is referenced, then record
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  If the
  ** column number is greater than the number of bits in the bitmask
  ** then set the high-order bit of the bitmask.
................................................................................
    sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
  }
  return target;
}

/*
** Generate code that evalutes the given expression and puts the result
** in register target.


**
** Also make a copy of the expression results into another "cache" register
** and modify the expression so that the next time it is evaluated,
** the result is a copy of the cache register.
**
** This routine is used for expressions that are used multiple 
** times.  They are evaluated once and the results of the expression
** are reused.
*/
int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
  Vdbe *v = pParse->pVdbe;
  int inReg;
  inReg = sqlite3ExprCode(pParse, pExpr, target);
  assert( target>0 );
  if( pExpr->op!=TK_REGISTER ){  
    int iMem;



    iMem = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);

    pExpr->iTable = iMem;
    pExpr->op = TK_REGISTER;
  }
  return inReg;
}


Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.181 2007/12/13 21:54:11 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

................................................................................
  for(i=0; i<nArg; i++){
    char const *z = (char*)sqlite3_value_text(argv[i]);
    if( z ){
      char *zAux = sqlite3_get_auxdata(pCtx, i);
      if( zAux ){
        zRet[i*2] = '1';
        if( strcmp(zAux, z) ){
          sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
          return;
        }
      }else {
        zRet[i*2] = '0';
      }

      zAux = contextMalloc(pCtx, strlen(z)+1);







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.182 2008/01/19 23:50:26 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

................................................................................
  for(i=0; i<nArg; i++){
    char const *z = (char*)sqlite3_value_text(argv[i]);
    if( z ){
      char *zAux = sqlite3_get_auxdata(pCtx, i);
      if( zAux ){
        zRet[i*2] = '1';
        if( strcmp(zAux, z) ){
          sqlite3_result_error(pCtx, "auxdata corruption", -1);
          return;
        }
      }else {
        zRet[i*2] = '0';
      }

      zAux = contextMalloc(pCtx, strlen(z)+1);

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
2370
2371
2372
2373
2374
2375
2376




2377
2378
2379
2380
2381
2382
2383
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.283 2008/01/19 20:11:26 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  Tcl_ListObjAppendElement(interp, pX, 
      Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
  Tcl_EvalObjEx(interp, pX, 0);
  Tcl_DecrRefCount(pX);
  pVal = sqlite3ValueNew(0);
  sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 
      SQLITE_UTF8, SQLITE_STATIC);




  sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
      -1, SQLITE_TRANSIENT);
  sqlite3ValueFree(pVal);
}
#endif /* SQLITE_OMIT_UTF16 */
static int test_function(
  void * clientData,







|







 







>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.284 2008/01/19 23:50:26 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  Tcl_ListObjAppendElement(interp, pX, 
      Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
  Tcl_EvalObjEx(interp, pX, 0);
  Tcl_DecrRefCount(pX);
  pVal = sqlite3ValueNew(0);
  sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 
      SQLITE_UTF8, SQLITE_STATIC);
  sqlite3_result_text16(pCtx, sqlite3_value_text16le(pVal),
      -1, SQLITE_TRANSIENT);
  sqlite3_result_text16be(pCtx, sqlite3_value_text16le(pVal),
      -1, SQLITE_TRANSIENT);
  sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
      -1, SQLITE_TRANSIENT);
  sqlite3ValueFree(pVal);
}
#endif /* SQLITE_OMIT_UTF16 */
static int test_function(
  void * clientData,

Changes to src/test3.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.88 2007/12/07 18:55:29 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

................................................................................

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TextToPtr(argv[1]);
#ifdef SQLITE_DEBUG
  sqlite3BtreeEnter(pBt);
  sqlite3PagerRefdump(sqlite3BtreePager(pBt));
  sqlite3BtreeLeave(pBt);
#endif
  return TCL_OK;
}








|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.89 2008/01/19 23:50:26 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

................................................................................

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TextToPtr(argv[1]);
#ifdef SQLITE_TEST
  sqlite3BtreeEnter(pBt);
  sqlite3PagerRefdump(sqlite3BtreePager(pBt));
  sqlite3BtreeLeave(pBt);
#endif
  return TCL_OK;
}

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383

3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411

3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
....
4498
4499
4500
4501
4502
4503
4504
4505

4506

4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534


4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
....
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591

4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.701 2008/01/19 20:11:26 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
/* Opcode: RowData P1 P2 * * *
**
** Write into register P2 the complete row data for cursor P1.
** There is no interpretation of the data.  
** It is just copied onto the P2 register exactly as 
** it is found in the database file.
**
** If the cursor is not pointing to a valid row, a NULL value is
** written into P2.
*/
/* Opcode: RowKey P1 P2 * * *
**
** Write into register P2 the complete row key for cursor P1.
** There is no interpretation of the data.  
** The key is copied onto the P3 register exactly as 
** it is found in the database file.
**
** If the cursor is not pointing to a valid row, a NULL is
** written into P2.
*/
case OP_RowKey:             /* out2-prerelease */
case OP_RowData: {          /* out2-prerelease */
  int i = pOp->p1;
  Cursor *pC;

  u32 n;

  /* Note that RowKey and RowData are really exactly the same instruction */
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC->isTable || pOp->opcode==OP_RowKey );
  assert( pC->isIndex || pOp->opcode==OP_RowData );
  assert( pC!=0 );
  if( pC->nullRow ){
    pOut->flags = MEM_Null;
  }else if( pC->pCursor!=0 ){
    BtCursor *pCrsr = pC->pCursor;
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->isIndex ){
      i64 n64;
      assert( !pC->isTable );
      sqlite3BtreeKeySize(pCrsr, &n64);
      if( n64>SQLITE_MAX_LENGTH ){
        goto too_big;
      }
      n = n64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &n);
    }
    if( n>SQLITE_MAX_LENGTH ){
      goto too_big;
    }

    pOut->n = n;
    if( n<=NBFS ){
      pOut->flags = MEM_Blob | MEM_Short;
      pOut->z = pOut->zShort;
    }else{
      char *z = sqlite3_malloc( n );
      if( z==0 ) goto no_mem;
      pOut->flags = MEM_Blob | MEM_Dyn;
      pOut->xDel = 0;
      pOut->z = z;
    }
    if( pC->isIndex ){
      rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
    }else{
      rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
    }
  }else{
    assert( pC->pseudoTable );
    pOut->n = pC->nData;
    assert( pC->nData<=SQLITE_MAX_LENGTH );
    pOut->z = pC->pData;
    pOut->flags = MEM_Blob|MEM_Ephem;
  }
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Rowid P1 P2 * * *
................................................................................
/* Opcode: VRowid P1 P2 * * *
**
** Store into register P2  the rowid of
** the virtual-table that the P1 cursor is pointing to.
*/
case OP_VRowid: {             /* out2-prerelease */
  const sqlite3_module *pModule;


  Cursor *pCur = p->apCsr[pOp->p1];

  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xRowid==0 ){
    sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xRowid", 0);
    rc = SQLITE_ERROR;
  } else {
    sqlite_int64 iRow;

    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
    pOut->flags = MEM_Int;
    pOut->u.i = iRow;
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
**
** Store the value of the P2-th column of
** the row of the virtual-table that the 
** P1 cursor is pointing to into register P3.
*/
case OP_VColumn: {
  const sqlite3_module *pModule;



  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xColumn==0 ){
    sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0);
    rc = SQLITE_ERROR;
  } else {
    Mem *pDest;
    sqlite3_context sContext;
    memset(&sContext, 0, sizeof(sContext));
    sContext.s.flags = MEM_Null;
    sContext.s.db = db;
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);

    /* Copy the result of the function to the P3 register. We
    ** do this regardless of whether or not an error occured to ensure any
    ** dynamic allocation in sContext.s (a Mem struct) is  released.
    */
    sqlite3VdbeChangeEncoding(&sContext.s, encoding);
    assert( pOp->p3>0 && pOp->p3<=p->nMem );
    pDest = &p->aMem[pOp->p3];
    REGISTER_TRACE(pOp->p3, pDest);
    sqlite3VdbeMemMove(pDest, &sContext.s);
    UPDATE_MAX_BLOBSIZE(pDest);

    if( sqlite3SafetyOn(db) ){
      goto abort_due_to_misuse;
    }
    if( sqlite3VdbeMemTooBig(pDest) ){
      goto too_big;
    }
  }
  
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VNext P1 P2 * * *
**
................................................................................
case OP_VNext: {   /* jump */
  const sqlite3_module *pModule;
  int res = 0;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xNext==0 ){
    sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xNext", 0);
    rc = SQLITE_ERROR;
  } else {

    /* Invoke the xNext() method of the module. There is no way for the
    ** underlying implementation to return an error if one occurs during
    ** xNext(). Instead, if an error occurs, true is returned (indicating that 
    ** data is available) and the error code returned when xColumn or
    ** some other method is next invoked on the save virtual table cursor.
    */
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    p->inVtabMethod = 1;
    rc = pModule->xNext(pCur->pVtabCursor);
    p->inVtabMethod = 0;
    if( rc==SQLITE_OK ){
      res = pModule->xEof(pCur->pVtabCursor);
    }
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;

    if( !res ){
      /* If there is data, jump to P2 */
      pc = pOp->p2 - 1;
    }
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRename P1 * * P4 *
**







|







 







|
|








|
|





>








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



>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<







 







<
>

>


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













>
>




|
<
<
<
<
<
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
<
<







 







|
<
<
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
<
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408

3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427







3428
3429
3430
3431
3432
3433
3434
....
4492
4493
4494
4495
4496
4497
4498

4499
4500
4501
4502
4503
4504





4505
4506
4507
4508
4509


4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529





4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552


4553
4554
4555
4556
4557
4558
4559
....
4564
4565
4566
4567
4568
4569
4570
4571



4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591


4592
4593
4594
4595
4596
4597
4598
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.702 2008/01/19 23:50:26 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
/* Opcode: RowData P1 P2 * * *
**
** Write into register P2 the complete row data for cursor P1.
** There is no interpretation of the data.  
** It is just copied onto the P2 register exactly as 
** it is found in the database file.
**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
*/
/* Opcode: RowKey P1 P2 * * *
**
** Write into register P2 the complete row key for cursor P1.
** There is no interpretation of the data.  
** The key is copied onto the P3 register exactly as 
** it is found in the database file.
**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
*/
case OP_RowKey:             /* out2-prerelease */
case OP_RowData: {          /* out2-prerelease */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  u32 n;

  /* Note that RowKey and RowData are really exactly the same instruction */
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC->isTable || pOp->opcode==OP_RowKey );
  assert( pC->isIndex || pOp->opcode==OP_RowData );
  assert( pC!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTable==0 );
  assert( pC->pCursor!=0 );
  pCrsr = pC->pCursor;
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  if( pC->isIndex ){
    i64 n64;
    assert( !pC->isTable );
    sqlite3BtreeKeySize(pCrsr, &n64);
    if( n64>SQLITE_MAX_LENGTH ){
      goto too_big;
    }
    n = n64;
  }else{
    sqlite3BtreeDataSize(pCrsr, &n);

    if( n>SQLITE_MAX_LENGTH ){
      goto too_big;
    }
  }
  pOut->n = n;
  if( n<=NBFS ){
    pOut->flags = MEM_Blob | MEM_Short;
    pOut->z = pOut->zShort;
  }else{
    char *z = sqlite3_malloc( n );
    if( z==0 ) goto no_mem;
    pOut->flags = MEM_Blob | MEM_Dyn;
    pOut->xDel = 0;
    pOut->z = z;
  }
  if( pC->isIndex ){
    rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
  }else{
    rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);







  }
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Rowid P1 P2 * * *
................................................................................
/* Opcode: VRowid P1 P2 * * *
**
** Store into register P2  the rowid of
** the virtual-table that the P1 cursor is pointing to.
*/
case OP_VRowid: {             /* out2-prerelease */
  const sqlite3_module *pModule;

  sqlite_int64 iRow;
  Cursor *pCur = p->apCsr[pOp->p1];

  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  assert( pModule->xRowid );





  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  pOut->flags = MEM_Int;
  pOut->u.i = iRow;


  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
**
** Store the value of the P2-th column of
** the row of the virtual-table that the 
** P1 cursor is pointing to into register P3.
*/
case OP_VColumn: {
  const sqlite3_module *pModule;
  Mem *pDest;
  sqlite3_context sContext;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  assert( pModule->xColumn );





  memset(&sContext, 0, sizeof(sContext));
  sContext.s.flags = MEM_Null;
  sContext.s.db = db;
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);

  /* Copy the result of the function to the P3 register. We
  ** do this regardless of whether or not an error occured to ensure any
  ** dynamic allocation in sContext.s (a Mem struct) is  released.
  */
  sqlite3VdbeChangeEncoding(&sContext.s, encoding);
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pDest = &p->aMem[pOp->p3];
  REGISTER_TRACE(pOp->p3, pDest);
  sqlite3VdbeMemMove(pDest, &sContext.s);
  UPDATE_MAX_BLOBSIZE(pDest);

  if( sqlite3SafetyOn(db) ){
    goto abort_due_to_misuse;
  }
  if( sqlite3VdbeMemTooBig(pDest) ){
    goto too_big;
  }


  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VNext P1 P2 * * *
**
................................................................................
case OP_VNext: {   /* jump */
  const sqlite3_module *pModule;
  int res = 0;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  assert( pModule->xNext );




  /* Invoke the xNext() method of the module. There is no way for the
  ** underlying implementation to return an error if one occurs during
  ** xNext(). Instead, if an error occurs, true is returned (indicating that 
  ** data is available) and the error code returned when xColumn or
  ** some other method is next invoked on the save virtual table cursor.
  */
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  p->inVtabMethod = 1;
  rc = pModule->xNext(pCur->pVtabCursor);
  p->inVtabMethod = 0;
  if( rc==SQLITE_OK ){
    res = pModule->xEof(pCur->pVtabCursor);
  }
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;

  if( !res ){
    /* If there is data, jump to P2 */
    pc = pOp->p2 - 1;
  }


  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRename P1 * * P4 *
**

Changes to test/btree.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is btree database backend
#
# $Id: btree.test,v 1.41 2007/09/06 22:19:15 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable default_autovacuum {
  finish_test
................................................................................
  btree_insert $::c1 2020 $data
} {}
btree_page_dump $::b1 1
btree_page_dump $::b1 2
do_test btree-8.1.1 {
  lindex [btree_pager_stats $::b1] 1
} {1}
#btree_pager_ref_dump $::b1
do_test btree-8.2 {
  btree_move_to $::c1 2020
  string length [btree_data $::c1]
} [string length $::data]
do_test btree-8.3 {
  btree_data $::c1
} $::data







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is btree database backend
#
# $Id: btree.test,v 1.42 2008/01/19 23:50:26 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable default_autovacuum {
  finish_test
................................................................................
  btree_insert $::c1 2020 $data
} {}
btree_page_dump $::b1 1
btree_page_dump $::b1 2
do_test btree-8.1.1 {
  lindex [btree_pager_stats $::b1] 1
} {1}
btree_pager_ref_dump $::b1
do_test btree-8.2 {
  btree_move_to $::c1 2020
  string length [btree_data $::c1]
} [string length $::data]
do_test btree-8.3 {
  btree_data $::c1
} $::data

Changes to test/capi3c.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1169
1170
1171
1172
1173
1174
1175



1176



1177
1178



1179
1180
1181
1182
1183
1184
1185
1186



1187
1188
1189
1190
1191
1192
1193
#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This is a copy of the capi3.test file that has been adapted to
# test the new sqlite3_prepare_v2 interface.
#
# $Id: capi3c.test,v 1.13 2007/12/13 21:54:11 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
  sqlite3_step $STMT
} SQLITE_DONE
do_test capi3c-19.4 {
  sqlite3_reset $STMT
  db eval {DROP TABLE t3}
  sqlite3_step $STMT
} SQLITE_SCHEMA



do_test capi3c-19.4.2 {



  sqlite3_errmsg $DB
} {no such table: t3}



do_test capi3c-19.5 {
  sqlite3_reset $STMT
  db eval {
     CREATE TABLE t3(x,y);
     INSERT INTO t3 VALUES(1,2);
  }
  sqlite3_step $STMT
} SQLITE_ROW



do_test capi3c-19.6 {
  sqlite3_column_int $STMT 1
} 2
do_test capi3c-19.99 {
  sqlite3_finalize $STMT
} SQLITE_OK








|







 







>
>
>

>
>
>


>
>
>








>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This is a copy of the capi3.test file that has been adapted to
# test the new sqlite3_prepare_v2 interface.
#
# $Id: capi3c.test,v 1.14 2008/01/19 23:50:26 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
  sqlite3_step $STMT
} SQLITE_DONE
do_test capi3c-19.4 {
  sqlite3_reset $STMT
  db eval {DROP TABLE t3}
  sqlite3_step $STMT
} SQLITE_SCHEMA
do_test capi3c-19.4.1 {
  sqlite3_errmsg $DB
} {no such table: t3}
do_test capi3c-19.4.2 {
  sqlite3_expired $STMT
} 1
do_test capi3c-19.4.3 {
  sqlite3_errmsg $DB
} {no such table: t3}
do_test capi3c-19.4.4 {
  sqlite3_expired 0
} 1
do_test capi3c-19.5 {
  sqlite3_reset $STMT
  db eval {
     CREATE TABLE t3(x,y);
     INSERT INTO t3 VALUES(1,2);
  }
  sqlite3_step $STMT
} SQLITE_ROW
do_test capi3c-19.5.2 {
  sqlite3_expired $STMT
} 0
do_test capi3c-19.6 {
  sqlite3_column_int $STMT 1
} 2
do_test capi3c-19.99 {
  sqlite3_finalize $STMT
} SQLITE_OK

Changes to test/enc3.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
73
74
75
76
77
78
79

80




















81
#
#***********************************************************************
# This file implements regression tests for SQLite library. 
#
# The focus of this file is testing of the proper handling of conversions
# to the native text representation.
#
# $Id: enc3.test,v 1.6 2007/05/10 21:14:03 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {utf16} {
  do_test enc3-1.1 {
    execsql {
................................................................................
  do_test enc3-2.4 {
    execsql {
      SELECT rowid FROM t2 WHERE a LIKE x'610062002500';
    }
  } {1}
}























finish_test







|







 







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

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#
#***********************************************************************
# This file implements regression tests for SQLite library. 
#
# The focus of this file is testing of the proper handling of conversions
# to the native text representation.
#
# $Id: enc3.test,v 1.7 2008/01/19 23:50:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {utf16} {
  do_test enc3-1.1 {
    execsql {
................................................................................
  do_test enc3-2.4 {
    execsql {
      SELECT rowid FROM t2 WHERE a LIKE x'610062002500';
    }
  } {1}
}

# Try to attach a database with a different encoding.
#
ifcapable {utf16} {
  file delete -force test8.db test8.db-journal
  sqlite3 dbaux test8.db
  do_test enc3-3.1 {
    dbaux eval {
      PRAGMA encoding='utf8';
      CREATE TABLE t1(x);
      PRAGMA encoding
    }
  } {UTF-8}
  do_test enc3-3.2 {
    catchsql {
      ATTACH 'test.db' AS utf16;
      SELECT 1 FROM utf16.sqlite_master LIMIT 1;
    } dbaux
  } {1 {attached databases must use the same text encoding as main database}}
  catch {dbaux close}
  file delete -force test8.db test8.db-journal
}

finish_test

Changes to test/ioerr3.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
28
29
30
31
32
33
34




35
36
37
38
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# in conjunction with very small soft-heap-limit values.
#
# $Id: ioerr3.test,v 1.1 2007/12/19 09:20:42 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_ioerr_test ioerr3-1 -sqlprep {
  CREATE TABLE t1(id INTEGER, name TEXT);
} -tclbody {
................................................................................
      INSERT INTO t1(id, name) VALUES (1,
'A1234567890B1234567890C1234567890D1234567890E1234567890F1234567890G1234567890H1234567890I1234567890J1234567890K1234567890L1234567890M1234567890N1234567890O1234567890P1234567890Q1234567890R1234567890'
      );
    }
  }
  execsql COMMIT
}





sqlite3_soft_heap_limit 0

finish_test







|







 







>
>
>
>




8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# in conjunction with very small soft-heap-limit values.
#
# $Id: ioerr3.test,v 1.2 2008/01/19 23:50:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_ioerr_test ioerr3-1 -sqlprep {
  CREATE TABLE t1(id INTEGER, name TEXT);
} -tclbody {
................................................................................
      INSERT INTO t1(id, name) VALUES (1,
'A1234567890B1234567890C1234567890D1234567890E1234567890F1234567890G1234567890H1234567890I1234567890J1234567890K1234567890L1234567890M1234567890N1234567890O1234567890P1234567890Q1234567890R1234567890'
      );
    }
  }
  execsql COMMIT
}

do_ioerr_test ioerr3-2 -sqlbody {
  CREATE TEMP TABLE t1(x,y);
}

sqlite3_soft_heap_limit 0

finish_test

Changes to test/malloc.test.

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
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.54 2008/01/16 17:46:38 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
ifcapable !memdebug {
   puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
   finish_test
   return
}









source $testdir/malloc_common.tcl

ifcapable bloblit&&subquery {
  do_malloc_test 1 -tclprep {
    db close
  } -tclbody {







|











>
>
>
>
>
>
>
>







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
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.55 2008/01/19 23:50:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
ifcapable !memdebug {
   puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
   finish_test
   return
}

# Do a couple of memory dumps just to exercise the memory dump logic
# that that we can say that we have.
#
puts stderr "This is a test.  Ignore the error that follows:"
sqlite3_memdebug_dump $testdir
puts "Memory dump to file memdump.txt..."
sqlite3_memdebug_dump memdump.txt

source $testdir/malloc_common.tcl

ifcapable bloblit&&subquery {
  do_malloc_test 1 -tclprep {
    db close
  } -tclbody {

Changes to test/misc3.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
258
259
260
261
262
263
264


265


266
267
268
269
270
271
272
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc3.test,v 1.17 2008/01/19 20:11:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {integrityck} {
  # Ticket #529.  Make sure an ABORT does not damage the in-memory cache
  # that will be used by subsequent statements in the same transaction.
................................................................................
    execsql {BEGIN; EXPLAIN ROLLBACK}
    catchsql {ROLLBACK}
  } {0 {}}

  # Do some additional EXPLAIN operations to exercise the displayP4 logic.
  do_test misc3-6.10 {
    set x [execsql {


      CREATE TABLE ex1(a INTEGER, b TEXT DEFAULT "hello", c);


      CREATE UNIQUE INDEX ex1i1 ON ex1(a);
      EXPLAIN REINDEX;
    }]
    regexp { IsUnique \d+ \d+ \d+ \d+ } $x
  } {1}
  do_test misc3-6.11 {
    set x [execsql {







|







 







>
>
|
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc3.test,v 1.18 2008/01/19 23:50:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {integrityck} {
  # Ticket #529.  Make sure an ABORT does not damage the in-memory cache
  # that will be used by subsequent statements in the same transaction.
................................................................................
    execsql {BEGIN; EXPLAIN ROLLBACK}
    catchsql {ROLLBACK}
  } {0 {}}

  # Do some additional EXPLAIN operations to exercise the displayP4 logic.
  do_test misc3-6.10 {
    set x [execsql {
      CREATE TABLE ex1(
        a INTEGER DEFAULT 54321,
        b TEXT DEFAULT "hello",
        c REAL DEFAULT 3.1415926
      );
      CREATE UNIQUE INDEX ex1i1 ON ex1(a);
      EXPLAIN REINDEX;
    }]
    regexp { IsUnique \d+ \d+ \d+ \d+ } $x
  } {1}
  do_test misc3-6.11 {
    set x [execsql {