SQLite

Check-in [83705e90a5]
Login

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

Overview
Comment:Merge the latest trunk changes into the sessions branch.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 83705e90a54bad462a5b7fbca70cc129998f871c
User & Date: drh 2011-04-09 18:07:51.034
Context
2011-04-14
11:16
Start adding the sqlite3changeset_concat() function to the session module. (check-in: 8927b2260b user: dan tags: sessions)
2011-04-09
18:07
Merge the latest trunk changes into the sessions branch. (check-in: 83705e90a5 user: drh tags: sessions)
17:53
Remove an always-true conditional. Replace it with an assert(). (check-in: 1c2f0f8477 user: drh tags: trunk)
2011-04-06
23:40
Add a missing "extern C" terminator to the end of sqlite3session.h. (check-in: 29090b695a user: drh tags: sessions)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/analyze.c.
544
545
546
547
548
549
550




551
552
553
554
555
556
557
      v = v*10 + c - '0';
      z++;
    }
    if( i==0 ) pTable->nRowEst = v;
    if( pIndex==0 ) break;
    pIndex->aiRowEst[i] = v;
    if( *z==' ' ) z++;




  }
  return 0;
}

/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.







>
>
>
>







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
      v = v*10 + c - '0';
      z++;
    }
    if( i==0 ) pTable->nRowEst = v;
    if( pIndex==0 ) break;
    pIndex->aiRowEst[i] = v;
    if( *z==' ' ) z++;
    if( memcmp(z, "unordered", 10)==0 ){
      pIndex->bUnordered = 1;
      break;
    }
  }
  return 0;
}

/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.
Changes to src/attach.c.
172
173
174
175
176
177
178

179

180
181
182
183
184
185
186
        zKey = (char *)sqlite3_value_blob(argv[2]);
        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        break;

      case SQLITE_NULL:
        /* No key specified.  Use the key from the main database */
        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);

        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);

        break;
    }
  }
#endif

  /* If the file was opened successfully, read the schema for the new database.
  ** If this fails, or if opening the file failed, then close the file and 







>
|
>







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
        zKey = (char *)sqlite3_value_blob(argv[2]);
        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        break;

      case SQLITE_NULL:
        /* No key specified.  Use the key from the main database */
        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
        if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
          rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        }
        break;
    }
  }
#endif

  /* If the file was opened successfully, read the schema for the new database.
  ** If this fails, or if opening the file failed, then close the file and 
Changes to src/backup.c.
215
216
217
218
219
220
221




222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244











245
246
247
248
249
250
251
*/
static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
  Pager * const pDestPager = sqlite3BtreePager(p->pDest);
  const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
  int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
  const int nCopy = MIN(nSrcPgsz, nDestPgsz);
  const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;





  int rc = SQLITE_OK;
  i64 iOff;

  assert( p->bDestLocked );
  assert( !isFatalError(p->rc) );
  assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
  assert( zSrcData );

  /* Catch the case where the destination is an in-memory database and the
  ** page sizes of the source and destination differ. 
  */
  if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
    rc = SQLITE_READONLY;
  }

#ifdef SQLITE_HAS_CODEC
  /* Backup is not possible if the page size of the destination is changing
  ** a a codec is in use.
  */
  if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
    rc = SQLITE_READONLY;
  }











#endif

  /* This loop runs once for each destination page spanned by the source 
  ** page. For each iteration, variable iOff is set to the byte offset
  ** of the destination page.
  */
  for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){







>
>
>
>


















|




>
>
>
>
>
>
>
>
>
>
>







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
*/
static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
  Pager * const pDestPager = sqlite3BtreePager(p->pDest);
  const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
  int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
  const int nCopy = MIN(nSrcPgsz, nDestPgsz);
  const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
#ifdef SQLITE_HAS_CODEC
  int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
  int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
#endif

  int rc = SQLITE_OK;
  i64 iOff;

  assert( p->bDestLocked );
  assert( !isFatalError(p->rc) );
  assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
  assert( zSrcData );

  /* Catch the case where the destination is an in-memory database and the
  ** page sizes of the source and destination differ. 
  */
  if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
    rc = SQLITE_READONLY;
  }

#ifdef SQLITE_HAS_CODEC
  /* Backup is not possible if the page size of the destination is changing
  ** and a codec is in use.
  */
  if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
    rc = SQLITE_READONLY;
  }

  /* Backup is not possible if the number of bytes of reserve space differ
  ** between source and destination.  If there is a difference, try to
  ** fix the destination to agree with the source.  If that is not possible,
  ** then the backup cannot proceed.
  */
  if( nSrcReserve!=nDestReserve ){
    u32 newPgsz = nSrcPgsz;
    rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
    if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
  }
#endif

  /* This loop runs once for each destination page spanned by the source 
  ** page. For each iteration, variable iOff is set to the byte offset
  ** of the destination page.
  */
  for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
603
604
605
606
607
608
609



610

611
612
613
614
615
616
617
  for(p=pBackup; p; p=p->pNext){
    assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
    if( !isFatalError(p->rc) && iPage<p->iNext ){
      /* The backup process p has already copied page iPage. But now it
      ** has been modified by a transaction on the source pager. Copy
      ** the new data into the backup.
      */



      int rc = backupOnePage(p, iPage, aData);

      assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
      if( rc!=SQLITE_OK ){
        p->rc = rc;
      }
    }
  }
}







>
>
>
|
>







618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
  for(p=pBackup; p; p=p->pNext){
    assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
    if( !isFatalError(p->rc) && iPage<p->iNext ){
      /* The backup process p has already copied page iPage. But now it
      ** has been modified by a transaction on the source pager. Copy
      ** the new data into the backup.
      */
      int rc;
      assert( p->pDestDb );
      sqlite3_mutex_enter(p->pDestDb->mutex);
      rc = backupOnePage(p, iPage, aData);
      sqlite3_mutex_leave(p->pDestDb->mutex);
      assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
      if( rc!=SQLITE_OK ){
        p->rc = rc;
      }
    }
  }
}
Changes to src/btree.c.
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }

      k = get4byte(&pTrunk->aData[4]);
      if( k==0 && !searchList ){
        /* The trunk has no leaves and the list is not being searched. 
        ** So extract the trunk page itself and use it as the newly 
        ** allocated page */
        assert( pPrevTrunk==0 );
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
        if( rc ){







|







4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }

      k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
      if( k==0 && !searchList ){
        /* The trunk has no leaves and the list is not being searched. 
        ** So extract the trunk page itself and use it as the newly 
        ** allocated page */
        assert( pPrevTrunk==0 );
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
        if( rc ){
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
#endif
      }else if( k>0 ){
        /* Extract a leaf from the trunk */
        u32 closest;
        Pgno iPage;
        unsigned char *aData = pTrunk->aData;
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
        if( rc ){
          goto end_allocate_page;
        }
        if( nearby>0 ){
          u32 i;
          int dist;
          closest = 0;
          dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
          for(i=1; i<k; i++){
            int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);







<
<
<
<







4900
4901
4902
4903
4904
4905
4906




4907
4908
4909
4910
4911
4912
4913
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
#endif
      }else if( k>0 ){
        /* Extract a leaf from the trunk */
        u32 closest;
        Pgno iPage;
        unsigned char *aData = pTrunk->aData;




        if( nearby>0 ){
          u32 i;
          int dist;
          closest = 0;
          dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
          for(i=1; i<k; i++){
            int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
4933
4934
4935
4936
4937
4938
4939


4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
        testcase( iPage==mxPage );
        if( !searchList || iPage==nearby ){
          int noContent;
          *pPgno = iPage;
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));


          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
          noContent = !btreeGetHasContent(pBt, *pPgno);
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }







>
>




<







4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941

4942
4943
4944
4945
4946
4947
4948
        testcase( iPage==mxPage );
        if( !searchList || iPage==nearby ){
          int noContent;
          *pPgno = iPage;
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);

          noContent = !btreeGetHasContent(pBt, *pPgno);
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }
5006
5007
5008
5009
5010
5011
5012

5013
5014
5015
5016
5017
5018
5019
      releasePage(*ppPage);
      return SQLITE_CORRUPT_BKPT;
    }
    (*ppPage)->isInit = 0;
  }else{
    *ppPage = 0;
  }

  return rc;
}

