/ Check-in [4eaef4ad]
Login

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

Overview
Comment:Pull all the latest trunk changes into the apple-osx branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: 4eaef4ad4cfda519f18922a249904d16489ee606
User & Date: drh 2011-04-09 18:13:35
Context
2011-04-13
15:42
Update the apple-osx branch to version 3.7.6.1. check-in: 289194d6 user: drh tags: apple-osx
2011-04-09
18:13
Pull all the latest trunk changes into the apple-osx branch. check-in: 4eaef4ad user: drh tags: apple-osx
17:53
Remove an always-true conditional. Replace it with an assert(). check-in: 1c2f0f84 user: drh tags: trunk
2011-04-05
22:10
Merge the latest trunk changes into the apple-osx branch. check-in: c77a767c user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

   544    544         v = v*10 + c - '0';
   545    545         z++;
   546    546       }
   547    547       if( i==0 ) pTable->nRowEst = v;
   548    548       if( pIndex==0 ) break;
   549    549       pIndex->aiRowEst[i] = v;
   550    550       if( *z==' ' ) z++;
          551  +    if( memcmp(z, "unordered", 10)==0 ){
          552  +      pIndex->bUnordered = 1;
          553  +      break;
          554  +    }
   551    555     }
   552    556     return 0;
   553    557   }
   554    558   
   555    559   /*
   556    560   ** If the Index.aSample variable is not NULL, delete the aSample[] array
   557    561   ** and its contents.

Changes to src/attach.c.

   172    172           zKey = (char *)sqlite3_value_blob(argv[2]);
   173    173           rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
   174    174           break;
   175    175   
   176    176         case SQLITE_NULL:
   177    177           /* No key specified.  Use the key from the main database */
   178    178           sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
   179         -        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
          179  +        if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
          180  +          rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
          181  +        }
   180    182           break;
   181    183       }
   182    184     }
   183    185   #endif
   184    186   
   185    187     /* If the file was opened successfully, read the schema for the new database.
   186    188     ** If this fails, or if opening the file failed, then close the file and 

Changes to src/backup.c.

   215    215   */
   216    216   static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
   217    217     Pager * const pDestPager = sqlite3BtreePager(p->pDest);
   218    218     const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
   219    219     int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
   220    220     const int nCopy = MIN(nSrcPgsz, nDestPgsz);
   221    221     const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
          222  +#ifdef SQLITE_HAS_CODEC
          223  +  int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
          224  +  int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
          225  +#endif
   222    226   
   223    227     int rc = SQLITE_OK;
   224    228     i64 iOff;
   225    229   
   226    230     assert( p->bDestLocked );
   227    231     assert( !isFatalError(p->rc) );
   228    232     assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
................................................................................
   233    237     */
   234    238     if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
   235    239       rc = SQLITE_READONLY;
   236    240     }
   237    241   
   238    242   #ifdef SQLITE_HAS_CODEC
   239    243     /* Backup is not possible if the page size of the destination is changing
   240         -  ** a a codec is in use.
          244  +  ** and a codec is in use.
   241    245     */
   242    246     if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
   243    247       rc = SQLITE_READONLY;
   244    248     }
          249  +
          250  +  /* Backup is not possible if the number of bytes of reserve space differ
          251  +  ** between source and destination.  If there is a difference, try to
          252  +  ** fix the destination to agree with the source.  If that is not possible,
          253  +  ** then the backup cannot proceed.
          254  +  */
          255  +  if( nSrcReserve!=nDestReserve ){
          256  +    u32 newPgsz = nSrcPgsz;
          257  +    rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
          258  +    if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
          259  +  }
   245    260   #endif
   246    261   
   247    262     /* This loop runs once for each destination page spanned by the source 
   248    263     ** page. For each iteration, variable iOff is set to the byte offset
   249    264     ** of the destination page.
   250    265     */
   251    266     for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
................................................................................
   603    618     for(p=pBackup; p; p=p->pNext){
   604    619       assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
   605    620       if( !isFatalError(p->rc) && iPage<p->iNext ){
   606    621         /* The backup process p has already copied page iPage. But now it
   607    622         ** has been modified by a transaction on the source pager. Copy
   608    623         ** the new data into the backup.
   609    624         */
   610         -      int rc = backupOnePage(p, iPage, aData);
          625  +      int rc;
          626  +      assert( p->pDestDb );
          627  +      sqlite3_mutex_enter(p->pDestDb->mutex);
          628  +      rc = backupOnePage(p, iPage, aData);
          629  +      sqlite3_mutex_leave(p->pDestDb->mutex);
   611    630         assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
   612    631         if( rc!=SQLITE_OK ){
   613    632           p->rc = rc;
   614    633         }
   615    634       }
   616    635     }
   617    636   }

Changes to src/btmutex.c.

   198    198     Btree *p;
   199    199     assert( sqlite3_mutex_held(db->mutex) );
   200    200     for(i=0; i<db->nDb; i++){
   201    201       p = db->aDb[i].pBt;
   202    202       if( p ) sqlite3BtreeLeave(p);
   203    203     }
   204    204   }
          205  +
          206  +/*
          207  +** Return true if a particular Btree requires a lock.  Return FALSE if
          208  +** no lock is ever required since it is not sharable.
          209  +*/
          210  +int sqlite3BtreeSharable(Btree *p){
          211  +  return p->sharable;
          212  +}
   205    213   
   206    214   #ifndef NDEBUG
   207    215   /*
   208    216   ** Return true if the current thread holds the database connection
   209    217   ** mutex and all required BtShared mutexes.
   210    218   **
   211    219   ** This routine is used inside assert() statements only.

Changes to src/btree.c.

  2123   2123     sqlite3BtreeEnter(p);
  2124   2124     assert( pBt && pBt->pPager );
  2125   2125     rc = sqlite3PagerNosync(pBt->pPager);
  2126   2126     sqlite3BtreeLeave(p);
  2127   2127     return rc;
  2128   2128   }
  2129   2129   
  2130         -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
  2131   2130   /*
  2132   2131   ** Change the default pages size and the number of reserved bytes per page.
  2133   2132   ** Or, if the page size has already been fixed, return SQLITE_READONLY 
  2134   2133   ** without changing anything.
  2135   2134   **
  2136   2135   ** The page size must be a power of 2 between 512 and 65536.  If the page
  2137   2136   ** size supplied does not meet this constraint then the page size is not
................................................................................
  2178   2177   /*
  2179   2178   ** Return the currently defined page size
  2180   2179   */
  2181   2180   int sqlite3BtreeGetPageSize(Btree *p){
  2182   2181     return p->pBt->pageSize;
  2183   2182   }
  2184   2183   
         2184  +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
  2185   2185   /*
  2186   2186   ** Return the number of bytes of space at the end of every page that
  2187   2187   ** are intentually left unused.  This is the "reserved" space that is
  2188   2188   ** sometimes used by extensions.
  2189   2189   */
  2190   2190   int sqlite3BtreeGetReserve(Btree *p){
  2191   2191     int n;
................................................................................
  4815   4815           rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
  4816   4816         }
  4817   4817         if( rc ){
  4818   4818           pTrunk = 0;
  4819   4819           goto end_allocate_page;
  4820   4820         }
  4821   4821   
  4822         -      k = get4byte(&pTrunk->aData[4]);
         4822  +      k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
  4823   4823         if( k==0 && !searchList ){
  4824   4824           /* The trunk has no leaves and the list is not being searched. 
  4825   4825           ** So extract the trunk page itself and use it as the newly 
  4826   4826           ** allocated page */
  4827   4827           assert( pPrevTrunk==0 );
  4828   4828           rc = sqlite3PagerWrite(pTrunk->pDbPage);
  4829   4829           if( rc ){
................................................................................
  4900   4900           TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
  4901   4901   #endif
  4902   4902         }else if( k>0 ){
  4903   4903           /* Extract a leaf from the trunk */
  4904   4904           u32 closest;
  4905   4905           Pgno iPage;
  4906   4906           unsigned char *aData = pTrunk->aData;
  4907         -        rc = sqlite3PagerWrite(pTrunk->pDbPage);
  4908         -        if( rc ){
  4909         -          goto end_allocate_page;
  4910         -        }
  4911   4907           if( nearby>0 ){
  4912   4908             u32 i;
  4913   4909             int dist;
  4914   4910             closest = 0;
  4915   4911             dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
  4916   4912             for(i=1; i<k; i++){
  4917   4913               int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
................................................................................
  4933   4929           testcase( iPage==mxPage );
  4934   4930           if( !searchList || iPage==nearby ){
  4935   4931             int noContent;
  4936   4932             *pPgno = iPage;
  4937   4933             TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
  4938   4934                    ": %d more free pages\n",
  4939   4935                    *pPgno, closest+1, k, pTrunk->pgno, n-1));
         4936  +          rc = sqlite3PagerWrite(pTrunk->pDbPage);
         4937  +          if( rc ) goto end_allocate_page;
  4940   4938             if( closest<k-1 ){
  4941   4939               memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
  4942   4940             }
  4943   4941             put4byte(&aData[4], k-1);
  4944         -          assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
  4945   4942             noContent = !btreeGetHasContent(pBt, *pPgno);
  4946   4943             rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
  4947   4944             if( rc==SQLITE_OK ){
  4948   4945               rc = sqlite3PagerWrite((*ppPage)->pDbPage);
  4949   4946               if( rc!=SQLITE_OK ){
  4950   4947                 releasePage(*ppPage);
  4951   4948               }
................................................................................
  5006   5003         releasePage(*ppPage);
  5007   5004         return SQLITE_CORRUPT_BKPT;
  5008   5005       }
  5009   5006       (*ppPage)->isInit = 0;
  5010   5007     }else{
  5011   5008       *ppPage = 0;
  5012   5009     }
         5010  +  assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
  5013   5011     return rc;
  5014   5012   }
  5015   5013   
  5016   5014   /*
  5017   5015   ** This function is used to add page iPage to the database file free-list. 
  5018   5016   ** It is assumed that the page is not already a part of the free-list.
  5019   5017   **

Changes to src/btree.h.

   208    208     void sqlite3BtreeEnterAll(sqlite3*);
   209    209   #else
   210    210   # define sqlite3BtreeEnter(X) 
   211    211   # define sqlite3BtreeEnterAll(X)
   212    212   #endif
   213    213   
   214    214   #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
          215  +  int sqlite3BtreeSharable(Btree*);
   215    216     void sqlite3BtreeLeave(Btree*);
   216    217     void sqlite3BtreeEnterCursor(BtCursor*);
   217    218     void sqlite3BtreeLeaveCursor(BtCursor*);
   218    219     void sqlite3BtreeLeaveAll(sqlite3*);
   219    220   #ifndef NDEBUG
   220    221     /* These routines are used inside assert() statements only. */
   221    222     int sqlite3BtreeHoldsMutex(Btree*);
   222    223     int sqlite3BtreeHoldsAllMutexes(sqlite3*);
   223    224     int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
   224    225   #endif
   225    226   #else
   226    227   
          228  +# define sqlite3BtreeSharable(X) 0
   227    229   # define sqlite3BtreeLeave(X)
   228    230   # define sqlite3BtreeEnterCursor(X)
   229    231   # define sqlite3BtreeLeaveCursor(X)
   230    232   # define sqlite3BtreeLeaveAll(X)
   231    233   
   232    234   # define sqlite3BtreeHoldsMutex(X) 1
   233    235   # define sqlite3BtreeHoldsAllMutexes(X) 1
   234    236   # define sqlite3SchemaMutexHeld(X,Y,Z) 1
   235    237   #endif
   236    238   
   237    239   
   238    240   #endif /* _BTREE_H_ */

Changes to src/build.c.

   809    809       if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
   810    810         goto begin_table_error;
   811    811       }
   812    812       pTable = sqlite3FindTable(db, zName, zDb);
   813    813       if( pTable ){
   814    814         if( !noErr ){
   815    815           sqlite3ErrorMsg(pParse, "table %T already exists", pName);
          816  +      }else{
          817  +        assert( !db->init.busy );
          818  +        sqlite3CodeVerifySchema(pParse, iDb);
   816    819         }
   817    820         goto begin_table_error;
   818    821       }
   819    822       if( sqlite3FindIndex(db, zName, zDb)!=0 ){
   820    823         sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
   821    824         goto begin_table_error;
   822    825       }