/*
** This function is used to add page iPage to the database file free-list. 
** It is assumed that the page is not already a part of the free-list.
**







>







5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
      releasePage(*ppPage);
      return SQLITE_CORRUPT_BKPT;
    }
    (*ppPage)->isInit = 0;
  }else{
    *ppPage = 0;
  }
  assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
  return rc;
}

/*
** This function is used to add page iPage to the database file free-list. 
** It is assumed that the page is not already a part of the free-list.
**
Changes to src/build.c.
809
810
811
812
813
814
815



816
817
818
819
820
821
822
    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
      goto begin_table_error;
    }
    pTable = sqlite3FindTable(db, zName, zDb);
    if( pTable ){
      if( !noErr ){
        sqlite3ErrorMsg(pParse, "table %T already exists", pName);



      }
      goto begin_table_error;
    }
    if( sqlite3FindIndex(db, zName, zDb)!=0 ){
      sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
      goto begin_table_error;
    }







>
>
>







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
      goto begin_table_error;
    }
    pTable = sqlite3FindTable(db, zName, zDb);
    if( pTable ){
      if( !noErr ){
        sqlite3ErrorMsg(pParse, "table %T already exists", pName);
      }else{
        assert( !db->init.busy );
        sqlite3CodeVerifySchema(pParse, iDb);
      }
      goto begin_table_error;
    }
    if( sqlite3FindIndex(db, zName, zDb)!=0 ){
      sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
      goto begin_table_error;
    }
1996
1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
  assert( pName->nSrc==1 );
  if( noErr ) db->suppressErr++;
  pTab = sqlite3LocateTable(pParse, isView, 
                            pName->a[0].zName, pName->a[0].zDatabase);
  if( noErr ) db->suppressErr--;

  if( pTab==0 ){

    goto exit_drop_table;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb>=0 && iDb<db->nDb );

  /* If pTab is a virtual table, call ViewGetColumnNames() to ensure
  ** it is initialized.







>







1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
  assert( pName->nSrc==1 );
  if( noErr ) db->suppressErr++;
  pTab = sqlite3LocateTable(pParse, isView, 
                            pName->a[0].zName, pName->a[0].zDatabase);
  if( noErr ) db->suppressErr--;

  if( pTab==0 ){
    if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
    goto exit_drop_table;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb>=0 && iDb<db->nDb );

  /* If pTab is a virtual table, call ViewGetColumnNames() to ensure
  ** it is initialized.
2514
2515
2516
2517
2518
2519
2520



2521
2522
2523
2524
2525
2526
2527
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
      }
    }
    if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
      if( !ifNotExist ){
        sqlite3ErrorMsg(pParse, "index %s already exists", zName);



      }
      goto exit_create_index;
    }
  }else{
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}







>
>
>







2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
      }
    }
    if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
      if( !ifNotExist ){
        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
      }else{
        assert( !db->init.busy );
        sqlite3CodeVerifySchema(pParse, iDb);
      }
      goto exit_create_index;
    }
  }else{
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
2907
2908
2909
2910
2911
2912
2913


2914
2915
2916
2917
2918
2919
2920
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_drop_index;
  }
  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    if( !ifExists ){
      sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);


    }
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);







>
>







2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_drop_index;
  }
  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    if( !ifExists ){
      sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
    }else{
      sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
    }
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);
3495
3496
3497
3498
3499
3500
3501















3502
3503
3504
3505
3506
3507
3508
      pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
      if( !OMIT_TEMPDB && iDb==1 ){
        sqlite3OpenTempDatabase(pToplevel);
      }
    }
  }
}
















/*
** Generate VDBE code that prepares for doing an operation that
** might change the database.
**
** This routine starts a new transaction if we are not already within
** a transaction.  If we are already within a transaction, then a checkpoint







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
      pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
      if( !OMIT_TEMPDB && iDb==1 ){
        sqlite3OpenTempDatabase(pToplevel);
      }
    }
  }
}

/*
** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each 
** attached database. Otherwise, invoke it for the database named zDb only.
*/
void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
  sqlite3 *db = pParse->db;
  int i;
  for(i=0; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
      sqlite3CodeVerifySchema(pParse, i);
    }
  }
}

/*
** Generate VDBE code that prepares for doing an operation that
** might change the database.
**
** This routine starts a new transaction if we are not already within
** a transaction.  If we are already within a transaction, then a checkpoint
Changes to src/ctime.c.
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#endif
#ifdef SQLITE_OMIT_TRIGGER
  "OMIT_TRIGGER",
#endif
#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  "OMIT_TRUNCATE_OPTIMIZATION",
#endif
#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
  "OMIT_UNIQUE_ENFORCEMENT",
#endif
#ifdef SQLITE_OMIT_UTF16
  "OMIT_UTF16",
#endif
#ifdef SQLITE_OMIT_VACUUM
  "OMIT_VACUUM",
#endif
#ifdef SQLITE_OMIT_VIEW







<
<
<







298
299
300
301
302
303
304



305
306
307
308
309
310
311
#endif
#ifdef SQLITE_OMIT_TRIGGER
  "OMIT_TRIGGER",
#endif
#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  "OMIT_TRUNCATE_OPTIMIZATION",
#endif



#ifdef SQLITE_OMIT_UTF16
  "OMIT_UTF16",
#endif
#ifdef SQLITE_OMIT_VACUUM
  "OMIT_VACUUM",
#endif
#ifdef SQLITE_OMIT_VIEW
Changes to src/insert.c.
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
    int regIdx;
#ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT
    int regR;
#endif
    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */

    /* Create a key for accessing the index entry */
    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
    for(i=0; i<pIdx->nColumn; i++){
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
      }else{
        sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
      }
    }
    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);

#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
    continue;  /* Treat pIdx as if it is not a UNIQUE index */
#else

    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ){ 
      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
      continue;  /* pIdx is not a UNIQUE index */
    }
    if( overrideError!=OE_Default ){







<

|

















<
<
<
<
<







1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343





1344
1345
1346
1347
1348
1349
1350

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
    int regIdx;

    int regR;

    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */

    /* Create a key for accessing the index entry */
    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
    for(i=0; i<pIdx->nColumn; i++){
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
      }else{
        sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
      }
    }
    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);






    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ){ 
      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
      continue;  /* pIdx is not a UNIQUE index */
    }
    if( overrideError!=OE_Default ){
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
        );
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    sqlite3ReleaseTempReg(pParse, regR);
#endif
  }
  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
}








<







1410
1411
1412
1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
        );
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    sqlite3ReleaseTempReg(pParse, regR);

  }
  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
}