................................................................................
  1996   1999     assert( pName->nSrc==1 );
  1997   2000     if( noErr ) db->suppressErr++;
  1998   2001     pTab = sqlite3LocateTable(pParse, isView, 
  1999   2002                               pName->a[0].zName, pName->a[0].zDatabase);
  2000   2003     if( noErr ) db->suppressErr--;
  2001   2004   
  2002   2005     if( pTab==0 ){
         2006  +    if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
  2003   2007       goto exit_drop_table;
  2004   2008     }
  2005   2009     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  2006   2010     assert( iDb>=0 && iDb<db->nDb );
  2007   2011   
  2008   2012     /* If pTab is a virtual table, call ViewGetColumnNames() to ensure
  2009   2013     ** it is initialized.
................................................................................
  2514   2518           sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
  2515   2519           goto exit_create_index;
  2516   2520         }
  2517   2521       }
  2518   2522       if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
  2519   2523         if( !ifNotExist ){
  2520   2524           sqlite3ErrorMsg(pParse, "index %s already exists", zName);
         2525  +      }else{
         2526  +        assert( !db->init.busy );
         2527  +        sqlite3CodeVerifySchema(pParse, iDb);
  2521   2528         }
  2522   2529         goto exit_create_index;
  2523   2530       }
  2524   2531     }else{
  2525   2532       int n;
  2526   2533       Index *pLoop;
  2527   2534       for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
................................................................................
  2907   2914     if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
  2908   2915       goto exit_drop_index;
  2909   2916     }
  2910   2917     pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  2911   2918     if( pIndex==0 ){
  2912   2919       if( !ifExists ){
  2913   2920         sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
         2921  +    }else{
         2922  +      sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
  2914   2923       }
  2915   2924       pParse->checkSchema = 1;
  2916   2925       goto exit_drop_index;
  2917   2926     }
  2918   2927     if( pIndex->autoIndex ){
  2919   2928       sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
  2920   2929         "or PRIMARY KEY constraint cannot be dropped", 0);
................................................................................
  3495   3504         pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
  3496   3505         if( !OMIT_TEMPDB && iDb==1 ){
  3497   3506           sqlite3OpenTempDatabase(pToplevel);
  3498   3507         }
  3499   3508       }
  3500   3509     }
  3501   3510   }
         3511  +
         3512  +/*
         3513  +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each 
         3514  +** attached database. Otherwise, invoke it for the database named zDb only.
         3515  +*/
         3516  +void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
         3517  +  sqlite3 *db = pParse->db;
         3518  +  int i;
         3519  +  for(i=0; i<db->nDb; i++){
         3520  +    Db *pDb = &db->aDb[i];
         3521  +    if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
         3522  +      sqlite3CodeVerifySchema(pParse, i);
         3523  +    }
         3524  +  }
         3525  +}
  3502   3526   
  3503   3527   /*
  3504   3528   ** Generate VDBE code that prepares for doing an operation that
  3505   3529   ** might change the database.
  3506   3530   **
  3507   3531   ** This routine starts a new transaction if we are not already within
  3508   3532   ** a transaction.  If we are already within a transaction, then a checkpoint

Changes to src/ctime.c.

   298    298   #endif
   299    299   #ifdef SQLITE_OMIT_TRIGGER
   300    300     "OMIT_TRIGGER",
   301    301   #endif
   302    302   #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
   303    303     "OMIT_TRUNCATE_OPTIMIZATION",
   304    304   #endif
   305         -#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
   306         -  "OMIT_UNIQUE_ENFORCEMENT",
   307         -#endif
   308    305   #ifdef SQLITE_OMIT_UTF16
   309    306     "OMIT_UTF16",
   310    307   #endif
   311    308   #ifdef SQLITE_OMIT_VACUUM
   312    309     "OMIT_VACUUM",
   313    310   #endif
   314    311   #ifdef SQLITE_OMIT_VIEW

Changes to src/insert.c.

  1308   1308   
  1309   1309     /* Test all UNIQUE constraints by creating entries for each UNIQUE
  1310   1310     ** index and making sure that duplicate entries do not already exist.
  1311   1311     ** Add the new records to the indices as we go.
  1312   1312     */
  1313   1313     for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
  1314   1314       int regIdx;
  1315         -#ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT
  1316   1315       int regR;
  1317         -#endif
         1316  +
  1318   1317       if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */
  1319   1318   
  1320   1319       /* Create a key for accessing the index entry */
  1321   1320       regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
  1322   1321       for(i=0; i<pIdx->nColumn; i++){
  1323   1322         int idx = pIdx->aiColumn[i];
  1324   1323         if( idx==pTab->iPKey ){
................................................................................
  1328   1327         }
  1329   1328       }
  1330   1329       sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
  1331   1330       sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
  1332   1331       sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
  1333   1332       sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
  1334   1333   
  1335         -#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
  1336         -    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
  1337         -    continue;  /* Treat pIdx as if it is not a UNIQUE index */
  1338         -#else
  1339         -
  1340   1334       /* Find out what action to take in case there is an indexing conflict */
  1341   1335       onError = pIdx->onError;
  1342   1336       if( onError==OE_None ){ 
  1343   1337         sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
  1344   1338         continue;  /* pIdx is not a UNIQUE index */
  1345   1339       }
  1346   1340       if( overrideError!=OE_Default ){
................................................................................
  1406   1400           );
  1407   1401           seenReplace = 1;
  1408   1402           break;
  1409   1403         }
  1410   1404       }
  1411   1405       sqlite3VdbeJumpHere(v, j3);
  1412   1406       sqlite3ReleaseTempReg(pParse, regR);
  1413         -#endif
  1414   1407     }
  1415   1408     
  1416   1409     if( pbMayReplace ){
  1417   1410       *pbMayReplace = seenReplace;
  1418   1411     }
  1419   1412   }
  1420   1413   

Changes to src/loadext.c.

    66     66   # define sqlite3_column_origin_name16   0
    67     67   #endif
    68     68   
    69     69   #ifdef SQLITE_OMIT_COMPLETE
    70     70   # define sqlite3_complete 0
    71     71   # define sqlite3_complete16 0
    72     72   #endif
           73  +
           74  +#ifdef SQLITE_OMIT_DECLTYPE
           75  +# define sqlite3_column_decltype16      0
           76  +# define sqlite3_column_decltype        0
           77  +#endif
    73     78   
    74     79   #ifdef SQLITE_OMIT_PROGRESS_CALLBACK
    75     80   # define sqlite3_progress_handler 0
    76     81   #endif
    77     82   
    78     83   #ifdef SQLITE_OMIT_VIRTUALTABLE
    79     84   # define sqlite3_create_module 0

Changes to src/main.c.

   514    514   */
   515    515   int sqlite3_db_config(sqlite3 *db, int op, ...){
   516    516     va_list ap;
   517    517     int rc;
   518    518     va_start(ap, op);
   519    519     switch( op ){
   520    520       case SQLITE_DBCONFIG_LOOKASIDE: {
   521         -      void *pBuf = va_arg(ap, void*); /* IMP: R-21112-12275 */
          521  +      void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
   522    522         int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
   523    523         int cnt = va_arg(ap, int);      /* IMP: R-04460-53386 */
   524    524         rc = setupLookaside(db, pBuf, sz, cnt);
   525    525         break;
   526    526       }
   527    527       default: {
   528    528         static const struct {

Changes to src/os_unix.c.

  3409   3409         ** ftruncate() to set the file size, then write a single byte to
  3410   3410         ** the last byte in each block within the extended region. This
  3411   3411         ** is the same technique used by glibc to implement posix_fallocate()
  3412   3412         ** on systems that do not have a real fallocate() system call.
  3413   3413         */
  3414   3414         int nBlk = buf.st_blksize;  /* File-system block size */
  3415   3415         i64 iWrite;                 /* Next offset to write to */
  3416         -      int nWrite;                 /* Return value from seekAndWrite() */
  3417   3416   
  3418   3417         if( robust_ftruncate(pFile->h, nSize) ){
  3419   3418           pFile->lastErrno = errno;
  3420   3419           return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
  3421   3420         }
  3422   3421         iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
  3423         -      do {
  3424         -        nWrite = seekAndWrite(pFile, iWrite, "", 1);
         3422  +      while( iWrite<nSize ){
         3423  +        int nWrite = seekAndWrite(pFile, iWrite, "", 1);
         3424  +        if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
  3425   3425           iWrite += nBlk;
  3426         -      } while( nWrite==1 && iWrite<nSize );
  3427         -      if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
         3426  +      }
  3428   3427   #endif
  3429   3428       }
  3430   3429     }
  3431   3430   
  3432   3431     return SQLITE_OK;
  3433   3432   }
  3434   3433   

Changes to src/prepare.c.

    33     33       sqlite3SetString(pData->pzErrMsg, db,
    34     34         "malformed database schema (%s)", zObj);
    35     35       if( zExtra ){
    36     36         *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, 
    37     37                                    "%s - %s", *pData->pzErrMsg, zExtra);
    38     38       }
    39     39     }
    40         -  pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT;
           40  +  pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
    41     41   }
    42     42   
    43     43   /*
    44     44   ** This is the callback routine for the code that initializes the
    45     45   ** database.  See sqlite3Init() below for additional information.
    46     46   ** This routine is also called from the OP_ParseSchema opcode of the VDBE.
    47     47   **

Changes to src/select.c.

   802    802     if( pParse->explain==2 ){
   803    803       Vdbe *v = pParse->pVdbe;
   804    804       char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
   805    805       sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
   806    806     }
   807    807   }
   808    808   
          809  +/*
          810  +** Assign expression b to lvalue a. A second, no-op, version of this macro
          811  +** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code
          812  +** in sqlite3Select() to assign values to structure member variables that
          813  +** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the
          814  +** code with #ifndef directives.
          815  +*/
          816  +# define explainSetInteger(a, b) a = b
          817  +
          818  +#else
          819  +/* No-op versions of the explainXXX() functions and macros. */
          820  +# define explainTempTable(y,z)
          821  +# define explainSetInteger(y,z)
          822  +#endif
          823  +
          824  +#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
   809    825   /*
   810    826   ** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
   811    827   ** is a no-op. Otherwise, it adds a single row of output to the EQP result,
   812    828   ** where the caption is of one of the two forms:
   813    829   **
   814    830   **   "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
   815    831   **   "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
................................................................................
   833    849       char *zMsg = sqlite3MPrintf(
   834    850           pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
   835    851           bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
   836    852       );
   837    853       sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
   838    854     }
   839    855   }
   840         -
   841         -/*
   842         -** Assign expression b to lvalue a. A second, no-op, version of this macro
   843         -** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code
   844         -** in sqlite3Select() to assign values to structure member variables that
   845         -** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the
   846         -** code with #ifndef directives.
   847         -*/
   848         -# define explainSetInteger(a, b) a = b
   849         -
   850    856   #else
   851    857   /* No-op versions of the explainXXX() functions and macros. */
   852         -# define explainTempTable(y,z)
   853    858   # define explainComposite(v,w,x,y,z)
   854         -# define explainSetInteger(y,z)
   855    859   #endif
   856    860   
   857    861   /*
   858    862   ** If the inner loop was generated using a non-null pOrderBy argument,
   859    863   ** then the results were placed in a sorter.  After the loop is terminated
   860    864   ** we need to run the sorter and output the results.  The following
   861    865   ** routine generates the code needed to do that.

Changes to src/shell.c.

  2195   2195       int testctrl = -1;
  2196   2196       int rc = 0;
  2197   2197       int i, n;
  2198   2198       open_db(p);
  2199   2199   
  2200   2200       /* convert testctrl text option to value. allow any unique prefix
  2201   2201       ** of the option name, or a numerical value. */
  2202         -    n = strlen(azArg[1]);
         2202  +    n = strlen30(azArg[1]);
  2203   2203       for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
  2204   2204         if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
  2205   2205           if( testctrl<0 ){
  2206   2206             testctrl = aCtrl[i].ctrlCode;
  2207   2207           }else{
  2208   2208             fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
  2209   2209             testctrl = -1;

Changes to src/sqlite.h.in.

   723    723   ** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
   724    724   ** SQLite and sent to all VFSes in place of a call to the xSync method
   725    725   ** when the database connection has [PRAGMA synchronous] set to OFF.)^
   726    726   ** Some specialized VFSes need this signal in order to operate correctly
   727    727   ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most 
   728    728   ** VFSes do not need this signal and should silently ignore this opcode.
   729    729   ** Applications should not call [sqlite3_file_control()] with this
   730         -** opcode as doing so may disrupt the operation of the specilized VFSes
          730  +** opcode as doing so may disrupt the operation of the specialized VFSes
   731    731   ** that do require it.  
   732    732   */
   733    733   #define SQLITE_FCNTL_LOCKSTATE        1
   734    734   #define SQLITE_GET_LOCKPROXYFILE      2
   735    735   #define SQLITE_SET_LOCKPROXYFILE      3
   736    736   #define SQLITE_LAST_ERRNO             4
   737    737   #define SQLITE_FCNTL_SIZE_HINT        5
................................................................................
  1305   1305   ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
  1306   1306   ** allocation statistics are disabled by default.
  1307   1307   ** </dd>
  1308   1308   **
  1309   1309   ** <dt>SQLITE_CONFIG_SCRATCH</dt>
  1310   1310   ** <dd> ^This option specifies a static memory buffer that SQLite can use for
  1311   1311   ** scratch memory.  There are three arguments:  A pointer an 8-byte
  1312         -** aligned memory buffer from which the scrach allocations will be
         1312  +** aligned memory buffer from which the scratch allocations will be
  1313   1313   ** drawn, the size of each scratch allocation (sz),
  1314   1314   ** and the maximum number of scratch allocations (N).  The sz
  1315   1315   ** argument must be a multiple of 16.
  1316   1316   ** The first argument must be a pointer to an 8-byte aligned buffer
  1317   1317   ** of at least sz*N bytes of memory.
  1318   1318   ** ^SQLite will use no more than two scratch buffers per thread.  So
  1319   1319   ** N should be set to twice the expected maximum number of threads.
................................................................................
  1457   1457   ** is invoked.
  1458   1458   **
  1459   1459   ** <dl>
  1460   1460   ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
  1461   1461   ** <dd> ^This option takes three additional arguments that determine the 
  1462   1462   ** [lookaside memory allocator] configuration for the [database connection].
  1463   1463   ** ^The first argument (the third parameter to [sqlite3_db_config()] is a
  1464         -** pointer to an memory buffer to use for lookaside memory.
         1464  +** pointer to a memory buffer to use for lookaside memory.
  1465   1465   ** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
  1466   1466   ** may be NULL in which case SQLite will allocate the
  1467   1467   ** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
  1468   1468   ** size of each lookaside buffer slot.  ^The third argument is the number of
  1469   1469   ** slots.  The size of the buffer in the first argument must be greater than
  1470   1470   ** or equal to the product of the second and third arguments.  The buffer
  1471   1471   ** must be aligned to an 8-byte boundary.  ^If the second argument to
................................................................................
  1489   1489   ** following this call.  The second parameter may be a NULL pointer, in
  1490   1490   ** which case the FK enforcement setting is not reported back. </dd>
  1491   1491   **
  1492   1492   ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
  1493   1493   ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
  1494   1494   ** There should be two additional arguments.
  1495   1495   ** The first argument is an integer which is 0 to disable triggers,
  1496         -** positive to enable trigers or negative to leave the setting unchanged.
         1496  +** positive to enable triggers or negative to leave the setting unchanged.
  1497   1497   ** The second parameter is a pointer to an integer into which
  1498   1498   ** is written 0 or 1 to indicate whether triggers are disabled or enabled
  1499   1499   ** following this call.  The second parameter may be a NULL pointer, in
  1500   1500   ** which case the trigger setting is not reported back. </dd>
  1501   1501   **
  1502   1502   ** </dl>
  1503   1503   */
................................................................................
  2101   2101   ** method.
  2102   2102   */
  2103   2103   void sqlite3_randomness(int N, void *P);
  2104   2104   
  2105   2105   /*
  2106   2106   ** CAPI3REF: Compile-Time Authorization Callbacks
  2107   2107   **
  2108         -** ^This routine registers a authorizer callback with a particular
         2108  +** ^This routine registers an authorizer callback with a particular
  2109   2109   ** [database connection], supplied in the first argument.
  2110   2110   ** ^The authorizer callback is invoked as SQL statements are being compiled
  2111   2111   ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
  2112   2112   ** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()].  ^At various
  2113   2113   ** points during the compilation process, as logic is being created
  2114   2114   ** to perform various actions, the authorizer callback is invoked to
  2115   2115   ** see if those actions are allowed.  ^The authorizer callback should
................................................................................
  2747   2747   ** An sqlite3_value object may be either "protected" or "unprotected".
  2748   2748   ** Some interfaces require a protected sqlite3_value.  Other interfaces
  2749   2749   ** will accept either a protected or an unprotected sqlite3_value.
  2750   2750   ** Every interface that accepts sqlite3_value arguments specifies
  2751   2751   ** whether or not it requires a protected sqlite3_value.
  2752   2752   **
  2753   2753   ** The terms "protected" and "unprotected" refer to whether or not
  2754         -** a mutex is held.  A internal mutex is held for a protected
         2754  +** a mutex is held.  An internal mutex is held for a protected
  2755   2755   ** sqlite3_value object but no mutex is held for an unprotected
  2756   2756   ** sqlite3_value object.  If SQLite is compiled to be single-threaded
  2757   2757   ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
  2758   2758   ** or if SQLite is run in one of reduced mutex modes 
  2759   2759   ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
  2760   2760   ** then there is no distinction between protected and unprotected
  2761   2761   ** sqlite3_value objects and they can be used interchangeably.  However,
................................................................................
  3433   3433   ** KEYWORDS: {application-defined SQL function}
  3434   3434   ** KEYWORDS: {application-defined SQL functions}
  3435   3435   **
  3436   3436   ** ^These functions (collectively known as "function creation routines")
  3437   3437   ** are used to add SQL functions or aggregates or to redefine the behavior
  3438   3438   ** of existing SQL functions or aggregates.  The only differences between
  3439   3439   ** these routines are the text encoding expected for
  3440         -** the the second parameter (the name of the function being created)
         3440  +** the second parameter (the name of the function being created)
  3441   3441   ** and the presence or absence of a destructor callback for
  3442   3442   ** the application data pointer.
  3443   3443   **
  3444   3444   ** ^The first parameter is the [database connection] to which the SQL
  3445   3445   ** function is to be added.  ^If an application uses more than one database
  3446   3446   ** connection then application-defined SQL functions must be added
  3447   3447   ** to each database connection separately.
................................................................................
  3478   3478   **
  3479   3479   ** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
  3480   3480   ** pointers to C-language functions that implement the SQL function or
  3481   3481   ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
  3482   3482   ** callback only; NULL pointers must be passed as the xStep and xFinal
  3483   3483   ** parameters. ^An aggregate SQL function requires an implementation of xStep
  3484   3484   ** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
  3485         -** SQL function or aggregate, pass NULL poiners for all three function
         3485  +** SQL function or aggregate, pass NULL pointers for all three function
  3486   3486   ** callbacks.
  3487   3487   **
  3488   3488   ** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
  3489   3489   ** then it is destructor for the application data pointer. 
  3490   3490   ** The destructor is invoked when the function is deleted, either by being
  3491   3491   ** overloaded or when the database connection closes.)^
  3492   3492   ** ^The destructor is also invoked if the call to
................................................................................
  3912   3912   ** ^The eTextRep argument determines the encoding of strings passed
  3913   3913   ** to the collating function callback, xCallback.
  3914   3914   ** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
  3915   3915   ** force strings to be UTF16 with native byte order.
  3916   3916   ** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
  3917   3917   ** on an even byte address.
  3918   3918   **
  3919         -** ^The fourth argument, pArg, is a application data pointer that is passed
         3919  +** ^The fourth argument, pArg, is an application data pointer that is passed
  3920   3920   ** through as the first argument to the collating function callback.
  3921   3921   **
  3922   3922   ** ^The fifth argument, xCallback, is a pointer to the collating function.
  3923   3923   ** ^Multiple collating functions can be registered using the same name but
  3924   3924   ** with different eTextRep parameters and SQLite will use whichever
  3925   3925   ** function requires the least amount of data transformation.
  3926   3926   ** ^If the xCallback argument is NULL then the collating function is
................................................................................
  3928   3928   ** that collation is no longer usable.
  3929   3929   **
  3930   3930   ** ^The collating function callback is invoked with a copy of the pArg 
  3931   3931   ** application data pointer and with two strings in the encoding specified
  3932   3932   ** by the eTextRep argument.  The collating function must return an
  3933   3933   ** integer that is negative, zero, or positive
  3934   3934   ** if the first string is less than, equal to, or greater than the second,
  3935         -** respectively.  A collating function must alway return the same answer
         3935  +** respectively.  A collating function must always return the same answer
  3936   3936   ** given the same inputs.  If two or more collating functions are registered
  3937   3937   ** to the same collation name (using different eTextRep values) then all
  3938   3938   ** must give an equivalent answer when invoked with equivalent strings.
  3939   3939   ** The collating function must obey the following properties for all
  3940   3940   ** strings A, B, and C:
  3941   3941   **
  3942   3942   ** <ol>
................................................................................
  4340   4340   ** if one or more of following conditions are true:
  4341   4341   **
  4342   4342   ** <ul>
  4343   4343   ** <li> The soft heap limit is set to zero.
  4344   4344   ** <li> Memory accounting is disabled using a combination of the
  4345   4345   **      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
  4346   4346   **      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
  4347         -** <li> An alternative page cache implementation is specifed using
         4347  +** <li> An alternative page cache implementation is specified using
  4348   4348   **      [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
  4349   4349   ** <li> The page cache allocates from its own memory pool supplied
  4350   4350   **      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
  4351   4351   **      from the heap.
  4352   4352   ** </ul>)^
  4353   4353   **
  4354   4354   ** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
................................................................................
  4561   4561   typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
  4562   4562   typedef struct sqlite3_module sqlite3_module;
  4563   4563   
  4564   4564   /*
  4565   4565   ** CAPI3REF: Virtual Table Object
  4566   4566   ** KEYWORDS: sqlite3_module {virtual table module}
  4567   4567   **
  4568         -** This structure, sometimes called a a "virtual table module", 
         4568  +** This structure, sometimes called a "virtual table module", 
  4569   4569   ** defines the implementation of a [virtual tables].  
  4570   4570   ** This structure consists mostly of methods for the module.
  4571   4571   **
  4572   4572   ** ^A virtual table module is created by filling in a persistent
  4573   4573   ** instance of this structure and passing a pointer to that instance
  4574   4574   ** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
  4575   4575   ** ^The registration remains valid until it is replaced by a different
................................................................................
  4873   4873   **
  4874   4874   ** ^(If the row that a BLOB handle points to is modified by an
  4875   4875   ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
  4876   4876   ** then the BLOB handle is marked as "expired".
  4877   4877   ** This is true if any column of the row is changed, even a column
  4878   4878   ** other than the one the BLOB handle is open on.)^
  4879   4879   ** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
  4880         -** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
         4880  +** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
  4881   4881   ** ^(Changes written into a BLOB prior to the BLOB expiring are not
  4882   4882   ** rolled back by the expiration of the BLOB.  Such changes will eventually
  4883   4883   ** commit if the transaction continues to completion.)^
  4884   4884   **
  4885   4885   ** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
  4886   4886   ** the opened blob.  ^The size of a blob may not be changed by this
  4887   4887   ** interface.  Use the [UPDATE] SQL command to change the size of a

Changes to src/sqliteInt.h.

  1472   1472     int nColumn;     /* Number of columns in the table used by this index */
  1473   1473     int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
  1474   1474     unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
  1475   1475     Table *pTable;   /* The SQL table being indexed */
  1476   1476     int tnum;        /* Page containing root of this index in database file */
  1477   1477     u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  1478   1478     u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
         1479  +  u8 bUnordered;   /* Use this index for == or IN queries only */
  1479   1480     char *zColAff;   /* String defining the affinity of each column */
  1480   1481     Index *pNext;    /* The next index associated with the same table */
  1481   1482     Schema *pSchema; /* Schema containing this index */
  1482   1483     u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
  1483   1484     char **azColl;   /* Array of collation sequence names for index */
  1484   1485     IndexSample *aSample;    /* Array of SQLITE_INDEX_SAMPLES samples */
  1485   1486   };