Changes to src/main.c.
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
*/
int sqlite3_db_config(sqlite3 *db, int op, ...){
  va_list ap;
  int rc;
  va_start(ap, op);
  switch( op ){
    case SQLITE_DBCONFIG_LOOKASIDE: {
      void *pBuf = va_arg(ap, void*); /* IMP: R-21112-12275 */
      int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
      int cnt = va_arg(ap, int);      /* IMP: R-04460-53386 */
      rc = setupLookaside(db, pBuf, sz, cnt);
      break;
    }
    default: {
      static const struct {







|







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
*/
int sqlite3_db_config(sqlite3 *db, int op, ...){
  va_list ap;
  int rc;
  va_start(ap, op);
  switch( op ){
    case SQLITE_DBCONFIG_LOOKASIDE: {
      void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
      int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
      int cnt = va_arg(ap, int);      /* IMP: R-04460-53386 */
      rc = setupLookaside(db, pBuf, sz, cnt);
      break;
    }
    default: {
      static const struct {
Changes to src/prepare.c.
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    sqlite3SetString(pData->pzErrMsg, db,
      "malformed database schema (%s)", zObj);
    if( zExtra ){
      *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, 
                                 "%s - %s", *pData->pzErrMsg, zExtra);
    }
  }
  pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT;
}

/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    sqlite3SetString(pData->pzErrMsg, db,
      "malformed database schema (%s)", zObj);
    if( zExtra ){
      *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, 
                                 "%s - %s", *pData->pzErrMsg, zExtra);
    }
  }
  pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
}

/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
Changes to src/shell.c.
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
    int testctrl = -1;
    int rc = 0;
    int i, n;
    open_db(p);

    /* convert testctrl text option to value. allow any unique prefix
    ** of the option name, or a numerical value. */
    n = strlen(azArg[1]);
    for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
        if( testctrl<0 ){
          testctrl = aCtrl[i].ctrlCode;
        }else{
          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
          testctrl = -1;







|







2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
    int testctrl = -1;
    int rc = 0;
    int i, n;
    open_db(p);

    /* convert testctrl text option to value. allow any unique prefix
    ** of the option name, or a numerical value. */
    n = strlen30(azArg[1]);
    for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
        if( testctrl<0 ){
          testctrl = aCtrl[i].ctrlCode;
        }else{
          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
          testctrl = -1;
Changes to src/sqlite.h.in.
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
** SQLite and sent to all VFSes in place of a call to the xSync method
** when the database connection has [PRAGMA synchronous] set to OFF.)^
** Some specialized VFSes need this signal in order to operate correctly
** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most 
** VFSes do not need this signal and should silently ignore this opcode.
** Applications should not call [sqlite3_file_control()] with this
** opcode as doing so may disrupt the operation of the specilized VFSes
** that do require it.  
*/
#define SQLITE_FCNTL_LOCKSTATE        1
#define SQLITE_GET_LOCKPROXYFILE      2
#define SQLITE_SET_LOCKPROXYFILE      3
#define SQLITE_LAST_ERRNO             4
#define SQLITE_FCNTL_SIZE_HINT        5







|







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
** SQLite and sent to all VFSes in place of a call to the xSync method
** when the database connection has [PRAGMA synchronous] set to OFF.)^
** Some specialized VFSes need this signal in order to operate correctly
** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most 
** VFSes do not need this signal and should silently ignore this opcode.
** Applications should not call [sqlite3_file_control()] with this
** opcode as doing so may disrupt the operation of the specialized VFSes
** that do require it.  
*/
#define SQLITE_FCNTL_LOCKSTATE        1
#define SQLITE_GET_LOCKPROXYFILE      2
#define SQLITE_SET_LOCKPROXYFILE      3
#define SQLITE_LAST_ERRNO             4
#define SQLITE_FCNTL_SIZE_HINT        5
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** scratch memory.  There are three arguments:  A pointer an 8-byte
** aligned memory buffer from which the scrach allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).  The sz
** argument must be a multiple of 16.
** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will use no more than two scratch buffers per thread.  So
** N should be set to twice the expected maximum number of threads.







|







1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
** allocation statistics are disabled by default.
** </dd>
**
** <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** scratch memory.  There are three arguments:  A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).  The sz
** argument must be a multiple of 16.
** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will use no more than two scratch buffers per thread.  So
** N should be set to twice the expected maximum number of threads.
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
** is invoked.
**
** <dl>
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd> ^This option takes three additional arguments that determine the 
** [lookaside memory allocator] configuration for the [database connection].
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to an memory buffer to use for lookaside memory.
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
** may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
** size of each lookaside buffer slot.  ^The third argument is the number of
** slots.  The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.  The buffer
** must be aligned to an 8-byte boundary.  ^If the second argument to







|







1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
** is invoked.
**
** <dl>
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd> ^This option takes three additional arguments that determine the 
** [lookaside memory allocator] configuration for the [database connection].
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
** may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
** size of each lookaside buffer slot.  ^The third argument is the number of
** slots.  The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.  The buffer
** must be aligned to an 8-byte boundary.  ^If the second argument to
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
** following this call.  The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back. </dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable trigers or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether triggers are disabled or enabled
** following this call.  The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back. </dd>
**
** </dl>
*/







|







1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
** following this call.  The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back. </dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable triggers or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether triggers are disabled or enabled
** following this call.  The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back. </dd>
**
** </dl>
*/
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
** method.
*/
void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks
**
** ^This routine registers a authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
** points during the compilation process, as logic is being created
** to perform various actions, the authorizer callback is invoked to
** see if those actions are allowed.  ^The authorizer callback should







|







2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
** method.
*/
void sqlite3_randomness(int N, void *P);

/*
** CAPI3REF: Compile-Time Authorization Callbacks
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
** points during the compilation process, as logic is being created
** to perform various actions, the authorizer callback is invoked to
** see if those actions are allowed.  ^The authorizer callback should
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
** An sqlite3_value object may be either "protected" or "unprotected".
** Some interfaces require a protected sqlite3_value.  Other interfaces
** will accept either a protected or an unprotected sqlite3_value.
** Every interface that accepts sqlite3_value arguments specifies
** whether or not it requires a protected sqlite3_value.
**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held.  A internal mutex is held for a protected
** sqlite3_value object but no mutex is held for an unprotected
** sqlite3_value object.  If SQLite is compiled to be single-threaded
** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
** or if SQLite is run in one of reduced mutex modes 
** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
** then there is no distinction between protected and unprotected
** sqlite3_value objects and they can be used interchangeably.  However,







|







2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
** An sqlite3_value object may be either "protected" or "unprotected".
** Some interfaces require a protected sqlite3_value.  Other interfaces
** will accept either a protected or an unprotected sqlite3_value.
** Every interface that accepts sqlite3_value arguments specifies
** whether or not it requires a protected sqlite3_value.
**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held.  An internal mutex is held for a protected
** sqlite3_value object but no mutex is held for an unprotected
** sqlite3_value object.  If SQLite is compiled to be single-threaded
** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
** or if SQLite is run in one of reduced mutex modes 
** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
** then there is no distinction between protected and unprotected
** sqlite3_value objects and they can be used interchangeably.  However,
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
** of existing SQL functions or aggregates.  The only differences between
** these routines are the text encoding expected for
** the the second parameter (the name of the function being created)
** and the presence or absence of a destructor callback for
** the application data pointer.
**
** ^The first parameter is the [database connection] to which the SQL
** function is to be added.  ^If an application uses more than one database
** connection then application-defined SQL functions must be added
** to each database connection separately.







|







3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
** of existing SQL functions or aggregates.  The only differences between
** these routines are the text encoding expected for
** the second parameter (the name of the function being created)
** and the presence or absence of a destructor callback for
** the application data pointer.
**
** ^The first parameter is the [database connection] to which the SQL
** function is to be added.  ^If an application uses more than one database
** connection then application-defined SQL functions must be added
** to each database connection separately.
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
**
** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
** pointers to C-language functions that implement the SQL function or
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
** callback only; NULL pointers must be passed as the xStep and xFinal
** parameters. ^An aggregate SQL function requires an implementation of xStep
** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
** SQL function or aggregate, pass NULL poiners for all three function
** callbacks.
**
** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
** then it is destructor for the application data pointer. 
** The destructor is invoked when the function is deleted, either by being
** overloaded or when the database connection closes.)^
** ^The destructor is also invoked if the call to







|







3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
**
** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
** pointers to C-language functions that implement the SQL function or
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
** callback only; NULL pointers must be passed as the xStep and xFinal
** parameters. ^An aggregate SQL function requires an implementation of xStep
** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
** SQL function or aggregate, pass NULL pointers for all three function
** callbacks.
**
** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
** then it is destructor for the application data pointer. 
** The destructor is invoked when the function is deleted, either by being
** overloaded or when the database connection closes.)^
** ^The destructor is also invoked if the call to
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
** ^The eTextRep argument determines the encoding of strings passed
** to the collating function callback, xCallback.
** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
** force strings to be UTF16 with native byte order.
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
** on an even byte address.
**
** ^The fourth argument, pArg, is a application data pointer that is passed
** through as the first argument to the collating function callback.
**
** ^The fifth argument, xCallback, is a pointer to the collating function.
** ^Multiple collating functions can be registered using the same name but
** with different eTextRep parameters and SQLite will use whichever
** function requires the least amount of data transformation.
** ^If the xCallback argument is NULL then the collating function is
** deleted.  ^When all collating functions having the same name are deleted,
** that collation is no longer usable.
**
** ^The collating function callback is invoked with a copy of the pArg 
** application data pointer and with two strings in the encoding specified
** by the eTextRep argument.  The collating function must return an
** integer that is negative, zero, or positive
** if the first string is less than, equal to, or greater than the second,
** respectively.  A collating function must alway return the same answer
** given the same inputs.  If two or more collating functions are registered
** to the same collation name (using different eTextRep values) then all
** must give an equivalent answer when invoked with equivalent strings.
** The collating function must obey the following properties for all
** strings A, B, and C:
**
** <ol>







|















|







3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
** ^The eTextRep argument determines the encoding of strings passed
** to the collating function callback, xCallback.
** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
** force strings to be UTF16 with native byte order.
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
** on an even byte address.
**
** ^The fourth argument, pArg, is an application data pointer that is passed
** through as the first argument to the collating function callback.
**
** ^The fifth argument, xCallback, is a pointer to the collating function.
** ^Multiple collating functions can be registered using the same name but
** with different eTextRep parameters and SQLite will use whichever
** function requires the least amount of data transformation.
** ^If the xCallback argument is NULL then the collating function is
** deleted.  ^When all collating functions having the same name are deleted,
** that collation is no longer usable.
**
** ^The collating function callback is invoked with a copy of the pArg 
** application data pointer and with two strings in the encoding specified
** by the eTextRep argument.  The collating function must return an
** integer that is negative, zero, or positive
** if the first string is less than, equal to, or greater than the second,
** respectively.  A collating function must always return the same answer
** given the same inputs.  If two or more collating functions are registered
** to the same collation name (using different eTextRep values) then all
** must give an equivalent answer when invoked with equivalent strings.
** The collating function must obey the following properties for all
** strings A, B, and C:
**
** <ol>
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
** if one or more of following conditions are true:
**
** <ul>
** <li> The soft heap limit is set to zero.
** <li> Memory accounting is disabled using a combination of the
**      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
**      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
** <li> An alternative page cache implementation is specifed using
**      [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
** <li> The page cache allocates from its own memory pool supplied
**      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
**      from the heap.
** </ul>)^
**
** Beginning with SQLite version 3.7.3, the soft heap limit is enforced







|







4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
** if one or more of following conditions are true:
**
** <ul>
** <li> The soft heap limit is set to zero.
** <li> Memory accounting is disabled using a combination of the
**      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
**      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
** <li> An alternative page cache implementation is specified using
**      [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
** <li> The page cache allocates from its own memory pool supplied
**      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
**      from the heap.
** </ul>)^
**
** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
typedef struct sqlite3_module sqlite3_module;

/*
** CAPI3REF: Virtual Table Object
** KEYWORDS: sqlite3_module {virtual table module}
**
** This structure, sometimes called a a "virtual table module", 
** defines the implementation of a [virtual tables].  
** This structure consists mostly of methods for the module.
**
** ^A virtual table module is created by filling in a persistent
** instance of this structure and passing a pointer to that instance
** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
** ^The registration remains valid until it is replaced by a different







|







4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
typedef struct sqlite3_module sqlite3_module;

/*
** CAPI3REF: Virtual Table Object
** KEYWORDS: sqlite3_module {virtual table module}
**
** This structure, sometimes called a "virtual table module", 
** defines the implementation of a [virtual tables].  
** This structure consists mostly of methods for the module.
**
** ^A virtual table module is created by filling in a persistent
** instance of this structure and passing a pointer to that instance
** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
** ^The registration remains valid until it is replaced by a different
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
** ^(Changes written into a BLOB prior to the BLOB expiring are not
** rolled back by the expiration of the BLOB.  Such changes will eventually
** commit if the transaction continues to completion.)^
**
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  ^The size of a blob may not be changed by this
** interface.  Use the [UPDATE] SQL command to change the size of a







|







4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
** then the BLOB handle is marked as "expired".
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
** ^(Changes written into a BLOB prior to the BLOB expiring are not
** rolled back by the expiration of the BLOB.  Such changes will eventually
** commit if the transaction continues to completion.)^
**
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  ^The size of a blob may not be changed by this
** interface.  Use the [UPDATE] SQL command to change the size of a
Changes to src/sqliteInt.h.
1480
1481
1482
1483
1484
1485
1486

1487
1488
1489
1490
1491
1492
1493
  int nColumn;     /* Number of columns in the table used by this index */
  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
  unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */

  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  Schema *pSchema; /* Schema containing this index */
  u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
  char **azColl;   /* Array of collation sequence names for index */
  IndexSample *aSample;    /* Array of SQLITE_INDEX_SAMPLES samples */
};







>







1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
  int nColumn;     /* Number of columns in the table used by this index */
  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
  unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
  u8 bUnordered;   /* Use this index for == or IN queries only */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  Schema *pSchema; /* Schema containing this index */
  u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
  char **azColl;   /* Array of collation sequence names for index */
  IndexSample *aSample;    /* Array of SQLITE_INDEX_SAMPLES samples */
};
2772
2773
2774
2775
2776
2777
2778

2779
2780
2781
2782
2783
2784
2785
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
Vdbe *sqlite3GetVdbe(Parse*);
void sqlite3PrngSaveState(void);
void sqlite3PrngRestoreState(void);
void sqlite3PrngResetState(void);
void sqlite3RollbackAll(sqlite3*);
void sqlite3CodeVerifySchema(Parse*, int);

void sqlite3BeginTransaction(Parse*, int);
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);







>







2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
Vdbe *sqlite3GetVdbe(Parse*);
void sqlite3PrngSaveState(void);
void sqlite3PrngRestoreState(void);
void sqlite3PrngResetState(void);
void sqlite3RollbackAll(sqlite3*);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
Changes to src/test_config.c.
92
93
94
95
96
97
98






99
100
101
102
103
104
105
#endif

#ifdef SQLITE_MUTEX_OMIT
  Tcl_SetVar2(interp, "sqlite_options", "mutex", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "mutex", "1", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_OMIT_ALTERTABLE
  Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY);
#endif








>
>
>
>
>
>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#endif

#ifdef SQLITE_MUTEX_OMIT
  Tcl_SetVar2(interp, "sqlite_options", "mutex", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "mutex", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_MUTEX_NOOP
  Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_ALTERTABLE
  Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY);