................................................................................
  2763   2764   void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
  2764   2765   Vdbe *sqlite3GetVdbe(Parse*);
  2765   2766   void sqlite3PrngSaveState(void);
  2766   2767   void sqlite3PrngRestoreState(void);
  2767   2768   void sqlite3PrngResetState(void);
  2768   2769   void sqlite3RollbackAll(sqlite3*);
  2769   2770   void sqlite3CodeVerifySchema(Parse*, int);
         2771  +void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
  2770   2772   void sqlite3BeginTransaction(Parse*, int);
  2771   2773   void sqlite3CommitTransaction(Parse*);
  2772   2774   void sqlite3RollbackTransaction(Parse*);
  2773   2775   void sqlite3Savepoint(Parse*, int, Token*);
  2774   2776   void sqlite3CloseSavepoints(sqlite3 *);
  2775   2777   int sqlite3ExprIsConstant(Expr*);
  2776   2778   int sqlite3ExprIsConstantNotJoin(Expr*);

Changes to src/sqliteLimit.h.

   114    114   */
   115    115   #ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
   116    116   # define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT  1000
   117    117   #endif
   118    118   
   119    119   /*
   120    120   ** The maximum number of attached databases.  This must be between 0
   121         -** and 30.  The upper bound on 30 is because a 32-bit integer bitmap
          121  +** and 62.  The upper bound on 62 is because a 64-bit integer bitmap
   122    122   ** is used internally to track attached databases.
   123    123   */
   124    124   #ifndef SQLITE_MAX_ATTACHED
   125    125   # define SQLITE_MAX_ATTACHED 10
   126    126   #endif
   127    127   
   128    128   

Changes to src/test_config.c.

    86     86   #endif
    87     87   
    88     88   #ifdef SQLITE_MUTEX_OMIT
    89     89     Tcl_SetVar2(interp, "sqlite_options", "mutex", "0", TCL_GLOBAL_ONLY);
    90     90   #else
    91     91     Tcl_SetVar2(interp, "sqlite_options", "mutex", "1", TCL_GLOBAL_ONLY);
    92     92   #endif
           93  +
           94  +#ifdef SQLITE_MUTEX_NOOP
           95  +  Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "1", TCL_GLOBAL_ONLY);
           96  +#else
           97  +  Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "0", TCL_GLOBAL_ONLY);
           98  +#endif
    93     99   
    94    100   #ifdef SQLITE_OMIT_ALTERTABLE
    95    101     Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY);
    96    102   #else
    97    103     Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY);
    98    104   #endif
    99    105   
................................................................................
   471    477   
   472    478   #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
   473    479     Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "0", TCL_GLOBAL_ONLY);
   474    480   #else
   475    481     Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY);
   476    482   #endif
   477    483   
   478         -#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
   479         -  Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "0", TCL_GLOBAL_ONLY);
   480         -#else
   481         -  Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "1", TCL_GLOBAL_ONLY);
   482         -#endif
   483         -
   484    484   #ifdef SQLITE_OMIT_UTF16
   485    485     Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY);
   486    486   #else
   487    487     Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY);
   488    488   #endif
   489    489   
   490    490   #if defined(SQLITE_OMIT_VACUUM) || defined(SQLITE_OMIT_ATTACH)

Changes to src/test_server.c.

   449    449   
   450    450       /* Signal the client that the message has been processed.
   451    451       */
   452    452       pMsg->op = MSG_Done;
   453    453       pthread_mutex_unlock(&pMsg->clientMutex);
   454    454       pthread_cond_signal(&pMsg->clientWakeup);
   455    455     }
   456         -  sqlite3_thread_cleanup();
   457    456     pthread_mutex_unlock(&g.serverMutex);
   458    457     return 0;
   459    458   }
   460    459   
   461    460   /*
   462    461   ** Start a server thread if one is not already running.  If there
   463    462   ** is aleady a server thread running, the new thread will quickly

Changes to src/trigger.c.

   167    167       goto trigger_cleanup;
   168    168     }
   169    169     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   170    170     if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
   171    171                         zName, sqlite3Strlen30(zName)) ){
   172    172       if( !noErr ){
   173    173         sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
          174  +    }else{
          175  +      assert( !db->init.busy );
          176  +      sqlite3CodeVerifySchema(pParse, iDb);
   174    177       }
   175    178       goto trigger_cleanup;
   176    179     }
   177    180   
   178    181     /* Do not create a trigger on a system table */
   179    182     if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
   180    183       sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
................................................................................
   495    498       assert( sqlite3SchemaMutexHeld(db, j, 0) );
   496    499       pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
   497    500       if( pTrigger ) break;
   498    501     }
   499    502     if( !pTrigger ){
   500    503       if( !noErr ){
   501    504         sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
          505  +    }else{
          506  +      sqlite3CodeVerifyNamedSchema(pParse, zDb);
   502    507       }
   503    508       pParse->checkSchema = 1;
   504    509       goto drop_trigger_cleanup;
   505    510     }
   506    511     sqlite3DropTriggerPtr(pParse, pTrigger);
   507    512   
   508    513   drop_trigger_cleanup:

Changes to src/vdbe.c.

  4641   4641     ** sqlite3InitCallback().
  4642   4642     */
  4643   4643   #ifdef SQLITE_DEBUG
  4644   4644     for(iDb=0; iDb<db->nDb; iDb++){
  4645   4645       assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
  4646   4646     }
  4647   4647   #endif
  4648         -  assert( p->btreeMask == ~(yDbMask)0 );
  4649         -
  4650   4648   
  4651   4649     iDb = pOp->p1;
  4652   4650     assert( iDb>=0 && iDb<db->nDb );
  4653   4651     assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
  4654   4652     /* Used to be a conditional */ {
  4655   4653       zMaster = SCHEMA_TABLE(iDb);
  4656   4654       initData.db = db;

Changes to src/vdbeInt.h.

   299    299     u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   300    300     u8 inVtabMethod;        /* See comments above */
   301    301     u8 usesStmtJournal;     /* True if uses a statement journal */
   302    302     u8 readOnly;            /* True for read-only statements */
   303    303     u8 isPrepareV2;         /* True if prepared with prepare_v2() */
   304    304     int nChange;            /* Number of db changes made since last reset */
   305    305     yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
          306  +  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
   306    307     int iStatement;         /* Statement number (or 0 if has not opened stmt) */
   307    308     int aCounter[3];        /* Counters used by sqlite3_stmt_status() */
   308    309   #ifndef SQLITE_OMIT_TRACE
   309    310     i64 startTime;          /* Time when query started - used for profiling */
   310    311   #endif
   311    312     i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   312    313     i64 nStmtDefCons;       /* Number of def. constraints when stmt started */

Changes to src/vdbeaux.c.

   156    156     pOp->p3 = p3;
   157    157     pOp->p4.p = 0;
   158    158     pOp->p4type = P4_NOTUSED;
   159    159     p->expired = 0;
   160    160     if( op==OP_ParseSchema ){
   161    161       /* Any program that uses the OP_ParseSchema opcode needs to lock
   162    162       ** all btrees. */
   163         -    p->btreeMask = ~(yDbMask)0;
          163  +    int j;
          164  +    for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
   164    165     }
   165    166   #ifdef SQLITE_DEBUG
   166    167     pOp->zComment = 0;
   167    168     if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
   168    169   #endif
   169    170   #ifdef VDBE_PROFILE
   170    171     pOp->cycles = 0;
................................................................................
   954    955   ** attached databases that they will be using.  A mask of these databases
   955    956   ** is maintained in p->btreeMask and is used for locking and other purposes.
   956    957   */
   957    958   void sqlite3VdbeUsesBtree(Vdbe *p, int i){
   958    959     assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 );
   959    960     assert( i<(int)sizeof(p->btreeMask)*8 );
   960    961     p->btreeMask |= ((yDbMask)1)<<i;
          962  +  if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){
          963  +    p->lockMask |= ((yDbMask)1)<<i;
          964  +  }
   961    965   }
   962    966   
   963    967   #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
   964    968   /*
   965    969   ** If SQLite is compiled to support shared-cache mode and to be threadsafe,
   966    970   ** this routine obtains the mutex associated with each BtShared structure
   967    971   ** that may be accessed by the VM passed as an argument. In doing so it also
................................................................................
   981    985   ** corresponding to btrees that use shared cache.  Then the runtime of
   982    986   ** this routine is N*N.  But as N is rarely more than 1, this should not
   983    987   ** be a problem.
   984    988   */
   985    989   void sqlite3VdbeEnter(Vdbe *p){
   986    990     int i;
   987    991     yDbMask mask;
   988         -  sqlite3 *db = p->db;
   989         -  Db *aDb = db->aDb;
   990         -  int nDb = db->nDb;
          992  +  sqlite3 *db;
          993  +  Db *aDb;
          994  +  int nDb;
          995  +  if( p->lockMask==0 ) return;  /* The common case */
          996  +  db = p->db;
          997  +  aDb = db->aDb;
          998  +  nDb = db->nDb;
   991    999     for(i=0, mask=1; i<nDb; i++, mask += mask){
   992         -    if( i!=1 && (mask & p->btreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){
         1000  +    if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){
   993   1001         sqlite3BtreeEnter(aDb[i].pBt);
   994   1002       }
   995   1003     }
   996   1004   }
   997   1005   #endif
   998   1006   
   999   1007   #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
  1000   1008   /*
  1001   1009   ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter().
  1002   1010   */
  1003   1011   void sqlite3VdbeLeave(Vdbe *p){
  1004   1012     int i;
  1005   1013     yDbMask mask;
  1006         -  sqlite3 *db = p->db;
  1007         -  Db *aDb = db->aDb;
  1008         -  int nDb = db->nDb;
  1009         -
         1014  +  sqlite3 *db;
         1015  +  Db *aDb;
         1016  +  int nDb;
         1017  +  if( p->lockMask==0 ) return;  /* The common case */
         1018  +  db = p->db;
         1019  +  aDb = db->aDb;
         1020  +  nDb = db->nDb;
  1010   1021     for(i=0, mask=1; i<nDb; i++, mask += mask){
  1011         -    if( i!=1 && (mask & p->btreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){
         1022  +    if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){
  1012   1023         sqlite3BtreeLeave(aDb[i].pBt);
  1013   1024       }
  1014   1025     }
  1015   1026   }
  1016   1027   #endif
  1017   1028   
  1018   1029   #if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)

Changes to src/vdbetrace.c.

    81     81                         db->aLimit[SQLITE_LIMIT_LENGTH]);
    82     82     out.db = db;
    83     83     if( db->vdbeExecCnt>1 ){
    84     84       while( *zRawSql ){
    85     85         const char *zStart = zRawSql;
    86     86         while( *(zRawSql++)!='\n' && *zRawSql );
    87     87         sqlite3StrAccumAppend(&out, "-- ", 3);
    88         -      sqlite3StrAccumAppend(&out, zStart, zRawSql-zStart);
           88  +      sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
    89     89       }
    90     90     }else{
    91     91       while( zRawSql[0] ){
    92     92         n = findNextHostParameter(zRawSql, &nToken);
    93     93         assert( n>0 );
    94     94         sqlite3StrAccumAppend(&out, zRawSql, n);
    95     95         zRawSql += n;

Changes to src/where.c.

  1338   1338     ** virtual term of that form.
  1339   1339     **
  1340   1340     ** Note that the virtual term must be tagged with TERM_VNULL.  This
  1341   1341     ** TERM_VNULL tag will suppress the not-null check at the beginning
  1342   1342     ** of the loop.  Without the TERM_VNULL flag, the not-null check at
  1343   1343     ** the start of the loop will prevent any results from being returned.
  1344   1344     */
  1345         -  if( pExpr->op==TK_NOTNULL && pExpr->pLeft->iColumn>=0 ){
         1345  +  if( pExpr->op==TK_NOTNULL
         1346  +   && pExpr->pLeft->op==TK_COLUMN
         1347  +   && pExpr->pLeft->iColumn>=0
         1348  +  ){
  1346   1349       Expr *pNewExpr;
  1347   1350       Expr *pLeft = pExpr->pLeft;
  1348   1351       int idxNew;
  1349   1352       WhereTerm *pNewTerm;
  1350   1353   
  1351   1354       pNewExpr = sqlite3PExpr(pParse, TK_GT,
  1352   1355                               sqlite3ExprDup(db, pLeft, 0),
................................................................................
  2528   2531   ** non-zero.
  2529   2532   **
  2530   2533   ** This routine can fail if it is unable to load a collating sequence
  2531   2534   ** required for string comparison, or if unable to allocate memory
  2532   2535   ** for a UTF conversion required for comparison.  The error is stored
  2533   2536   ** in the pParse structure.
  2534   2537   */
  2535         -int whereEqualScanEst(
         2538  +static int whereEqualScanEst(
  2536   2539     Parse *pParse,       /* Parsing & code generating context */
  2537   2540     Index *p,            /* The index whose left-most column is pTerm */
  2538   2541     Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
  2539   2542     double *pnRow        /* Write the revised row estimate here */
  2540   2543   ){
  2541   2544     sqlite3_value *pRhs = 0;  /* VALUE on right-hand side of pTerm */
  2542   2545     int iLower, iUpper;       /* Range of histogram regions containing pRhs */
................................................................................
  2585   2588   ** non-zero.
  2586   2589   **
  2587   2590   ** This routine can fail if it is unable to load a collating sequence
  2588   2591   ** required for string comparison, or if unable to allocate memory
  2589   2592   ** for a UTF conversion required for comparison.  The error is stored
  2590   2593   ** in the pParse structure.
  2591   2594   */
  2592         -int whereInScanEst(
         2595  +static int whereInScanEst(
  2593   2596     Parse *pParse,       /* Parsing & code generating context */
  2594   2597     Index *p,            /* The index whose left-most column is pTerm */
  2595   2598     ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
  2596   2599     double *pnRow        /* Write the revised row estimate here */
  2597   2600   ){
  2598   2601     sqlite3_value *pVal = 0;  /* One value from list */
  2599   2602     int iLower, iUpper;       /* Range of histogram regions containing pRhs */
................................................................................
  2856   2859   #ifdef SQLITE_ENABLE_STAT2
  2857   2860         if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
  2858   2861   #endif
  2859   2862         used |= pTerm->prereqRight;
  2860   2863       }
  2861   2864   
  2862   2865       /* Determine the value of estBound. */
  2863         -    if( nEq<pProbe->nColumn ){
         2866  +    if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
  2864   2867         int j = pProbe->aiColumn[nEq];
  2865   2868         if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
  2866   2869           WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
  2867   2870           WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
  2868   2871           whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
  2869   2872           if( pTop ){
  2870   2873             nBound = 1;
................................................................................
  2888   2891   
  2889   2892       /* If there is an ORDER BY clause and the index being considered will
  2890   2893       ** naturally scan rows in the required order, set the appropriate flags
  2891   2894       ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
  2892   2895       ** will scan rows in a different order, set the bSort variable.  */
  2893   2896       if( pOrderBy ){
  2894   2897         if( (wsFlags & WHERE_COLUMN_IN)==0
         2898  +        && pProbe->bUnordered==0
  2895   2899           && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
  2896   2900                             nEq, wsFlags, &rev)
  2897   2901         ){
  2898   2902           wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
  2899   2903           wsFlags |= (rev ? WHERE_REVERSE : 0);
  2900   2904         }else{
  2901   2905           bSort = 1;

Changes to test/analyze5.test.

   205    205   #
   206    206   foreach {testid where index rows} {
   207    207     500  {x IS NULL AND u='charlie'}         t1u  20
   208    208     501  {x=1 AND u='charlie'}               t1x   5
   209    209     502  {x IS NULL}                          {} 100
   210    210     503  {x=1}                               t1x  50
   211    211     504  {x IS NOT NULL}                     t1x  25
          212  +  505  {+x IS NOT NULL}                     {} 500
          213  +  506  {upper(x) IS NOT NULL}               {} 500
   212    214   
   213    215   } {
   214    216     # Verify that the expected index is used with the expected row count
   215    217     do_test analyze5-1.${testid}a {
   216    218       set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
   217    219       set idx {}
   218    220       regexp {INDEX (t1.) } $x all idx

Changes to test/analyze7.test.

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

Added test/attach4.test.

            1  +# 200 July 1
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this script is attaching many database files to a single
           13  +# connection.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +
           19  +set testprefix attach4
           20  +
           21  +ifcapable !attach {
           22  +  finish_test
           23  +  return
           24  +}
           25  +
           26  +puts "Testing with SQLITE_MAX_ATTACHED=$SQLITE_MAX_ATTACHED"
           27  +
           28  +set files {main test.db}
           29  +for {set ii 0} {$ii < $SQLITE_MAX_ATTACHED} {incr ii} {
           30  +  lappend files aux$ii "test.db$ii"
           31  +}
           32  +
           33  +do_test 1.1 {
           34  +  sqlite3_limit db SQLITE_LIMIT_ATTACHED -1
           35  +} $SQLITE_MAX_ATTACHED
           36  +
           37  +do_test 1.2.1 {
           38  +  db close
           39  +  foreach {name f} $files { forcedelete $f }
           40  +  sqlite3 db test.db
           41  +  
           42  +  foreach {name f} $files {
           43  +    if {$name == "main"} continue
           44  +    execsql "ATTACH '$f' AS $name"
           45  +  }
           46  +
           47  +  db eval {PRAGMA database_list} {
           48  +    lappend L $name [file tail $file]
           49  +  }
           50  +  set L
           51  +} $files
           52  +
           53  +do_catchsql_test 1.2.2 {
           54  +  ATTACH 'x.db' AS next;
           55  +} [list 1 "too many attached databases - max $SQLITE_MAX_ATTACHED"]
           56  +
           57  +do_test 1.3 {
           58  +  execsql BEGIN;
           59  +  foreach {name f} $files {
           60  +    execsql "CREATE TABLE $name.tbl(x)"
           61  +    execsql "INSERT INTO $name.tbl VALUES('$f')"
           62  +  }
           63  +  execsql COMMIT;
           64  +} {}
           65  +
           66  +do_test 1.4 {
           67  +  set L [list]
           68  +  foreach {name f} $files {
           69  +    lappend L $name [execsql "SELECT x FROM $name.tbl"]
           70  +  }
           71  +  set L
           72  +} $files
           73  +
           74  +set L [list]
           75  +set S ""
           76  +foreach {name f} $files {
           77  +  if {[permutation] == "journaltest"} {
           78  +    lappend L delete
           79  +  } else {
           80  +    lappend L wal
           81  +  }
           82  +  append S "
           83  +    PRAGMA $name.journal_mode = WAL;
           84  +    UPDATE $name.tbl SET x = '$name';
           85  +  "
           86  +}
           87  +do_execsql_test 1.5 $S $L
           88  +
           89  +do_test 1.6 {
           90  +  set L [list]
           91  +  foreach {name f} $files {
           92  +    lappend L [execsql "SELECT x FROM $name.tbl"] $f
           93  +  }
           94  +  set L
           95  +} $files
           96  +
           97  +do_test 1.7 {
           98  +  execsql BEGIN;
           99  +  foreach {name f} $files {
          100  +    execsql "UPDATE $name.tbl SET x = '$f'"
          101  +  }
          102  +  execsql COMMIT;
          103  +} {}
          104  +
          105  +do_test 1.8 {
          106  +  set L [list]
          107  +  foreach {name f} $files {
          108  +    lappend L $name [execsql "SELECT x FROM $name.tbl"]
          109  +  }
          110  +  set L
          111  +} $files
          112  +
          113  +db close
          114  +foreach {name f} $files { forcedelete $f }
          115  +
          116  +finish_test

Changes to test/backcompat.test.

   362    362   
   363    363         6    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'aa'"
   364    364         7    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH '44'"
   365    365         8    "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'a*'"
   366    366       } {
   367    367         do_test backcompat-3.7 [list sql1 $q] [sql2 $q]
   368    368       }
          369  +  }
          370  +}
          371  +
          372  +#-------------------------------------------------------------------------
          373  +# Test that Rtree tables may be read/written by different versions of 
          374  +# SQLite. 
          375  +#
          376  +set contents {
          377  +  CREATE VIRTUAL TABLE t1 USING rtree(id, x1, x2, y1, y2);
          378  +}
          379  +foreach {id x1 x2 y1 y2} {
          380  +  1    -47.64 43.87    33.86 34.42        2    -21.51 17.32    2.05 31.04
          381  +  3    -43.67 -38.33    -19.79 3.43       4    32.41 35.16    9.12 19.82
          382  +  5    33.28 34.87    14.78 28.26         6    49.31 116.59    -9.87 75.09
          383  +  7    -14.93 34.51    -17.64 64.09       8    -43.05 23.43    -1.19 69.44
          384  +  9    44.79 133.56    28.09 80.30        10    -2.66 81.47    -41.38 -10.46
          385  +  11    -42.89 -3.54    15.76 71.63       12    -3.50 84.96    -11.64 64.95
          386  +  13    -45.69 26.25    11.14 55.06       14    -44.09 11.23    17.52 44.45
          387  +  15    36.23 133.49    -19.38 53.67      16    -17.89 81.54    14.64 50.61
          388  +  17    -41.97 -24.04    -39.43 28.95     18    -5.85 7.76    -6.38 47.02
          389  +  19    18.82 27.10    42.82 100.09       20    39.17 113.45    26.14 73.47
          390  +  21    22.31 103.17    49.92 106.05      22    -43.06 40.38    -1.75 76.08
          391  +  23    2.43 57.27    -14.19 -3.83        24    -47.57 -4.35    8.93 100.06
          392  +  25    -37.47 49.14    -29.11 8.81       26    -7.86 75.72    49.34 107.42
          393  +  27    1.53 45.49    20.36 49.74         28    -48.48 32.54    28.81 54.45
          394  +  29    2.67 39.77    -4.05 13.67         30    4.11 62.88    -47.44 -5.72
          395  +  31    -21.47 51.75    37.25 116.09      32    45.59 111.37    -6.43 43.64
          396  +  33    35.23 48.29    23.54 113.33       34    16.61 68.35    -14.69 65.97
          397  +  35    13.98 16.60    48.66 102.87       36    19.74 23.84    31.15 77.27
          398  +  37    -27.61 24.43    7.96 94.91        38    -34.77 12.05    -22.60 -6.29
          399  +  39    -25.83 8.71    -13.48 -12.53      40    -17.11 -1.01    18.06 67.89
          400  +  41    14.13 71.72    -3.78 39.25        42    23.75 76.00    -16.30 8.23
          401  +  43    -39.15 28.63    38.12 125.88      44    48.62 86.09    36.49 102.95
          402  +  45    -31.39 -21.98    2.52 89.78       46    5.65 56.04    15.94 89.10
          403  +  47    18.28 95.81    46.46 143.08       48    30.93 102.82    -20.08 37.36
          404  +  49    -20.78 -3.48    -5.58 35.46       50    49.85 90.58    -24.48 46.29
          405  +} {
          406  +if {$x1 >= $x2 || $y1 >= $y2} { error "$x1 $x2 $y1 $y2" }
          407  +  append contents "INSERT INTO t1 VALUES($id, $x1, $x2, $y1, $y2);"
          408  +}
          409  +set queries {
          410  +  1    "SELECT id FROM t1 WHERE x1>10 AND x2<44"
          411  +  2    "SELECT id FROM t1 WHERE y1<100"
          412  +  3    "SELECT id FROM t1 WHERE y1<100 AND x1>0"
          413  +  4    "SELECT id FROM t1 WHERE y1>10 AND x1>0 AND x2<50 AND y2<550"
          414  +}
          415  +do_allbackcompat_test {
          416  +  if {[code1 {set ::sqlite_options(fts3)}]
          417  +   && [code2 {set ::sqlite_options(fts3)}]
          418  +  } {
          419  +
          420  +    do_test backcompat-4.1 { sql1 $contents } {}
          421  +
          422  +    foreach {n q} $::queries {
          423  +      do_test backcompat-4.2.$n [list sql1 $q] [sql2 $q]
          424  +    }
          425  +
          426  +    do_test backcompat-4.3 { sql1 {
          427  +      INSERT INTO t1 SELECT id+100, x1+10.0, x2+10.0, y1-10.0, y2-10.0 FROM t1;
          428  +    } } {}
          429  +
          430  +    foreach {n q} $::queries {
          431  +      do_test backcompat-4.4.$n [list sql1 $q] [sql2 $q]
          432  +    }
          433  +
          434  +    do_test backcompat-4.5 { sql2 {
          435  +      INSERT INTO t1 SELECT id+200, x1+20.0, x2+20.0, y1-20.0, y2-20.0 FROM t1;
          436  +    } } {}
          437  +
          438  +    foreach {n q} $::queries {
          439  +      do_test backcompat-4.6.$n [list sql1 $q] [sql2 $q]
          440  +    }
          441  +
   369    442     }
   370    443   }
   371    444   
   372    445   finish_test

Added test/exists.test.

            1  +# 2011 April 9
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this file is testing the various schema modification statements
           13  +# that feature "IF EXISTS" or "IF NOT EXISTS" clauses.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/lock_common.tcl
           19  +
           20  +set testprefix exists
           21  +
           22  +# This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
           23  +#
           24  +do_multiclient_test tn {
           25  +
           26  +  # TABLE objects.
           27  +  #
           28  +  do_test 1.$tn.1.1 {
           29  +    sql2 { CREATE TABLE t1(x) }
           30  +    sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
           31  +    sql2 { DROP TABLE t1 }
           32  +    sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
           33  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
           34  +  } {t1}
           35  +
           36  +  do_test 1.$tn.1.2 {
           37  +    sql2 { CREATE TABLE t2(x) }
           38  +    sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
           39  +    sql2 { DROP TABLE t2 }
           40  +    sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
           41  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
           42  +  } {t1 t2}
           43  +
           44  +
           45  +  # INDEX objects.
           46  +  #
           47  +  do_test 1.$tn.2 {
           48  +    sql2 { CREATE INDEX i1 ON t1(a) }
           49  +    sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
           50  +    sql2 { DROP INDEX i1 }
           51  +    sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
           52  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
           53  +  } {i1}
           54  +
           55  +  # VIEW objects.
           56  +  #
           57  +  do_test 1.$tn.3 {
           58  +    sql2 { CREATE VIEW v1 AS SELECT * FROM t1 }
           59  +    sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
           60  +    sql2 { DROP VIEW v1 }
           61  +    sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
           62  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
           63  +  } {v1}
           64  +
           65  +  # TRIGGER objects.
           66  +  #
           67  +  do_test $tn.4 {
           68  +    sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
           69  +sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
           70  +    sql2 { DROP TRIGGER tr1 }
           71  +sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
           72  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
           73  +  } {tr1}
           74  +}
           75  +
           76  +# This block of tests is targeted at DROP XXX IF EXISTS statements.
           77  +#
           78  +do_multiclient_test tn {
           79  +
           80  +  # TABLE objects.
           81  +  #
           82  +  do_test 2.$tn.1 {
           83  +    sql1 { DROP TABLE IF EXISTS t1 }
           84  +    sql2 { CREATE TABLE t1(x) }
           85  +    sql1 { DROP TABLE IF EXISTS t1 }
           86  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
           87  +  } {}
           88  +
           89  +  # INDEX objects.
           90  +  #
           91  +  do_test 2.$tn.2 {
           92  +    sql1 { CREATE TABLE t2(x) }
           93  +    sql1 { DROP INDEX IF EXISTS i2 }
           94  +    sql2 { CREATE INDEX i2 ON t2(x) }
           95  +    sql1 { DROP INDEX IF EXISTS i2 }
           96  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
           97  +  } {}
           98  +
           99  +  # VIEW objects.
          100  +  #
          101  +  do_test 2.$tn.3 {
          102  +    sql1 { DROP VIEW IF EXISTS v1 }
          103  +    sql2 { CREATE VIEW v1 AS SELECT * FROM t2 }
          104  +    sql1 { DROP VIEW IF EXISTS v1 }
          105  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
          106  +  } {}
          107  +  
          108  +  # TRIGGER objects.
          109  +  #
          110  +  do_test 2.$tn.4 {
          111  +    sql1 { DROP TRIGGER IF EXISTS tr1 }
          112  +    sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
          113  +    sql1 { DROP TRIGGER IF EXISTS tr1 }
          114  +    sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
          115  +  } {}
          116  +}
          117  +
          118  +# This block of tests is targeted at DROP XXX IF EXISTS statements with
          119  +# attached databases.
          120  +#
          121  +do_multiclient_test tn {
          122  +
          123  +  forcedelete test.db2
          124  +  do_test 3.$tn.0 {
          125  +    sql1 { ATTACH 'test.db2' AS aux }
          126  +    sql2 { ATTACH 'test.db2' AS aux }
          127  +  } {}
          128  +
          129  +  # TABLE objects.
          130  +  #
          131  +  do_test 3.$tn.1.1 {
          132  +    sql1 { DROP TABLE IF EXISTS aux.t1 }
          133  +    sql2 { CREATE TABLE aux.t1(x) }
          134  +    sql1 { DROP TABLE IF EXISTS aux.t1 }
          135  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
          136  +  } {}
          137  +  do_test 3.$tn.1.2 {
          138  +    sql1 { DROP TABLE IF EXISTS t1 }
          139  +    sql2 { CREATE TABLE aux.t1(x) }
          140  +    sql1 { DROP TABLE IF EXISTS t1 }
          141  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
          142  +  } {}
          143  +
          144  +  # INDEX objects.
          145  +  #
          146  +  do_test 3.$tn.2.1 {
          147  +    sql1 { CREATE TABLE aux.t2(x) }
          148  +    sql1 { DROP INDEX IF EXISTS aux.i2 }
          149  +    sql2 { CREATE INDEX aux.i2 ON t2(x) }
          150  +    sql1 { DROP INDEX IF EXISTS aux.i2 }
          151  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
          152  +  } {}
          153  +  do_test 3.$tn.2.2 {
          154  +    sql1 { DROP INDEX IF EXISTS i2 }
          155  +    sql2 { CREATE INDEX aux.i2 ON t2(x) }
          156  +    sql1 { DROP INDEX IF EXISTS i2 }
          157  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
          158  +  } {}
          159  +
          160  +  # VIEW objects.
          161  +  #
          162  +  do_test 3.$tn.3.1 {
          163  +    sql1 { DROP VIEW IF EXISTS aux.v1 }
          164  +    sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
          165  +    sql1 { DROP VIEW IF EXISTS aux.v1 }
          166  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
          167  +  } {}
          168  +  do_test 3.$tn.3.2 {
          169  +    sql1 { DROP VIEW IF EXISTS v1 }
          170  +    sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
          171  +    sql1 { DROP VIEW IF EXISTS v1 }
          172  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
          173  +  } {}
          174  +  
          175  +  # TRIGGER objects.
          176  +  #
          177  +  do_test 3.$tn.4.1 {
          178  +    sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
          179  +    sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
          180  +    sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
          181  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
          182  +  } {}
          183  +  do_test 3.$tn.4.2 {
          184  +    sql1 { DROP TRIGGER IF EXISTS tr1 }
          185  +    sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
          186  +    sql1 { DROP TRIGGER IF EXISTS tr1 }
          187  +    sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
          188  +  } {}
          189  +}
          190  +
          191  +
          192  +finish_test

Changes to test/incrvacuum2.test.

    19     19   # If this build of the library does not support auto-vacuum, omit this
    20     20   # whole file.
    21     21   ifcapable {!autovacuum || !pragma} {
    22     22     finish_test
    23     23     return
    24     24   }
    25     25   
           26  +set testprefix incrvacuum2
    26     27   
    27     28   # Create a database in incremental vacuum mode that has many
    28     29   # pages on the freelist.
    29     30   #
    30     31   do_test incrvacuum2-1.1 {
    31     32     execsql {
    32     33       PRAGMA page_size=1024;
................................................................................
   127    128       BEGIN;
   128    129       DELETE FROM abc;
   129    130       PRAGMA incremental_vacuum;
   130    131       COMMIT;
   131    132     }
   132    133   } {}
   133    134   
   134         -integrity_check incremental2-3.3
          135  +integrity_check incrvacuum2-3.3
          136  +
          137  +ifcapable wal {
          138  +  # At one point, when a specific page was being extracted from the b-tree
          139  +  # free-list (e.g. during an incremental-vacuum), all trunk pages that
          140  +  # occurred before the specific page in the free-list trunk were being
          141  +  # written to the journal or wal file. This is not necessary. Only the 
          142  +  # extracted page and the page that contains the pointer to it need to
          143  +  # be journalled.
          144  +  #
          145  +  # This problem was fixed by [d03d63d77e] (just before 3.7.6 release).
          146  +  #
          147  +  # This test case builds a database containing many free pages. Then runs
          148  +  # "PRAGMA incremental_vacuum(1)" until the db contains zero free pages.
          149  +  # Each "PRAGMA incremental_vacuum(1)" should modify at most 4 pages. The
          150  +  # worst case is when a trunk page is removed from the end of the db file.
          151  +  # In this case pages written are:
          152  +  #
          153  +  #   1. The previous trunk page (that contains a pointer to the recycled
          154  +  #      trunk page), and
          155  +  #   2. The leaf page transformed into a trunk page to replace the recycled
          156  +  #      page, and
          157  +  #   3. The trunk page that contained a pointer to the leaf page used 
          158  +  #      in (2), and
          159  +  #   4. Page 1. Page 1 is always updated, even in WAL mode, since it contains
          160  +  #      the "number of free-list pages" field.
          161  +  #
          162  +  db close
          163  +  forcedelete test.db
          164  +  sqlite3 db test.db
          165  +
          166  +  do_execsql_test 4.1 {
          167  +    PRAGMA page_size = 512;
          168  +    PRAGMA auto_vacuum = 2;
          169  +    CREATE TABLE t1(x);
          170  +    INSERT INTO t1 VALUES(randomblob(400));
          171  +    INSERT INTO t1 SELECT * FROM t1;            --    2
          172  +    INSERT INTO t1 SELECT * FROM t1;            --    4
          173  +    INSERT INTO t1 SELECT * FROM t1;            --    8
          174  +    INSERT INTO t1 SELECT * FROM t1;            --   16
          175  +    INSERT INTO t1 SELECT * FROM t1;            --   32
          176  +    INSERT INTO t1 SELECT * FROM t1;            --  128
          177  +    INSERT INTO t1 SELECT * FROM t1;            --  256
          178  +    INSERT INTO t1 SELECT * FROM t1;            --  512
          179  +    INSERT INTO t1 SELECT * FROM t1;            -- 1024
          180  +    INSERT INTO t1 SELECT * FROM t1;            -- 2048
          181  +    INSERT INTO t1 SELECT * FROM t1;            -- 4096
          182  +    INSERT INTO t1 SELECT * FROM t1;            -- 8192
          183  +    DELETE FROM t1 WHERE oid>512;
          184  +    DELETE FROM t1;
          185  +  }
          186  +
          187  +  do_test 4.2 {
          188  +    execsql { 
          189  +      PRAGMA journal_mode = WAL;
          190  +      PRAGMA incremental_vacuum(1);
          191  +      PRAGMA wal_checkpoint;
          192  +    }
          193  +    file size test.db-wal
          194  +  } {1640}
          195  +
          196  +  do_test 4.3 {
          197  +    db close
          198  +    sqlite3 db test.db
          199  +    set maxsz 0
          200  +    while {[file size test.db] > [expr 512*3]} {
          201  +      execsql { PRAGMA journal_mode = WAL }
          202  +      execsql { PRAGMA wal_checkpoint }
          203  +      execsql { PRAGMA incremental_vacuum(1) }
          204  +      set newsz [file size test.db-wal]
          205  +      if {$newsz>$maxsz} {set maxsz $newsz}
          206  +    }
          207  +    set maxsz 
          208  +  } {2176}
          209  +}
   135    210   
   136    211   finish_test

Deleted test/omitunique.test.

     1         -# 2011 March 10
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this file is testing the SQLITE_OMIT_UNIQUE_ENFORCEMENT
    13         -# compiler option.
    14         -#
    15         -
    16         -set testdir [file dirname $argv0]
    17         -source $testdir/tester.tcl
    18         -
    19         -set uniq_enforced 1
    20         -ifcapable !unique_enforcement {
    21         -  set uniq_enforced 0
    22         -}
    23         -
    24         -# table with UNIQUE keyword on column
    25         -do_test omitunique-1.1 {
    26         -  catchsql { CREATE TABLE t1(a TEXT UNIQUE); }
    27         -} {0 {}}
    28         -
    29         -# table with UNIQUE clause on column
    30         -do_test omitunique-1.2 {
    31         -  catchsql { CREATE TABLE t2(a TEXT, UNIQUE(a)); }
    32         -} {0 {}}
    33         -
    34         -# table with UNIQUE index on column
    35         -do_test omitunique-1.3 {
    36         -  catchsql {
    37         -    CREATE TABLE t3(a TEXT);
    38         -    CREATE UNIQUE INDEX t3a ON t3(a);
    39         -  }
    40         -} {0 {}}
    41         -
    42         -# table with regular index on column
    43         -do_test omitunique-1.4 {
    44         -  catchsql {
    45         -    CREATE TABLE t4(a TEXT);
    46         -    CREATE INDEX t4a ON t4(a);
    47         -  }
    48         -} {0 {}}
    49         -
    50         -# table with no index on column
    51         -do_test omitunique-1.5 {
    52         -  catchsql { CREATE TABLE t5(a TEXT); }
    53         -} {0 {}}
    54         -
    55         -# run our tests using several table/index forms
    56         -foreach {j tbl uniq cnt qp_est stat_enforce stat_omit } {
    57         -1 {t1} 1 1 1      {2 1} {9 9}
    58         -2 {t2} 1 1 1      {2 1} {9 9}
    59         -3 {t3} 1 1 1      {2 1} {9 9}
    60         -4 {t4} 0 9 10     {9 9} {9 9}
    61         -5 {t5} 0 9 100000 9     9
    62         -} {
    63         -
    64         -  do_test omitunique-2.0.$j.1 {
    65         -    catchsql [ subst {INSERT INTO $tbl (a) VALUES('abc'); }]
    66         -  } {0 {}}
    67         -  do_test omitunique-2.0.$j.2 {
    68         -    catchsql [ subst {INSERT INTO $tbl (a) VALUES('123'); }]
    69         -  } {0 {}}
    70         -
    71         -  # check various INSERT commands
    72         -  foreach {i cmd err} {
    73         -    1 {INSERT}             1   
    74         -    2 {INSERT OR IGNORE}   0 
    75         -    3 {INSERT OR REPLACE}  0
    76         -    4 {REPLACE}            0
    77         -    5 {INSERT OR FAIL}     1
    78         -    6 {INSERT OR ABORT}    1
    79         -    7 {INSERT OR ROLLBACK} 1
    80         -  } {
    81         -
    82         -    ifcapable explain {
    83         -      set x [execsql [ subst { EXPLAIN $cmd INTO $tbl (a) VALUES('abc'); }]]
    84         -      ifcapable unique_enforcement {
    85         -          do_test omitunique-2.1.$j.$i.1 {
    86         -            regexp { IsUnique } $x
    87         -          } $uniq
    88         -      }
    89         -      ifcapable !unique_enforcement {
    90         -          do_test omitunique-2.1.$j.$i.1 {
    91         -            regexp { IsUnique } $x
    92         -          } {0}
    93         -      }
    94         -    }
    95         -
    96         -    if { $uniq_enforced==0 || $uniq==0 || $err==0 } { 
    97         -      set msg {0 {}}
    98         -    } {
    99         -      set msg {1 {column a is not unique}}
   100         -    }
   101         -    do_test omitunique-2.1.$j.$i.3 {
   102         -      catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc'); }]
   103         -    } $msg
   104         -
   105         -  }
   106         -  # end foreach cmd
   107         -
   108         -  # check UPDATE command
   109         -  ifcapable explain {
   110         -    set x [execsql [ subst { EXPLAIN UPDATE $tbl SET a='abc'; }]]
   111         -    ifcapable unique_enforcement {
   112         -        do_test omitunique-2.2.$j.1 {
   113         -          regexp { IsUnique } $x
   114         -        } $uniq
   115         -    }
   116         -    ifcapable !unique_enforcement {
   117         -        do_test omitunique-2.2.$j.1 {
   118         -          regexp { IsUnique } $x
   119         -        } {0}
   120         -    }
   121         -  }
   122         -  if { $uniq_enforced==0 || $uniq==0 } { 
   123         -    set msg {0 {}}
   124         -  } {
   125         -    set msg {1 {column a is not unique}}
   126         -  }
   127         -  do_test omitunique-2.2.$j.3 {
   128         -    catchsql [ subst { UPDATE $tbl SET a='abc'; }]
   129         -  } $msg
   130         -
   131         -  # check record counts
   132         -  do_test omitunique-2.3.$j {
   133         -    execsql [ subst { SELECT count(*) FROM $tbl WHERE a='abc'; }]
   134         -  } $cnt
   135         -
   136         -  # make sure the query planner row estimate not affected because of omit enforcement
   137         -  ifcapable explain {
   138         -    do_test omitunique-2.4.$j {
   139         -      set x [ execsql [ subst { EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc'; }]]
   140         -      set y [ subst {~$qp_est row} ]
   141         -      regexp $y $x
   142         -    } {1}
   143         -  }
   144         -
   145         -  # make sure we omit extra OP_Next opcodes when the UNIQUE constraints 
   146         -  # mean there will only be a single pass through the code 
   147         -  ifcapable explain {
   148         -    set x [execsql [ subst { EXPLAIN SELECT * FROM $tbl WHERE a='abc'; }]]
   149         -    do_test omitunique-2.5.$j {
   150         -      if { [ regexp { Next } $x ] } { expr { 0 } } { expr { 1 } }
   151         -    } $uniq
   152         -  }
   153         -
   154         -  # make sure analyze index stats correct
   155         -  ifcapable analyze {
   156         -    if { $uniq_enforced==0 } { 
   157         -      set msg [ list $stat_omit ]
   158         -    } {
   159         -      set msg [ list $stat_enforce ]
   160         -    }
   161         -    do_test omitunique-2.6.$j {
   162         -      execsql [ subst { ANALYZE $tbl; } ]
   163         -      execsql [ subst { SELECT stat FROM sqlite_stat1 WHERE tbl='$tbl'; } ]
   164         -    } $msg
   165         -  }
   166         -
   167         -}
   168         -# end foreach tbl
   169         -
   170         -finish_test

Changes to test/releasetest.tcl.

    56     56     ########################################################
    57     57   }
    58     58   
    59     59   array set ::Configs {
    60     60     "Default" {
    61     61       -O2
    62     62     }
           63  +  "Ftrapv" {
           64  +    -O2 -ftrapv
           65  +    -DSQLITE_MAX_ATTACHED=55
           66  +    -DSQLITE_TCL_DEFAULT_FULLMUTEX=1
           67  +  }
    63     68     "Unlock-Notify" {
    64     69       -O2
    65     70       -DSQLITE_ENABLE_UNLOCK_NOTIFY
    66     71       -DSQLITE_THREADSAFE
    67     72       -DSQLITE_TCL_DEFAULT_FULLMUTEX=1
    68     73     }
    69     74     "Secure-Delete" {
................................................................................
   140    145       -DSQLITE_MAX_LENGTH=2147483645
   141    146       -DSQLITE_MAX_VARIABLE_NUMBER=500000
   142    147       -DSQLITE_DEBUG=1 
   143    148       -DSQLITE_PREFER_PROXY_LOCKING=1
   144    149     }
   145    150     "Extra-Robustness" {
   146    151       -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
          152  +    -DSQLITE_MAX_ATTACHED=62
   147    153     }
   148    154   }
   149    155   
   150    156   array set ::Platforms {
   151    157     Linux-x86_64 {
   152    158       "Secure-Delete"           test
   153    159       "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
   154    160       "Update-Delete-Limit"     test
   155    161       "Debug-One"               test
   156    162       "Extra-Robustness"        test
   157    163       "Device-Two"              test
          164  +    "Ftrapv"                  test
   158    165       "Default"                 "threadtest test"
   159    166       "Device-One"              fulltest
   160    167     }
   161    168     Linux-i686 {
   162    169       "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
   163    170       "Device-One"              test
   164    171       "Device-Two"              test

Changes to test/syscall.test.

   235    235   forcedelete test.db test.db2
   236    236   
   237    237   do_test 8.1 {
   238    238     sqlite3 db test.db
   239    239     file_control_chunksize_test db main 4096
   240    240     file size test.db
   241    241   } {0}
   242         -
   243    242   foreach {tn hint size} {
   244    243     1  1000    4096 
   245    244     2  1000    4096 
   246    245     3  3000    4096 
   247    246     4  4096    4096 
   248    247     5  4197    8192 
   249    248   } {
   250    249     do_test 8.2.$tn {
          250  +    file_control_sizehint_test db main $hint
          251  +    file size test.db
          252  +  } $size
          253  +}
          254  +
          255  +do_test 8.3 {
          256  +  db close
          257  +  forcedelete test.db test.db2
          258  +  sqlite3 db test.db
          259  +  file_control_chunksize_test db main 16
          260  +  file size test.db
          261  +} {0}
          262  +foreach {tn hint size} {
          263  +  1  5       16 
          264  +  2  13      16 
          265  +  3  45      48 
          266  +  4  48      48 
          267  +  5  49      64 
          268  +} {
          269  +  do_test 8.4.$tn {
   251    270       file_control_sizehint_test db main $hint
   252    271       file size test.db
   253    272     } $size
   254    273   }
   255    274   
   256    275   test_syscall reset
   257    276   finish_test

Changes to test/thread1.test.

    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Skip this whole file if the thread testing code is not enabled
    21     21   #
    22         -ifcapable !mutex {
    23         -  finish_test
    24         -  return
    25         -}
           22  +if {[run_thread_tests]==0} { finish_test ; return }
    26     23   if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
    27     24     finish_test
    28     25     return
    29     26   }
    30     27   
    31     28   # Create some data to work with
    32     29   #

Changes to test/thread2.test.

    13     13   #
    14     14   # $Id: thread2.test,v 1.3 2008/10/07 15:25:49 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20         -ifcapable !mutex {
    21         -  finish_test
    22         -  return
    23         -}
    24         -
           20  +if {[run_thread_tests]==0} { finish_test ; return }
    25     21   
    26     22   # Skip this whole file if the thread testing code is not enabled
    27     23   #
    28     24   if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
    29     25     finish_test
    30     26     return
    31     27   }

Changes to test/thread_common.tcl.

    85     85   
    86     86   # Return true if this build can run the multi-threaded tests.
    87     87   #
    88     88   proc run_thread_tests {{print_warning 0}} {
    89     89     ifcapable !mutex { 
    90     90       set zProblem "SQLite build is not threadsafe"
    91     91     }
           92  +  ifcapable mutex_noop { 
           93  +    set zProblem "SQLite build uses SQLITE_MUTEX_NOOP"
           94  +  }
    92     95     if {[info commands sqlthread] eq ""} {
    93     96       set zProblem "SQLite build is not threadsafe"
    94     97     }
    95     98     if {![info exists ::tcl_platform(threaded)]} {
    96     99       set zProblem "Linked against a non-threadsafe Tcl build"
    97    100     }
    98    101     if {[info exists zProblem]} {

Changes to test/wal.test.

  1530   1530       CREATE TABLE t1(x);
  1531   1531       INSERT INTO t1 VALUES(randomblob(5000));
  1532   1532       INSERT INTO t1 SELECT * FROM t1;
  1533   1533       INSERT INTO t1 SELECT * FROM t1;
  1534   1534       INSERT INTO t1 SELECT * FROM t1;
  1535   1535       INSERT INTO t1 SELECT * FROM t1;
  1536   1536     } {wal}
  1537         -  do_execsql_test 24.2 { 
  1538         -    DELETE FROM t1;
  1539         -    PRAGMA wal_checkpoint;
  1540         -  } {0 109 109}
  1541         -  do_test 24.3 {
         1537  +  do_test 24.2 { 
         1538  +    execsql {
         1539  +      DELETE FROM t1;
         1540  +      PRAGMA wal_checkpoint;
         1541  +    }
  1542   1542       db close
  1543   1543       sqlite3 db test.db
  1544   1544       file exists test.db-wal
  1545   1545     } 0
  1546         -  do_test 24.4 {
         1546  +  do_test 24.3 {
  1547   1547       file size test.db
  1548   1548     } [expr 84 * 1024]
  1549         -  do_test 24.5 {
         1549  +  do_test 24.4 {
  1550   1550       execsql { 
         1551  +      PRAGMA cache_size = 200;
  1551   1552         PRAGMA incremental_vacuum;
  1552   1553         PRAGMA wal_checkpoint;
  1553   1554       }
  1554   1555       file size test.db
  1555   1556     } [expr 3 * 1024]
  1556         -  do_test 24.6 {
         1557  +  do_test 24.5 {
  1557   1558       file size test.db-wal
  1558   1559     } 2128
  1559   1560   }
  1560   1561   
  1561   1562   db close
  1562   1563   sqlite3_shutdown
  1563   1564   test_sqlite3_log
  1564   1565   sqlite3_initialize
  1565   1566   
  1566   1567   finish_test

Changes to tool/omittest.tcl.

     4      4   # Documentation for this script. This may be output to stderr
     5      5   # if the script is invoked incorrectly.
     6      6   set ::USAGE_MESSAGE {
     7      7   This Tcl script is used to test the various compile time options 
     8      8   available for omitting code (the SQLITE_OMIT_xxx options). It
     9      9   should be invoked as follows:
    10     10   
    11         -    <script> ?-makefile PATH-TO-MAKEFILE? ?-skip_run?
           11  +    <script> ?test-symbol? ?-makefile PATH-TO-MAKEFILE? ?-skip_run?
    12     12   
    13     13   The default value for ::MAKEFILE is "../Makefile.linux.gcc".
    14     14   
    15     15   If -skip_run option is given then only the compile part is attempted.
    16     16   
    17     17   This script builds the testfixture program and runs the SQLite test suite
    18     18   once with each SQLITE_OMIT_ option defined and then once with all options
................................................................................
   116    116   # This proc processes the command line options passed to this script.
   117    117   # Currently the only option supported is "-makefile", default
   118    118   # "../Makefile.linux-gcc". Set the ::MAKEFILE variable to the value of this
   119    119   # option.
   120    120   #
   121    121   proc process_options {argv} {
   122    122     if {$::tcl_platform(platform)=="windows" || $::tcl_platform(platform)=="os2"} {
   123         -      set ::MAKEFILE ./Makefile                         ;# Default value
          123  +    set ::MAKEFILE ./Makefile               ;# Default value
   124    124     } else {
   125         -      set ::MAKEFILE ./Makefile.linux-gcc               ;# Default value
          125  +    set ::MAKEFILE ./Makefile.linux-gcc     ;# Default value
   126    126     }
   127         -  set ::SKIP_RUN 0                                      ;# Default to attempt test
          127  +  set ::SKIP_RUN 0                          ;# Default to attempt test
   128    128   
   129    129     for {set i 0} {$i < [llength $argv]} {incr i} {
   130    130       switch -- [lindex $argv $i] {
   131    131         -makefile {
   132    132           incr i
   133    133           set ::MAKEFILE [lindex $argv $i]
   134    134         }
   135    135     
   136    136         -skip_run {
   137         -        incr i
   138    137           set ::SKIP_RUN 1
   139    138         }
   140    139   
   141    140         default {
   142         -        puts stderr [string trim $::USAGE_MESSAGE]
   143         -        exit -1
          141  +        if {[info exists ::SYMBOL]} {
          142  +          puts stderr [string trim $::USAGE_MESSAGE]
          143  +          exit -1
          144  +        }
          145  +        set ::SYMBOL [lindex $argv $i]
   144    146         }
   145    147       }
   146    148       set ::MAKEFILE [file normalize $::MAKEFILE]
   147    149     }
   148    150   }
   149    151   
   150    152   # Main routine.
................................................................................
   237    239       SQLITE_ENABLE_UNLOCK_NOTIFY \
   238    240       SQLITE_ENABLE_UPDATE_DELETE_LIMIT \
   239    241     ]
   240    242   
   241    243     # Process any command line options.
   242    244     process_options $argv
   243    245   
   244         -  # First try a test with all OMIT symbols except SQLITE_OMIT_FLOATING_POINT 
   245         -  # and SQLITE_OMIT_PRAGMA defined. The former doesn't work (causes segfaults)
   246         -  # and the latter is currently incompatible with the test suite (this should
   247         -  # be fixed, but it will be a lot of work).
   248         -  set allsyms [list]
   249         -  foreach s $::OMIT_SYMBOLS {
   250         -    if {$s!="SQLITE_OMIT_FLOATING_POINT" && $s!="SQLITE_OMIT_PRAGMA"} {
   251         -      lappend allsyms $s
          246  +  if {[info exists ::SYMBOL] } {
          247  +    set sym $::SYMBOL
          248  +
          249  +    if {[lsearch $::OMIT_SYMBOLS $sym]<0 && [lsearch $::ENABLE_SYMBOLS $sym]<0} {
          250  +      puts stderr "No such symbol: $sym"
          251  +      exit -1
   252    252       }
   253         -  }
   254         -  run_quick_test test_OMIT_EVERYTHING $allsyms
   255    253   
   256         -  # Now try one quick.test with each of the OMIT symbols defined. Included
   257         -  # are the OMIT_FLOATING_POINT and OMIT_PRAGMA symbols, even though we
   258         -  # know they will fail. It's good to be reminded of this from time to time.
   259         -  foreach sym $::OMIT_SYMBOLS {
   260    254       set dirname "test_[string range $sym 7 end]"
   261    255       run_quick_test $dirname $sym
   262         -  }
   263         -
   264         -  # Try the ENABLE/DISABLE symbols one at a time.  
   265         -  # We don't do them all at once since some are conflicting.
   266         -  foreach sym $::ENABLE_SYMBOLS {
   267         -    set dirname "test_[string range $sym 7 end]"
   268         -    run_quick_test $dirname $sym
          256  +  } else {
          257  +    # First try a test with all OMIT symbols except SQLITE_OMIT_FLOATING_POINT 
          258  +    # and SQLITE_OMIT_PRAGMA defined. The former doesn't work (causes segfaults)
          259  +    # and the latter is currently incompatible with the test suite (this should
          260  +    # be fixed, but it will be a lot of work).
          261  +    set allsyms [list]
          262  +    foreach s $::OMIT_SYMBOLS {
          263  +      if {$s!="SQLITE_OMIT_FLOATING_POINT" && $s!="SQLITE_OMIT_PRAGMA"} {
          264  +        lappend allsyms $s
          265  +      }
          266  +    }
          267  +    run_quick_test test_OMIT_EVERYTHING $allsyms
          268  +  
          269  +    # Now try one quick.test with each of the OMIT symbols defined. Included
          270  +    # are the OMIT_FLOATING_POINT and OMIT_PRAGMA symbols, even though we
          271  +    # know they will fail. It's good to be reminded of this from time to time.
          272  +    foreach sym $::OMIT_SYMBOLS {
          273  +      set dirname "test_[string range $sym 7 end]"
          274  +      run_quick_test $dirname $sym
          275  +    }
          276  +  
          277  +    # Try the ENABLE/DISABLE symbols one at a time.  
          278  +    # We don't do them all at once since some are conflicting.
          279  +    foreach sym $::ENABLE_SYMBOLS {
          280  +      set dirname "test_[string range $sym 7 end]"
          281  +      run_quick_test $dirname $sym
          282  +    }
   269    283     }
   270    284   }
   271    285   
   272    286   main $argv