#endif

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
  Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_UTF16
  Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY);
#endif

#if defined(SQLITE_OMIT_VACUUM) || defined(SQLITE_OMIT_ATTACH)







<
<
<
<
<
<







489
490
491
492
493
494
495






496
497
498
499
500
501
502

#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_OMIT_UTF16
  Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY);
#endif

#if defined(SQLITE_OMIT_VACUUM) || defined(SQLITE_OMIT_ATTACH)
Changes to src/trigger.c.
167
168
169
170
171
172
173



174
175
176
177
178
179
180
    goto trigger_cleanup;
  }
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
                      zName, sqlite3Strlen30(zName)) ){
    if( !noErr ){
      sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);



    }
    goto trigger_cleanup;
  }

  /* Do not create a trigger on a system table */
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    sqlite3ErrorMsg(pParse, "cannot create trigger on system table");







>
>
>







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
    goto trigger_cleanup;
  }
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
                      zName, sqlite3Strlen30(zName)) ){
    if( !noErr ){
      sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
    }else{
      assert( !db->init.busy );
      sqlite3CodeVerifySchema(pParse, iDb);
    }
    goto trigger_cleanup;
  }

  /* Do not create a trigger on a system table */
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
495
496
497
498
499
500
501


502
503
504
505
506
507
508
    assert( sqlite3SchemaMutexHeld(db, j, 0) );
    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    if( !noErr ){
      sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);


    }
    pParse->checkSchema = 1;
    goto drop_trigger_cleanup;
  }
  sqlite3DropTriggerPtr(pParse, pTrigger);

drop_trigger_cleanup:







>
>







498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    assert( sqlite3SchemaMutexHeld(db, j, 0) );
    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    if( !noErr ){
      sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
    }else{
      sqlite3CodeVerifyNamedSchema(pParse, zDb);
    }
    pParse->checkSchema = 1;
    goto drop_trigger_cleanup;
  }
  sqlite3DropTriggerPtr(pParse, pTrigger);

drop_trigger_cleanup:
Changes to src/where.c.
1338
1339
1340
1341
1342
1343
1344
1345



1346
1347
1348
1349
1350
1351
1352
  ** virtual term of that form.
  **
  ** Note that the virtual term must be tagged with TERM_VNULL.  This
  ** TERM_VNULL tag will suppress the not-null check at the beginning
  ** of the loop.  Without the TERM_VNULL flag, the not-null check at
  ** the start of the loop will prevent any results from being returned.
  */
  if( pExpr->op==TK_NOTNULL && pExpr->pLeft->iColumn>=0 ){



    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;

    pNewExpr = sqlite3PExpr(pParse, TK_GT,
                            sqlite3ExprDup(db, pLeft, 0),







|
>
>
>







1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
  ** virtual term of that form.
  **
  ** Note that the virtual term must be tagged with TERM_VNULL.  This
  ** TERM_VNULL tag will suppress the not-null check at the beginning
  ** of the loop.  Without the TERM_VNULL flag, the not-null check at
  ** the start of the loop will prevent any results from being returned.
  */
  if( pExpr->op==TK_NOTNULL
   && pExpr->pLeft->op==TK_COLUMN
   && pExpr->pLeft->iColumn>=0
  ){
    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;

    pNewExpr = sqlite3PExpr(pParse, TK_GT,
                            sqlite3ExprDup(db, pLeft, 0),
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
int whereEqualScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
  double *pnRow        /* Write the revised row estimate here */
){
  sqlite3_value *pRhs = 0;  /* VALUE on right-hand side of pTerm */
  int iLower, iUpper;       /* Range of histogram regions containing pRhs */







|







2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereEqualScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
  double *pnRow        /* Write the revised row estimate here */
){
  sqlite3_value *pRhs = 0;  /* VALUE on right-hand side of pTerm */
  int iLower, iUpper;       /* Range of histogram regions containing pRhs */
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
int whereInScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
  double *pnRow        /* Write the revised row estimate here */
){
  sqlite3_value *pVal = 0;  /* One value from list */
  int iLower, iUpper;       /* Range of histogram regions containing pRhs */







|







2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereInScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
  double *pnRow        /* Write the revised row estimate here */
){
  sqlite3_value *pVal = 0;  /* One value from list */
  int iLower, iUpper;       /* Range of histogram regions containing pRhs */
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
#ifdef SQLITE_ENABLE_STAT2
      if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
#endif
      used |= pTerm->prereqRight;
    }

    /* Determine the value of estBound. */
    if( nEq<pProbe->nColumn ){
      int j = pProbe->aiColumn[nEq];
      if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
        WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
        WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
        whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
        if( pTop ){
          nBound = 1;







|







2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
#ifdef SQLITE_ENABLE_STAT2
      if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
#endif
      used |= pTerm->prereqRight;
    }

    /* Determine the value of estBound. */
    if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
      int j = pProbe->aiColumn[nEq];
      if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
        WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
        WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
        whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
        if( pTop ){
          nBound = 1;
2888
2889
2890
2891
2892
2893
2894

2895
2896
2897
2898
2899
2900
2901

    /* If there is an ORDER BY clause and the index being considered will
    ** naturally scan rows in the required order, set the appropriate flags
    ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
    ** will scan rows in a different order, set the bSort variable.  */
    if( pOrderBy ){
      if( (wsFlags & WHERE_COLUMN_IN)==0

        && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
                          nEq, wsFlags, &rev)
      ){
        wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
        wsFlags |= (rev ? WHERE_REVERSE : 0);
      }else{
        bSort = 1;







>







2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905

    /* If there is an ORDER BY clause and the index being considered will
    ** naturally scan rows in the required order, set the appropriate flags
    ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
    ** will scan rows in a different order, set the bSort variable.  */
    if( pOrderBy ){
      if( (wsFlags & WHERE_COLUMN_IN)==0
        && pProbe->bUnordered==0
        && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
                          nEq, wsFlags, &rev)
      ){
        wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
        wsFlags |= (rev ? WHERE_REVERSE : 0);
      }else{
        bSort = 1;
Changes to test/analyze5.test.
205
206
207
208
209
210
211


212
213
214
215
216
217
218
#
foreach {testid where index rows} {
  500  {x IS NULL AND u='charlie'}         t1u  20
  501  {x=1 AND u='charlie'}               t1x   5
  502  {x IS NULL}                          {} 100
  503  {x=1}                               t1x  50
  504  {x IS NOT NULL}                     t1x  25



} {
  # Verify that the expected index is used with the expected row count
  do_test analyze5-1.${testid}a {
    set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
    set idx {}
    regexp {INDEX (t1.) } $x all idx







>
>







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#
foreach {testid where index rows} {
  500  {x IS NULL AND u='charlie'}         t1u  20
  501  {x=1 AND u='charlie'}               t1x   5
  502  {x IS NULL}                          {} 100
  503  {x=1}                               t1x  50
  504  {x IS NOT NULL}                     t1x  25
  505  {+x IS NOT NULL}                     {} 500
  506  {upper(x) IS NOT NULL}               {} 500

} {
  # Verify that the expected index is used with the expected row count
  do_test analyze5-1.${testid}a {
    set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
    set idx {}
    regexp {INDEX (t1.) } $x all idx
Changes to test/analyze7.test.
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}}
ifcapable stat2 {
  # If ENABLE_STAT2 is defined, SQLite comes up with a different estimated
  # row count for (c=2) than it does for (c=?).
  do_test analyze7-3.2.2 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~102 rows)}}
} else {
  # If ENABLE_STAT2 is not defined, the expected row count for (c=2) is the
  # same as that for (c=?).
  do_test analyze7-3.2.3 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}}
}







|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}}
ifcapable stat2 {
  # If ENABLE_STAT2 is defined, SQLite comes up with a different estimated
  # row count for (c=2) than it does for (c=?).
  do_test analyze7-3.2.2 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~51 rows)}}
} else {
  # If ENABLE_STAT2 is not defined, the expected row count for (c=2) is the
  # same as that for (c=?).
  do_test analyze7-3.2.3 {
    execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}}
}
Changes to test/attach4.test.
70
71
72
73
74
75
76



77

78
79
80
81
82
83
84
  }
  set L
} $files

set L [list]
set S ""
foreach {name f} $files {



  lappend L wal

  append S "
    PRAGMA $name.journal_mode = WAL;
    UPDATE $name.tbl SET x = '$name';
  "
}
do_execsql_test 1.5 $S $L








>
>
>
|
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  }
  set L
} $files

set L [list]
set S ""
foreach {name f} $files {
  if {[permutation] == "journaltest"} {
    lappend L delete
  } else {
    lappend L wal
  }
  append S "
    PRAGMA $name.journal_mode = WAL;
    UPDATE $name.tbl SET x = '$name';
  "
}
do_execsql_test 1.5 $S $L

Changes to test/backcompat.test.
362
363
364
365
366
367
368









































































369
370
371
372

      6    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'aa'"
      7    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH '44'"
      8    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'a*'"
    } {
      do_test backcompat-3.7 [list sql1 $q] [sql2 $q]
    }









































































  }
}

finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

      6    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'aa'"
      7    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH '44'"
      8    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'a*'"
    } {
      do_test backcompat-3.7 [list sql1 $q] [sql2 $q]
    }
  }
}

#-------------------------------------------------------------------------
# Test that Rtree tables may be read/written by different versions of 
# SQLite. 
#
set contents {
  CREATE VIRTUAL TABLE t1 USING rtree(id, x1, x2, y1, y2);
}
foreach {id x1 x2 y1 y2} {
  1    -47.64 43.87    33.86 34.42        2    -21.51 17.32    2.05 31.04
  3    -43.67 -38.33    -19.79 3.43       4    32.41 35.16    9.12 19.82
  5    33.28 34.87    14.78 28.26         6    49.31 116.59    -9.87 75.09
  7    -14.93 34.51    -17.64 64.09       8    -43.05 23.43    -1.19 69.44
  9    44.79 133.56    28.09 80.30        10    -2.66 81.47    -41.38 -10.46
  11    -42.89 -3.54    15.76 71.63       12    -3.50 84.96    -11.64 64.95
  13    -45.69 26.25    11.14 55.06       14    -44.09 11.23    17.52 44.45
  15    36.23 133.49    -19.38 53.67      16    -17.89 81.54    14.64 50.61
  17    -41.97 -24.04    -39.43 28.95     18    -5.85 7.76    -6.38 47.02
  19    18.82 27.10    42.82 100.09       20    39.17 113.45    26.14 73.47
  21    22.31 103.17    49.92 106.05      22    -43.06 40.38    -1.75 76.08
  23    2.43 57.27    -14.19 -3.83        24    -47.57 -4.35    8.93 100.06
  25    -37.47 49.14    -29.11 8.81       26    -7.86 75.72    49.34 107.42
  27    1.53 45.49    20.36 49.74         28    -48.48 32.54    28.81 54.45
  29    2.67 39.77    -4.05 13.67         30    4.11 62.88    -47.44 -5.72
  31    -21.47 51.75    37.25 116.09      32    45.59 111.37    -6.43 43.64
  33    35.23 48.29    23.54 113.33       34    16.61 68.35    -14.69 65.97
  35    13.98 16.60    48.66 102.87       36    19.74 23.84    31.15 77.27
  37    -27.61 24.43    7.96 94.91        38    -34.77 12.05    -22.60 -6.29
  39    -25.83 8.71    -13.48 -12.53      40    -17.11 -1.01    18.06 67.89
  41    14.13 71.72    -3.78 39.25        42    23.75 76.00    -16.30 8.23
  43    -39.15 28.63    38.12 125.88      44    48.62 86.09    36.49 102.95
  45    -31.39 -21.98    2.52 89.78       46    5.65 56.04    15.94 89.10
  47    18.28 95.81    46.46 143.08       48    30.93 102.82    -20.08 37.36
  49    -20.78 -3.48    -5.58 35.46       50    49.85 90.58    -24.48 46.29
} {
if {$x1 >= $x2 || $y1 >= $y2} { error "$x1 $x2 $y1 $y2" }
  append contents "INSERT INTO t1 VALUES($id, $x1, $x2, $y1, $y2);"
}
set queries {
  1    "SELECT id FROM t1 WHERE x1>10 AND x2<44"
  2    "SELECT id FROM t1 WHERE y1<100"
  3    "SELECT id FROM t1 WHERE y1<100 AND x1>0"
  4    "SELECT id FROM t1 WHERE y1>10 AND x1>0 AND x2<50 AND y2<550"
}
do_allbackcompat_test {
  if {[code1 {set ::sqlite_options(fts3)}]
   && [code2 {set ::sqlite_options(fts3)}]
  } {

    do_test backcompat-4.1 { sql1 $contents } {}

    foreach {n q} $::queries {
      do_test backcompat-4.2.$n [list sql1 $q] [sql2 $q]
    }

    do_test backcompat-4.3 { sql1 {
      INSERT INTO t1 SELECT id+100, x1+10.0, x2+10.0, y1-10.0, y2-10.0 FROM t1;
    } } {}

    foreach {n q} $::queries {
      do_test backcompat-4.4.$n [list sql1 $q] [sql2 $q]
    }

    do_test backcompat-4.5 { sql2 {
      INSERT INTO t1 SELECT id+200, x1+20.0, x2+20.0, y1-20.0, y2-20.0 FROM t1;
    } } {}

    foreach {n q} $::queries {
      do_test backcompat-4.6.$n [list sql1 $q] [sql2 $q]
    }

  }
}

finish_test
Added test/exists.test.
































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# 2011 April 9
#
# The author disclaims copyright to this source code.  In place of
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the various schema modification statements
# that feature "IF EXISTS" or "IF NOT EXISTS" clauses.
#

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

set testprefix exists

# This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
#
do_multiclient_test tn {

  # TABLE objects.
  #
  do_test 1.$tn.1.1 {
    sql2 { CREATE TABLE t1(x) }
    sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
    sql2 { DROP TABLE t1 }
    sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
  } {t1}

  do_test 1.$tn.1.2 {
    sql2 { CREATE TABLE t2(x) }
    sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
    sql2 { DROP TABLE t2 }
    sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
  } {t1 t2}


  # INDEX objects.
  #
  do_test 1.$tn.2 {
    sql2 { CREATE INDEX i1 ON t1(a) }
    sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
    sql2 { DROP INDEX i1 }
    sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
  } {i1}

  # VIEW objects.
  #
  do_test 1.$tn.3 {
    sql2 { CREATE VIEW v1 AS SELECT * FROM t1 }
    sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
    sql2 { DROP VIEW v1 }
    sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
  } {v1}

  # TRIGGER objects.
  #
  do_test $tn.4 {
    sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
    sql2 { DROP TRIGGER tr1 }
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
  } {tr1}
}

# This block of tests is targeted at DROP XXX IF EXISTS statements.
#
do_multiclient_test tn {

  # TABLE objects.
  #
  do_test 2.$tn.1 {
    sql1 { DROP TABLE IF EXISTS t1 }
    sql2 { CREATE TABLE t1(x) }
    sql1 { DROP TABLE IF EXISTS t1 }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
  } {}

  # INDEX objects.
  #
  do_test 2.$tn.2 {
    sql1 { CREATE TABLE t2(x) }
    sql1 { DROP INDEX IF EXISTS i2 }
    sql2 { CREATE INDEX i2 ON t2(x) }
    sql1 { DROP INDEX IF EXISTS i2 }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
  } {}

  # VIEW objects.
  #
  do_test 2.$tn.3 {
    sql1 { DROP VIEW IF EXISTS v1 }
    sql2 { CREATE VIEW v1 AS SELECT * FROM t2 }
    sql1 { DROP VIEW IF EXISTS v1 }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
  } {}
  
  # TRIGGER objects.
  #
  do_test 2.$tn.4 {
    sql1 { DROP TRIGGER IF EXISTS tr1 }
    sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
    sql1 { DROP TRIGGER IF EXISTS tr1 }
    sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
  } {}
}

# This block of tests is targeted at DROP XXX IF EXISTS statements with
# attached databases.
#
do_multiclient_test tn {

  forcedelete test.db2
  do_test 3.$tn.0 {
    sql1 { ATTACH 'test.db2' AS aux }
    sql2 { ATTACH 'test.db2' AS aux }
  } {}

  # TABLE objects.
  #
  do_test 3.$tn.1.1 {
    sql1 { DROP TABLE IF EXISTS aux.t1 }
    sql2 { CREATE TABLE aux.t1(x) }
    sql1 { DROP TABLE IF EXISTS aux.t1 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
  } {}
  do_test 3.$tn.1.2 {
    sql1 { DROP TABLE IF EXISTS t1 }
    sql2 { CREATE TABLE aux.t1(x) }
    sql1 { DROP TABLE IF EXISTS t1 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
  } {}

  # INDEX objects.
  #
  do_test 3.$tn.2.1 {
    sql1 { CREATE TABLE aux.t2(x) }
    sql1 { DROP INDEX IF EXISTS aux.i2 }
    sql2 { CREATE INDEX aux.i2 ON t2(x) }
    sql1 { DROP INDEX IF EXISTS aux.i2 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
  } {}
  do_test 3.$tn.2.2 {
    sql1 { DROP INDEX IF EXISTS i2 }
    sql2 { CREATE INDEX aux.i2 ON t2(x) }
    sql1 { DROP INDEX IF EXISTS i2 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
  } {}

  # VIEW objects.
  #
  do_test 3.$tn.3.1 {
    sql1 { DROP VIEW IF EXISTS aux.v1 }
    sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
    sql1 { DROP VIEW IF EXISTS aux.v1 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
  } {}
  do_test 3.$tn.3.2 {
    sql1 { DROP VIEW IF EXISTS v1 }
    sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
    sql1 { DROP VIEW IF EXISTS v1 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
  } {}
  
  # TRIGGER objects.
  #
  do_test 3.$tn.4.1 {
    sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
    sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
    sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
  } {}
  do_test 3.$tn.4.2 {
    sql1 { DROP TRIGGER IF EXISTS tr1 }
    sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
    sql1 { DROP TRIGGER IF EXISTS tr1 }
    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
  } {}
}


finish_test
Changes to test/incrvacuum2.test.
19
20
21
22
23
24
25

26
27
28
29
30
31
32
# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum || !pragma} {
  finish_test
  return
}



# Create a database in incremental vacuum mode that has many
# pages on the freelist.
#
do_test incrvacuum2-1.1 {
  execsql {
    PRAGMA page_size=1024;







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum || !pragma} {
  finish_test
  return
}

set testprefix incrvacuum2

# Create a database in incremental vacuum mode that has many
# pages on the freelist.
#
do_test incrvacuum2-1.1 {
  execsql {
    PRAGMA page_size=1024;
127
128
129
130
131
132
133
134
135










































































136
    BEGIN;
    DELETE FROM abc;
    PRAGMA incremental_vacuum;
    COMMIT;
  }
} {}

integrity_check incremental2-3.3











































































finish_test







|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    BEGIN;
    DELETE FROM abc;
    PRAGMA incremental_vacuum;
    COMMIT;
  }
} {}

integrity_check incrvacuum2-3.3

ifcapable wal {
  # At one point, when a specific page was being extracted from the b-tree
  # free-list (e.g. during an incremental-vacuum), all trunk pages that
  # occurred before the specific page in the free-list trunk were being
  # written to the journal or wal file. This is not necessary. Only the 
  # extracted page and the page that contains the pointer to it need to
  # be journalled.
  #
  # This problem was fixed by [d03d63d77e] (just before 3.7.6 release).
  #
  # This test case builds a database containing many free pages. Then runs
  # "PRAGMA incremental_vacuum(1)" until the db contains zero free pages.
  # Each "PRAGMA incremental_vacuum(1)" should modify at most 4 pages. The
  # worst case is when a trunk page is removed from the end of the db file.
  # In this case pages written are:
  #
  #   1. The previous trunk page (that contains a pointer to the recycled
  #      trunk page), and
  #   2. The leaf page transformed into a trunk page to replace the recycled
  #      page, and
  #   3. The trunk page that contained a pointer to the leaf page used 
  #      in (2), and
  #   4. Page 1. Page 1 is always updated, even in WAL mode, since it contains
  #      the "number of free-list pages" field.
  #
  db close
  forcedelete test.db
  sqlite3 db test.db

  do_execsql_test 4.1 {
    PRAGMA page_size = 512;
    PRAGMA auto_vacuum = 2;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(randomblob(400));
    INSERT INTO t1 SELECT * FROM t1;            --    2
    INSERT INTO t1 SELECT * FROM t1;            --    4
    INSERT INTO t1 SELECT * FROM t1;            --    8
    INSERT INTO t1 SELECT * FROM t1;            --   16
    INSERT INTO t1 SELECT * FROM t1;            --   32
    INSERT INTO t1 SELECT * FROM t1;            --  128
    INSERT INTO t1 SELECT * FROM t1;            --  256
    INSERT INTO t1 SELECT * FROM t1;            --  512
    INSERT INTO t1 SELECT * FROM t1;            -- 1024
    INSERT INTO t1 SELECT * FROM t1;            -- 2048
    INSERT INTO t1 SELECT * FROM t1;            -- 4096
    INSERT INTO t1 SELECT * FROM t1;            -- 8192
    DELETE FROM t1 WHERE oid>512;
    DELETE FROM t1;
  }

  do_test 4.2 {
    execsql { 
      PRAGMA journal_mode = WAL;
      PRAGMA incremental_vacuum(1);
      PRAGMA wal_checkpoint;
    }
    file size test.db-wal
  } {1640}

  do_test 4.3 {
    db close
    sqlite3 db test.db
    set maxsz 0
    while {[file size test.db] > [expr 512*3]} {
      execsql { PRAGMA journal_mode = WAL }
      execsql { PRAGMA wal_checkpoint }
      execsql { PRAGMA incremental_vacuum(1) }
      set newsz [file size test.db-wal]
      if {$newsz>$maxsz} {set maxsz $newsz}
    }
    set maxsz 
  } {2176}
}

finish_test
Deleted test/omitunique.test.
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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# 2011 March 10
#
# The author disclaims copyright to this source code.  In place of
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SQLITE_OMIT_UNIQUE_ENFORCEMENT
# compiler option.
#

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

set uniq_enforced 1
ifcapable !unique_enforcement {
  set uniq_enforced 0
}

# table with UNIQUE keyword on column
do_test omitunique-1.1 {
  catchsql { CREATE TABLE t1(a TEXT UNIQUE); }
} {0 {}}

# table with UNIQUE clause on column
do_test omitunique-1.2 {
  catchsql { CREATE TABLE t2(a TEXT, UNIQUE(a)); }
} {0 {}}

# table with UNIQUE index on column
do_test omitunique-1.3 {
  catchsql {
    CREATE TABLE t3(a TEXT);
    CREATE UNIQUE INDEX t3a ON t3(a);
  }
} {0 {}}

# table with regular index on column
do_test omitunique-1.4 {
  catchsql {
    CREATE TABLE t4(a TEXT);
    CREATE INDEX t4a ON t4(a);
  }
} {0 {}}

# table with no index on column
do_test omitunique-1.5 {
  catchsql { CREATE TABLE t5(a TEXT); }
} {0 {}}

# run our tests using several table/index forms
foreach {j tbl uniq cnt qp_est stat_enforce stat_omit } {
1 {t1} 1 1 1      {2 1} {9 9}
2 {t2} 1 1 1      {2 1} {9 9}
3 {t3} 1 1 1      {2 1} {9 9}
4 {t4} 0 9 10     {9 9} {9 9}
5 {t5} 0 9 100000 9     9
} {

  do_test omitunique-2.0.$j.1 {
    catchsql [ subst {INSERT INTO $tbl (a) VALUES('abc'); }]
  } {0 {}}
  do_test omitunique-2.0.$j.2 {
    catchsql [ subst {INSERT INTO $tbl (a) VALUES('123'); }]
  } {0 {}}

  # check various INSERT commands
  foreach {i cmd err} {
    1 {INSERT}             1   
    2 {INSERT OR IGNORE}   0 
    3 {INSERT OR REPLACE}  0
    4 {REPLACE}            0
    5 {INSERT OR FAIL}     1
    6 {INSERT OR ABORT}    1
    7 {INSERT OR ROLLBACK} 1
  } {

    ifcapable explain {
      set x [execsql [ subst { EXPLAIN $cmd INTO $tbl (a) VALUES('abc'); }]]
      ifcapable unique_enforcement {
          do_test omitunique-2.1.$j.$i.1 {
            regexp { IsUnique } $x
          } $uniq
      }
      ifcapable !unique_enforcement {
          do_test omitunique-2.1.$j.$i.1 {
            regexp { IsUnique } $x
          } {0}
      }
    }

    if { $uniq_enforced==0 || $uniq==0 || $err==0 } { 
      set msg {0 {}}
    } {
      set msg {1 {column a is not unique}}
    }
    do_test omitunique-2.1.$j.$i.3 {
      catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc'); }]
    } $msg

  }
  # end foreach cmd

  # check UPDATE command
  ifcapable explain {
    set x [execsql [ subst { EXPLAIN UPDATE $tbl SET a='abc'; }]]
    ifcapable unique_enforcement {
        do_test omitunique-2.2.$j.1 {
          regexp { IsUnique } $x
        } $uniq
    }
    ifcapable !unique_enforcement {
        do_test omitunique-2.2.$j.1 {
          regexp { IsUnique } $x
        } {0}
    }
  }
  if { $uniq_enforced==0 || $uniq==0 } { 
    set msg {0 {}}
  } {
    set msg {1 {column a is not unique}}
  }
  do_test omitunique-2.2.$j.3 {
    catchsql [ subst { UPDATE $tbl SET a='abc'; }]
  } $msg

  # check record counts
  do_test omitunique-2.3.$j {
    execsql [ subst { SELECT count(*) FROM $tbl WHERE a='abc'; }]
  } $cnt

  # make sure the query planner row estimate not affected because of omit enforcement
  ifcapable explain {
    do_test omitunique-2.4.$j {
      set x [ execsql [ subst { EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc'; }]]
      set y [ subst {~$qp_est row} ]
      regexp $y $x
    } {1}
  }

  # make sure we omit extra OP_Next opcodes when the UNIQUE constraints 
  # mean there will only be a single pass through the code 
  ifcapable explain {
    set x [execsql [ subst { EXPLAIN SELECT * FROM $tbl WHERE a='abc'; }]]
    do_test omitunique-2.5.$j {
      if { [ regexp { Next } $x ] } { expr { 0 } } { expr { 1 } }
    } $uniq
  }

  # make sure analyze index stats correct
  ifcapable analyze {
    if { $uniq_enforced==0 } { 
      set msg [ list $stat_omit ]
    } {
      set msg [ list $stat_enforce ]
    }
    do_test omitunique-2.6.$j {
      execsql [ subst { ANALYZE $tbl; } ]
      execsql [ subst { SELECT stat FROM sqlite_stat1 WHERE tbl='$tbl'; } ]
    } $msg
  }

}
# end foreach tbl

finish_test
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































Changes to test/thread1.test.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32


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

# Skip this whole file if the thread testing code is not enabled
#
ifcapable !mutex {
  finish_test
  return
}
if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
  finish_test
  return
}

# Create some data to work with
#







<
|
<
<







15
16
17
18
19
20
21

22


23
24
25
26
27
28
29


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

# Skip this whole file if the thread testing code is not enabled
#

if {[run_thread_tests]==0} { finish_test ; return }


if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
  finish_test
  return
}

# Create some data to work with
#
Changes to test/thread2.test.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#
# $Id: thread2.test,v 1.3 2008/10/07 15:25:49 drh Exp $


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

ifcapable !mutex {
  finish_test
  return
}


# Skip this whole file if the thread testing code is not enabled
#
if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
  finish_test
  return
}







<
|
<
<
<







13
14
15
16
17
18
19

20



21
22
23
24
25
26
27
#
# $Id: thread2.test,v 1.3 2008/10/07 15:25:49 drh Exp $


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


if {[run_thread_tests]==0} { finish_test ; return }




# Skip this whole file if the thread testing code is not enabled
#
if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
  finish_test
  return
}
Changes to test/thread_common.tcl.
85
86
87
88
89
90
91



92
93
94
95
96
97
98

# Return true if this build can run the multi-threaded tests.
#
proc run_thread_tests {{print_warning 0}} {
  ifcapable !mutex { 
    set zProblem "SQLite build is not threadsafe"
  }



  if {[info commands sqlthread] eq ""} {
    set zProblem "SQLite build is not threadsafe"
  }
  if {![info exists ::tcl_platform(threaded)]} {
    set zProblem "Linked against a non-threadsafe Tcl build"
  }
  if {[info exists zProblem]} {







>
>
>







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

# Return true if this build can run the multi-threaded tests.
#
proc run_thread_tests {{print_warning 0}} {
  ifcapable !mutex { 
    set zProblem "SQLite build is not threadsafe"
  }
  ifcapable mutex_noop { 
    set zProblem "SQLite build uses SQLITE_MUTEX_NOOP"
  }
  if {[info commands sqlthread] eq ""} {
    set zProblem "SQLite build is not threadsafe"
  }
  if {![info exists ::tcl_platform(threaded)]} {
    set zProblem "Linked against a non-threadsafe Tcl build"
  }
  if {[info exists zProblem]} {
Changes to test/wal.test.
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
    file exists test.db-wal
  } 0
  do_test 24.3 {
    file size test.db
  } [expr 84 * 1024]
  do_test 24.4 {
    execsql { 

      PRAGMA incremental_vacuum;
      PRAGMA wal_checkpoint;
    }
    file size test.db
  } [expr 3 * 1024]
  do_test 24.5 {
    file size test.db-wal







>







1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
    file exists test.db-wal
  } 0
  do_test 24.3 {
    file size test.db
  } [expr 84 * 1024]
  do_test 24.4 {
    execsql { 
      PRAGMA cache_size = 200;
      PRAGMA incremental_vacuum;
      PRAGMA wal_checkpoint;
    }
    file size test.db
  } [expr 3 * 1024]
  do_test 24.5 {
    file size test.db-wal