/ Check-in [4e5f17d1]
Login

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

Overview
Comment:Merge the latest trunk enhancements and fixes into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 4e5f17d189eb0578a544c21fc150f9e2ee3428e3
User & Date: drh 2015-04-23 13:49:53
Context
2015-04-23
14:40
Fix a performance problem in sqlite3session_diff(). check-in: ea400eca user: dan tags: sessions
13:49
Merge the latest trunk enhancements and fixes into the sessions branch. check-in: 4e5f17d1 user: drh tags: sessions
13:37
Fix a faulty assert() in the "AS" alias resolution logic of the parser. check-in: b5e43602 user: drh tags: trunk
2015-04-20
01:32
Merge all recent trunk enhancements and fixes into the sessions branch. check-in: b8ef1cde user: drh tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.msc.

   110    110   # Set this non-0 to compile binaries suitable for the WinRT environment.
   111    111   # This setting does not apply to any binaries that require Tcl to operate
   112    112   # properly (i.e. the text fixture, etc).
   113    113   #
   114    114   !IFNDEF FOR_WINRT
   115    115   FOR_WINRT = 0
   116    116   !ENDIF
          117  +
          118  +# Set this non-0 to compile binaries suitable for the UAP environment.
          119  +# This setting does not apply to any binaries that require Tcl to operate
          120  +# properly (i.e. the text fixture, etc).
          121  +#
          122  +!IFNDEF FOR_UAP
          123  +FOR_UAP = 0
          124  +!ENDIF
   117    125   
   118    126   # Set this non-0 to skip attempting to look for and/or link with the Tcl
   119    127   # runtime library.
   120    128   #
   121    129   !IFNDEF NO_TCL
   122    130   NO_TCL = 0
   123    131   !ENDIF
................................................................................
   284    292   
   285    293   # Check if the native library paths should be used when compiling
   286    294   # the command line tools used during the compilation process.  If
   287    295   # so, set the necessary macro now.
   288    296   #
   289    297   !IF $(USE_NATIVE_LIBPATHS)!=0
   290    298   NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
          299  +
          300  +!IFDEF NUCRTLIBPATH
          301  +NUCRTLIBPATH = $(NUCRTLIBPATH:\\=\)
          302  +NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
          303  +!ENDIF
   291    304   !ENDIF
   292    305   
   293    306   # C compiler and options for use in building executables that
   294    307   # will run on the target platform.  (BCC and TCC are usually the
   295    308   # same unless your are cross-compiling.)
   296    309   #
   297    310   !IF $(USE_FULLWARN)!=0
................................................................................
   714    727   
   715    728   # When compiling for use in the WinRT environment, the following
   716    729   # linker option must be used to mark the executable as runnable
   717    730   # only in the context of an application container.
   718    731   #
   719    732   !IF $(FOR_WINRT)!=0
   720    733   LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
   721         -!IF "$(VISUALSTUDIOVERSION)"=="12.0"
          734  +!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
   722    735   !IFNDEF STORELIBPATH
   723    736   !IF "$(PLATFORM)"=="x86"
   724    737   STORELIBPATH = $(CRTLIBPATH)\store
   725    738   !ELSEIF "$(PLATFORM)"=="x64"
   726    739   STORELIBPATH = $(CRTLIBPATH)\store\amd64
   727    740   !ELSEIF "$(PLATFORM)"=="ARM"
   728    741   STORELIBPATH = $(CRTLIBPATH)\store\arm
................................................................................
   757    770   !IFDEF WP81LIBPATH
   758    771   LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
   759    772   !ENDIF
   760    773   LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
   761    774   LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
   762    775   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
   763    776   !ENDIF
          777  +
          778  +# When compiling for UAP, some extra linker options are also required.
          779  +#
          780  +!IF $(FOR_UAP)!=0
          781  +LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
          782  +LTLINKOPTS = $(LTLINKOPTS) mincore.lib
          783  +!IFDEF PSDKLIBPATH
          784  +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
          785  +!ENDIF
          786  +!ENDIF
   764    787   
   765    788   # If either debugging or symbols are enabled, enable PDBs.
   766    789   #
   767    790   !IF $(DEBUG)>1 || $(SYMBOLS)!=0
   768    791   LDFLAGS = /DEBUG
   769    792   !ENDIF
   770    793   

Changes to ext/fts3/fts3.c.

  2806   2806     ** for the pending-terms. If this is a scan, then this call must be being
  2807   2807     ** made by an fts4aux module, not an FTS table. In this case calling
  2808   2808     ** Fts3SegReaderPending might segfault, as the data structures used by 
  2809   2809     ** fts4aux are not completely populated. So it's easiest to filter these
  2810   2810     ** calls out here.  */
  2811   2811     if( iLevel<0 && p->aIndex ){
  2812   2812       Fts3SegReader *pSeg = 0;
  2813         -    rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
         2813  +    rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
  2814   2814       if( rc==SQLITE_OK && pSeg ){
  2815   2815         rc = fts3SegReaderCursorAppend(pCsr, pSeg);
  2816   2816       }
  2817   2817     }
  2818   2818   
  2819   2819     if( iLevel!=FTS3_SEGCURSOR_PENDING ){
  2820   2820       if( rc==SQLITE_OK ){
................................................................................
  4613   4613   static void fts3EvalStartReaders(
  4614   4614     Fts3Cursor *pCsr,               /* FTS Cursor handle */
  4615   4615     Fts3Expr *pExpr,                /* Expression to initialize phrases in */
  4616   4616     int *pRc                        /* IN/OUT: Error code */
  4617   4617   ){
  4618   4618     if( pExpr && SQLITE_OK==*pRc ){
  4619   4619       if( pExpr->eType==FTSQUERY_PHRASE ){
  4620         -      int i;
  4621   4620         int nToken = pExpr->pPhrase->nToken;
  4622         -      for(i=0; i<nToken; i++){
  4623         -        if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
         4621  +      if( nToken ){
         4622  +        int i;
         4623  +        for(i=0; i<nToken; i++){
         4624  +          if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
         4625  +        }
         4626  +        pExpr->bDeferred = (i==nToken);
  4624   4627         }
  4625         -      pExpr->bDeferred = (i==nToken);
  4626   4628         *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
  4627   4629       }else{
  4628   4630         fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
  4629   4631         fts3EvalStartReaders(pCsr, pExpr->pRight, pRc);
  4630   4632         pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred);
  4631   4633       }
  4632   4634     }

Changes to ext/fts3/fts3_tokenizer.c.

   275    275     nInput = sqlite3_value_bytes(argv[argc-1]);
   276    276     zInput = (const char *)sqlite3_value_text(argv[argc-1]);
   277    277   
   278    278     pHash = (Fts3Hash *)sqlite3_user_data(context);
   279    279     p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
   280    280   
   281    281     if( !p ){
   282         -    char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
   283         -    sqlite3_result_error(context, zErr, -1);
   284         -    sqlite3_free(zErr);
          282  +    char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
          283  +    sqlite3_result_error(context, zErr2, -1);
          284  +    sqlite3_free(zErr2);
   285    285       return;
   286    286     }
   287    287   
   288    288     pRet = Tcl_NewObj();
   289    289     Tcl_IncrRefCount(pRet);
   290    290   
   291    291     for(i=1; i<argc-1; i++){

Changes to ext/fts3/fts3_write.c.

   322    322   /* 21 */  "SELECT size FROM %Q.'%q_docsize' WHERE docid=?",
   323    323   /* 22 */  "SELECT value FROM %Q.'%q_stat' WHERE id=?",
   324    324   /* 23 */  "REPLACE INTO %Q.'%q_stat' VALUES(?,?)",
   325    325   /* 24 */  "",
   326    326   /* 25 */  "",
   327    327   
   328    328   /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
   329         -/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
          329  +/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'",
   330    330   
   331    331   /* This statement is used to determine which level to read the input from
   332    332   ** when performing an incremental merge. It returns the absolute level number
   333    333   ** of the oldest level in the db that contains at least ? segments. Or,
   334    334   ** if no level in the FTS index contains more than ? segments, the statement
   335    335   ** returns zero rows.  */
   336    336   /* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?"
................................................................................
  3440   3440     int bSeenDone = 0;
  3441   3441     int rc;
  3442   3442     sqlite3_stmt *pAllLangid = 0;
  3443   3443   
  3444   3444     rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  3445   3445     if( rc==SQLITE_OK ){
  3446   3446       int rc2;
  3447         -    sqlite3_bind_int(pAllLangid, 1, p->nIndex);
         3447  +    sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
         3448  +    sqlite3_bind_int(pAllLangid, 2, p->nIndex);
  3448   3449       while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
  3449   3450         int i;
  3450   3451         int iLangid = sqlite3_column_int(pAllLangid, 0);
  3451   3452         for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
  3452   3453           rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL);
  3453   3454           if( rc==SQLITE_DONE ){
  3454   3455             bSeenDone = 1;
................................................................................
  4772   4773     i = pHint->n-2;
  4773   4774     while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
  4774   4775     while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
  4775   4776   
  4776   4777     pHint->n = i;
  4777   4778     i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
  4778   4779     i += fts3GetVarint32(&pHint->a[i], pnInput);
  4779         -  if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
         4780  +  if( i!=nHint ) return FTS_CORRUPT_VTAB;
  4780   4781   
  4781   4782     return SQLITE_OK;
  4782   4783   }
  4783   4784   
  4784   4785   
  4785   4786   /*
  4786   4787   ** Attempt an incremental merge that writes nMerge leaf blocks.
................................................................................
  5140   5141     u64 cksum2 = 0;                 /* Checksum based on %_content contents */
  5141   5142     sqlite3_stmt *pAllLangid = 0;   /* Statement to return all language-ids */
  5142   5143   
  5143   5144     /* This block calculates the checksum according to the FTS index. */
  5144   5145     rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  5145   5146     if( rc==SQLITE_OK ){
  5146   5147       int rc2;
  5147         -    sqlite3_bind_int(pAllLangid, 1, p->nIndex);
         5148  +    sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
         5149  +    sqlite3_bind_int(pAllLangid, 2, p->nIndex);
  5148   5150       while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
  5149   5151         int iLangid = sqlite3_column_int(pAllLangid, 0);
  5150   5152         int i;
  5151   5153         for(i=0; i<p->nIndex; i++){
  5152   5154           cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc);
  5153   5155         }
  5154   5156       }
  5155   5157       rc2 = sqlite3_reset(pAllLangid);
  5156   5158       if( rc==SQLITE_OK ) rc = rc2;
  5157   5159     }
  5158   5160   
  5159   5161     /* This block calculates the checksum according to the %_content table */
  5160         -  rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
  5161   5162     if( rc==SQLITE_OK ){
  5162   5163       sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
  5163   5164       sqlite3_stmt *pStmt = 0;
  5164   5165       char *zSql;
  5165   5166      
  5166   5167       zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
  5167   5168       if( !zSql ){
................................................................................
  5250   5251   */
  5251   5252   static int fts3DoIntegrityCheck(
  5252   5253     Fts3Table *p                    /* FTS3 table handle */
  5253   5254   ){
  5254   5255     int rc;
  5255   5256     int bOk = 0;
  5256   5257     rc = fts3IntegrityCheck(p, &bOk);
  5257         -  if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
         5258  +  if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
  5258   5259     return rc;
  5259   5260   }
  5260   5261   
  5261   5262   /*
  5262   5263   ** Handle a 'special' INSERT of the form:
  5263   5264   **
  5264   5265   **   "INSERT INTO tbl(tbl) VALUES(<expr>)"

Changes to ext/misc/fuzzer.c.

   872    872     fuzzer_rule *pRule;
   873    873     unsigned int h;
   874    874   
   875    875     pNew = sqlite3_malloc( sizeof(*pNew) + (int)strlen(zWord) + 1 );
   876    876     if( pNew==0 ) return 0;
   877    877     memset(pNew, 0, sizeof(*pNew));
   878    878     pNew->zBasis = (char*)&pNew[1];
   879         -  pNew->nBasis = (int)strlen(zWord);
          879  +  pNew->nBasis = (fuzzer_len)strlen(zWord);
   880    880     memcpy(pNew->zBasis, zWord, pNew->nBasis+1);
   881    881     pRule = pCur->pVtab->pRule;
   882    882     while( fuzzerSkipRule(pRule, pNew, pCur->iRuleset) ){
   883    883       pRule = pRule->pNext;
   884    884     }
   885    885     pNew->pRule = pRule;
   886    886     pNew->n = -1;

Changes to src/analyze.c.

  1515   1515       pIndex = sqlite3PrimaryKeyIndex(pTable);
  1516   1516     }else{
  1517   1517       pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  1518   1518     }
  1519   1519     z = argv[2];
  1520   1520   
  1521   1521     if( pIndex ){
         1522  +    tRowcnt *aiRowEst = 0;
  1522   1523       int nCol = pIndex->nKeyCol+1;
  1523   1524   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  1524         -    tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
  1525         -        sizeof(tRowcnt) * nCol
  1526         -    );
  1527         -    if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
  1528         -#else
  1529         -    tRowcnt * const aiRowEst = 0;
         1525  +    /* Index.aiRowEst may already be set here if there are duplicate 
         1526  +    ** sqlite_stat1 entries for this index. In that case just clobber
         1527  +    ** the old data with the new instead of allocating a new array.  */
         1528  +    if( pIndex->aiRowEst==0 ){
         1529  +      pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
         1530  +      if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
         1531  +    }
         1532  +    aiRowEst = pIndex->aiRowEst;
  1530   1533   #endif
  1531   1534       pIndex->bUnordered = 0;
  1532   1535       decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
  1533   1536       if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
  1534   1537     }else{
  1535   1538       Index fakeIdx;
  1536   1539       fakeIdx.szIdxRow = pTable->szTabRow;

Changes to src/expr.c.

  3379   3379       }
  3380   3380       case TK_AS: {
  3381   3381         sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
  3382   3382         sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
  3383   3383         break;
  3384   3384       }
  3385   3385       case TK_ID: {
  3386         -      sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
         3386  +      sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
  3387   3387         break;
  3388   3388       }
  3389   3389   #ifndef SQLITE_OMIT_CAST
  3390   3390       case TK_CAST: {
  3391   3391         /* Expressions of the form:   CAST(pLeft AS token) */
  3392   3392         sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
  3393   3393         sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);

Changes to src/fkey.c.

  1193   1193   
  1194   1194         /* Create the expression "OLD.zToCol = zFromCol". It is important
  1195   1195         ** that the "OLD.zToCol" term is on the LHS of the = operator, so
  1196   1196         ** that the affinity and collation sequence associated with the
  1197   1197         ** parent table are used for the comparison. */
  1198   1198         pEq = sqlite3PExpr(pParse, TK_EQ,
  1199   1199             sqlite3PExpr(pParse, TK_DOT, 
  1200         -            sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
  1201         -            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
         1200  +            sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
         1201  +            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
  1202   1202             , 0),
  1203         -          sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
         1203  +          sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
  1204   1204         , 0);
  1205   1205         pWhere = sqlite3ExprAnd(db, pWhere, pEq);
  1206   1206   
  1207   1207         /* For ON UPDATE, construct the next term of the WHEN clause.
  1208   1208         ** The final WHEN clause will be like this:
  1209   1209         **
  1210   1210         **    WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
  1211   1211         */
  1212   1212         if( pChanges ){
  1213   1213           pEq = sqlite3PExpr(pParse, TK_IS,
  1214   1214               sqlite3PExpr(pParse, TK_DOT, 
  1215         -              sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
  1216         -              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
         1215  +              sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
         1216  +              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
  1217   1217                 0),
  1218   1218               sqlite3PExpr(pParse, TK_DOT, 
  1219         -              sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
  1220         -              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
         1219  +              sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
         1220  +              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
  1221   1221                 0),
  1222   1222               0);
  1223   1223           pWhen = sqlite3ExprAnd(db, pWhen, pEq);
  1224   1224         }
  1225   1225     
  1226   1226         if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
  1227   1227           Expr *pNew;
  1228   1228           if( action==OE_Cascade ){
  1229   1229             pNew = sqlite3PExpr(pParse, TK_DOT, 
  1230         -            sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
  1231         -            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
         1230  +            sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
         1231  +            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
  1232   1232             , 0);
  1233   1233           }else if( action==OE_SetDflt ){
  1234   1234             Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
  1235   1235             if( pDflt ){
  1236   1236               pNew = sqlite3ExprDup(db, pDflt, 0);
  1237   1237             }else{
  1238   1238               pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
................................................................................
  1271   1271       /* Disable lookaside memory allocation */
  1272   1272       enableLookaside = db->lookaside.bEnabled;
  1273   1273       db->lookaside.bEnabled = 0;
  1274   1274   
  1275   1275       pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
  1276   1276           sizeof(Trigger) +         /* struct Trigger */
  1277   1277           sizeof(TriggerStep) +     /* Single step in trigger program */
  1278         -        nFrom + 1                 /* Space for pStep->target.z */
         1278  +        nFrom + 1                 /* Space for pStep->zTarget */
  1279   1279       );
  1280   1280       if( pTrigger ){
  1281   1281         pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
  1282         -      pStep->target.z = (char *)&pStep[1];
  1283         -      pStep->target.n = nFrom;
  1284         -      memcpy((char *)pStep->target.z, zFrom, nFrom);
         1282  +      pStep->zTarget = (char *)&pStep[1];
         1283  +      memcpy((char *)pStep->zTarget, zFrom, nFrom);
  1285   1284     
  1286   1285         pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
  1287   1286         pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
  1288   1287         pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
  1289   1288         if( pWhen ){
  1290   1289           pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
  1291   1290           pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);

Changes to src/insert.c.

  2033   2033         ** should be inserted. This is faster.
  2034   2034         **
  2035   2035         ** If any of the indexed columns use a collation sequence other than
  2036   2036         ** BINARY, this optimization is disabled. This is because the user 
  2037   2037         ** might change the definition of a collation sequence and then run
  2038   2038         ** a VACUUM command. In that case keys may not be written in strictly
  2039   2039         ** sorted order.  */
  2040         -      int i;
  2041   2040         for(i=0; i<pSrcIdx->nColumn; i++){
  2042   2041           char *zColl = pSrcIdx->azColl[i];
  2043   2042           assert( zColl!=0 );
  2044   2043           if( sqlite3_stricmp("BINARY", zColl) ) break;
  2045   2044         }
  2046   2045         if( i==pSrcIdx->nColumn ){
  2047   2046           useSeekResult = OPFLAG_USESEEKRESULT;

Changes to src/pager.c.

  3040   3040     Pager *pPager,                  /* Pager object */
  3041   3041     PgHdr *pList,                   /* List of frames to log */
  3042   3042     Pgno nTruncate,                 /* Database size after this commit */
  3043   3043     int isCommit                    /* True if this is a commit */
  3044   3044   ){
  3045   3045     int rc;                         /* Return code */
  3046   3046     int nList;                      /* Number of pages in pList */
  3047         -#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
  3048   3047     PgHdr *p;                       /* For looping over pages */
  3049         -#endif
  3050   3048   
  3051   3049     assert( pPager->pWal );
  3052   3050     assert( pList );
  3053   3051   #ifdef SQLITE_DEBUG
  3054   3052     /* Verify that the page list is in accending order */
  3055   3053     for(p=pList; p && p->pDirty; p=p->pDirty){
  3056   3054       assert( p->pgno < p->pDirty->pgno );
................................................................................
  3059   3057   
  3060   3058     assert( pList->pDirty==0 || isCommit );
  3061   3059     if( isCommit ){
  3062   3060       /* If a WAL transaction is being committed, there is no point in writing
  3063   3061       ** any pages with page numbers greater than nTruncate into the WAL file.
  3064   3062       ** They will never be read by any client. So remove them from the pDirty
  3065   3063       ** list here. */
  3066         -    PgHdr *p;
  3067   3064       PgHdr **ppNext = &pList;
  3068   3065       nList = 0;
  3069   3066       for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
  3070   3067         if( p->pgno<=nTruncate ){
  3071   3068           ppNext = &p->pDirty;
  3072   3069           nList++;
  3073   3070         }
................................................................................
  3079   3076     pPager->aStat[PAGER_STAT_WRITE] += nList;
  3080   3077   
  3081   3078     if( pList->pgno==1 ) pager_write_changecounter(pList);
  3082   3079     rc = sqlite3WalFrames(pPager->pWal, 
  3083   3080         pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
  3084   3081     );
  3085   3082     if( rc==SQLITE_OK && pPager->pBackup ){
  3086         -    PgHdr *p;
  3087   3083       for(p=pList; p; p=p->pDirty){
  3088   3084         sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
  3089   3085       }
  3090   3086     }
  3091   3087   
  3092   3088   #ifdef SQLITE_CHECK_PAGES
  3093   3089     pList = sqlite3PcacheDirtyList(pPager->pPCache);

Changes to src/pragma.c.

   160    160   #endif /* SQLITE_PAGER_PRAGMAS */
   161    161   
   162    162   /*
   163    163   ** Generate code to return a single integer value.
   164    164   */
   165    165   static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
   166    166     Vdbe *v = sqlite3GetVdbe(pParse);
   167         -  int mem = ++pParse->nMem;
          167  +  int nMem = ++pParse->nMem;
   168    168     i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
   169    169     if( pI64 ){
   170    170       memcpy(pI64, &value, sizeof(value));
   171    171     }
   172         -  sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
          172  +  sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
   173    173     sqlite3VdbeSetNumCols(v, 1);
   174    174     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
   175         -  sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
          175  +  sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
   176    176   }
   177    177   
   178    178   
   179    179   /*
   180    180   ** Set the safety_level and pager flags for pager iDb.  Or if iDb<0
   181    181   ** set these values for all pagers.
   182    182   */
................................................................................
   333    333     aFcntl[1] = zLeft;
   334    334     aFcntl[2] = zRight;
   335    335     aFcntl[3] = 0;
   336    336     db->busyHandler.nBusy = 0;
   337    337     rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
   338    338     if( rc==SQLITE_OK ){
   339    339       if( aFcntl[0] ){
   340         -      int mem = ++pParse->nMem;
   341         -      sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
          340  +      int nMem = ++pParse->nMem;
          341  +      sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
   342    342         sqlite3VdbeSetNumCols(v, 1);
   343    343         sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
   344         -      sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
          344  +      sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
   345    345         sqlite3_free(aFcntl[0]);
   346    346       }
   347    347       goto pragma_out;
   348    348     }
   349    349     if( rc!=SQLITE_NOTFOUND ){
   350    350       if( aFcntl[0] ){
   351    351         sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);

Changes to src/resolve.c.

    75     75   **     SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
    76     76   **
    77     77   ** Should be transformed into:
    78     78   **
    79     79   **     SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
    80     80   **
    81     81   ** The nSubquery parameter specifies how many levels of subquery the
    82         -** alias is removed from the original expression.  The usually value is
           82  +** alias is removed from the original expression.  The usual value is
    83     83   ** zero but it might be more if the alias is contained within a subquery
    84     84   ** of the original expression.  The Expr.op2 field of TK_AGG_FUNCTION
    85     85   ** structures must be increased by the nSubquery amount.
    86     86   */
    87     87   static void resolveAlias(
    88     88     Parse *pParse,         /* Parsing context */
    89     89     ExprList *pEList,      /* A result set */
................................................................................
    95     95     Expr *pOrig;           /* The iCol-th column of the result set */
    96     96     Expr *pDup;            /* Copy of pOrig */
    97     97     sqlite3 *db;           /* The database connection */
    98     98   
    99     99     assert( iCol>=0 && iCol<pEList->nExpr );
   100    100     pOrig = pEList->a[iCol].pExpr;
   101    101     assert( pOrig!=0 );
   102         -  assert( pOrig->flags & EP_Resolved );
          102  +  assert( (pOrig->flags & EP_Resolved)!=0 || zType[0]==0 );
   103    103     db = pParse->db;
   104    104     pDup = sqlite3ExprDup(db, pOrig, 0);
   105    105     if( pDup==0 ) return;
   106    106     if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
   107    107       incrAggFunctionDepth(pDup, nSubquery);
   108    108       pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
   109    109       if( pDup==0 ) return;

Changes to src/select.c.

  1696   1696     assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
  1697   1697     if( db->mallocFailed ) return;
  1698   1698     memset(&sNC, 0, sizeof(sNC));
  1699   1699     sNC.pSrcList = pSelect->pSrc;
  1700   1700     a = pSelect->pEList->a;
  1701   1701     for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
  1702   1702       p = a[i].pExpr;
  1703         -    pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
         1703  +    if( pCol->zType==0 ){
         1704  +      pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
         1705  +    }
  1704   1706       szAll += pCol->szEst;
  1705   1707       pCol->affinity = sqlite3ExprAffinity(p);
  1706   1708       if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
  1707   1709       pColl = sqlite3ExprCollSeq(pParse, p);
  1708         -    if( pColl ){
         1710  +    if( pColl && pCol->zColl==0 ){
  1709   1711         pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
  1710   1712       }
  1711   1713     }
  1712   1714     pTab->szTabRow = sqlite3LogEst(szAll*4);
  1713   1715   }
  1714   1716   
  1715   1717   /*
................................................................................
  2638   2640       ** starting at pDest->iSdst.  Then the co-routine yields.
  2639   2641       */
  2640   2642       case SRT_Coroutine: {
  2641   2643         if( pDest->iSdst==0 ){
  2642   2644           pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
  2643   2645           pDest->nSdst = pIn->nSdst;
  2644   2646         }
  2645         -      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
         2647  +      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
  2646   2648         sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
  2647   2649         break;
  2648   2650       }
  2649   2651   
  2650   2652       /* If none of the above, then the result destination must be
  2651   2653       ** SRT_Output.  This routine is never called with any other
  2652   2654       ** destination other than the ones handled above or SRT_Output.
................................................................................
  4604   4606         sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP);
  4605   4607       }else{
  4606   4608         nArg = 0;
  4607   4609         regAgg = 0;
  4608   4610       }
  4609   4611       if( pF->iDistinct>=0 ){
  4610   4612         addrNext = sqlite3VdbeMakeLabel(v);
  4611         -      assert( nArg==1 );
         4613  +      testcase( nArg==0 );  /* Error condition */
         4614  +      testcase( nArg>1 );   /* Also an error */
  4612   4615         codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
  4613   4616       }
  4614   4617       if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
  4615   4618         CollSeq *pColl = 0;
  4616   4619         struct ExprList_item *pItem;
  4617   4620         int j;
  4618   4621         assert( pList!=0 );  /* pList!=0 if pF->pFunc has NEEDCOLL */
................................................................................
  5533   5536       pView = sqlite3TreeViewPush(pView, (n--)>0);
  5534   5537       sqlite3TreeViewLine(pView, "FROM");
  5535   5538       for(i=0; i<p->pSrc->nSrc; i++){
  5536   5539         struct SrcList_item *pItem = &p->pSrc->a[i];
  5537   5540         StrAccum x;
  5538   5541         char zLine[100];
  5539   5542         sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
         5543  +      x.useMalloc = 0;
  5540   5544         sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
  5541   5545         if( pItem->zDatabase ){
  5542   5546           sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
  5543   5547         }else if( pItem->zName ){
  5544   5548           sqlite3XPrintf(&x, 0, " %s", pItem->zName);
  5545   5549         }
  5546   5550         if( pItem->pTab ){

Changes to src/shell.c.

   332    332   static int stdin_is_interactive = 1;
   333    333   
   334    334   /*
   335    335   ** The following is the open SQLite database.  We make a pointer
   336    336   ** to this database a static variable so that it can be accessed
   337    337   ** by the SIGINT handler to interrupt database processing.
   338    338   */
   339         -static sqlite3 *db = 0;
          339  +static sqlite3 *globalDb = 0;
   340    340   
   341    341   /*
   342    342   ** True if an interrupt (Control-C) has been received.
   343    343   */
   344    344   static volatile int seenInterrupt = 0;
   345    345   
   346    346   /*
................................................................................
   818    818   /*
   819    819   ** This routine runs when the user presses Ctrl-C
   820    820   */
   821    821   static void interrupt_handler(int NotUsed){
   822    822     UNUSED_PARAMETER(NotUsed);
   823    823     seenInterrupt++;
   824    824     if( seenInterrupt>2 ) exit(1);
   825         -  if( db ) sqlite3_interrupt(db);
          825  +  if( globalDb ) sqlite3_interrupt(globalDb);
   826    826   }
   827    827   #endif
   828    828   
   829    829   /*
   830    830   ** This is the callback routine that the shell
   831    831   ** invokes for each row of a query result.
   832    832   */
................................................................................
  1994   1994   ** Make sure the database is open.  If it is not, then open it.  If
  1995   1995   ** the database fails to open, print an error message and exit.
  1996   1996   */
  1997   1997   static void open_db(ShellState *p, int keepAlive){
  1998   1998     if( p->db==0 ){
  1999   1999       sqlite3_initialize();
  2000   2000       sqlite3_open(p->zDbFilename, &p->db);
  2001         -    db = p->db;
  2002         -    if( db && sqlite3_errcode(db)==SQLITE_OK ){
  2003         -      sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
         2001  +    globalDb = p->db;
         2002  +    if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
         2003  +      sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
  2004   2004             shellstaticFunc, 0, 0);
  2005   2005       }
  2006         -    if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
         2006  +    if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
  2007   2007         fprintf(stderr,"Error: unable to open database \"%s\": %s\n", 
  2008         -          p->zDbFilename, sqlite3_errmsg(db));
         2008  +          p->zDbFilename, sqlite3_errmsg(p->db));
  2009   2009         if( keepAlive ) return;
  2010   2010         exit(1);
  2011   2011       }
  2012   2012   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  2013   2013       sqlite3_enable_load_extension(p->db, 1);
  2014   2014   #endif
  2015         -    sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
         2015  +    sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
  2016   2016                               readfileFunc, 0, 0);
  2017         -    sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
         2017  +    sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
  2018   2018                               writefileFunc, 0, 0);
  2019   2019     }
  2020   2020   }
  2021   2021   
  2022   2022   /*
  2023   2023   ** Do C-language style dequoting.
  2024   2024   **
................................................................................
  2671   2671   /*
  2672   2672   ** If an input line begins with "." then invoke this routine to
  2673   2673   ** process that line.
  2674   2674   **
  2675   2675   ** Return 1 on error, 2 to exit, and 0 otherwise.
  2676   2676   */
  2677   2677   static int do_meta_command(char *zLine, ShellState *p){
  2678         -  int i = 1;
         2678  +  int h = 1;
  2679   2679     int nArg = 0;
  2680   2680     int n, c;
  2681   2681     int rc = 0;
  2682   2682     char *azArg[50];
  2683   2683   
  2684   2684     /* Parse the input line into tokens.
  2685   2685     */
  2686         -  while( zLine[i] && nArg<ArraySize(azArg) ){
  2687         -    while( IsSpace(zLine[i]) ){ i++; }
  2688         -    if( zLine[i]==0 ) break;
  2689         -    if( zLine[i]=='\'' || zLine[i]=='"' ){
  2690         -      int delim = zLine[i++];
  2691         -      azArg[nArg++] = &zLine[i];
  2692         -      while( zLine[i] && zLine[i]!=delim ){ 
  2693         -        if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
  2694         -        i++; 
         2686  +  while( zLine[h] && nArg<ArraySize(azArg) ){
         2687  +    while( IsSpace(zLine[h]) ){ h++; }
         2688  +    if( zLine[h]==0 ) break;
         2689  +    if( zLine[h]=='\'' || zLine[h]=='"' ){
         2690  +      int delim = zLine[h++];
         2691  +      azArg[nArg++] = &zLine[h];
         2692  +      while( zLine[h] && zLine[h]!=delim ){ 
         2693  +        if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
         2694  +        h++; 
  2695   2695         }
  2696         -      if( zLine[i]==delim ){
  2697         -        zLine[i++] = 0;
         2696  +      if( zLine[h]==delim ){
         2697  +        zLine[h++] = 0;
  2698   2698         }
  2699   2699         if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
  2700   2700       }else{
  2701         -      azArg[nArg++] = &zLine[i];
  2702         -      while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
  2703         -      if( zLine[i] ) zLine[i++] = 0;
         2701  +      azArg[nArg++] = &zLine[h];
         2702  +      while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
         2703  +      if( zLine[h] ) zLine[h++] = 0;
  2704   2704         resolve_backslashes(azArg[nArg-1]);
  2705   2705       }
  2706   2706     }
  2707   2707   
  2708   2708     /* Process the input line.
  2709   2709     */
  2710   2710     if( nArg==0 ) return 0; /* no tokens, no error */
................................................................................
  3072   3072         fprintf(stderr, "Error: out of memory\n");
  3073   3073         xCloser(sCtx.in);
  3074   3074         return 1;
  3075   3075       }
  3076   3076       nByte = strlen30(zSql);
  3077   3077       rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  3078   3078       import_append_char(&sCtx, 0);    /* To ensure sCtx.z is allocated */
  3079         -    if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
         3079  +    if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
  3080   3080         char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
  3081   3081         char cSep = '(';
  3082   3082         while( xRead(&sCtx) ){
  3083   3083           zCreate = sqlite3_mprintf("%z%c\n  \"%s\" TEXT", zCreate, cSep, sCtx.z);
  3084   3084           cSep = ',';
  3085   3085           if( sCtx.cTerm!=sCtx.cColSep ) break;
  3086   3086         }
................................................................................
  3092   3092           return 1;
  3093   3093         }
  3094   3094         zCreate = sqlite3_mprintf("%z\n)", zCreate);
  3095   3095         rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
  3096   3096         sqlite3_free(zCreate);
  3097   3097         if( rc ){
  3098   3098           fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
  3099         -                sqlite3_errmsg(db));
         3099  +                sqlite3_errmsg(p->db));
  3100   3100           sqlite3_free(sCtx.z);
  3101   3101           xCloser(sCtx.in);
  3102   3102           return 1;
  3103   3103         }
  3104   3104         rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  3105   3105       }
  3106   3106       sqlite3_free(zSql);
  3107   3107       if( rc ){
  3108   3108         if (pStmt) sqlite3_finalize(pStmt);
  3109         -      fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
         3109  +      fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
  3110   3110         xCloser(sCtx.in);
  3111   3111         return 1;
  3112   3112       }
  3113   3113       nCol = sqlite3_column_count(pStmt);
  3114   3114       sqlite3_finalize(pStmt);
  3115   3115       pStmt = 0;
  3116   3116       if( nCol==0 ) return 0; /* no columns, no error */
................................................................................
  3127   3127         zSql[j++] = '?';
  3128   3128       }
  3129   3129       zSql[j++] = ')';
  3130   3130       zSql[j] = 0;
  3131   3131       rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  3132   3132       sqlite3_free(zSql);
  3133   3133       if( rc ){
  3134         -      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
         3134  +      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
  3135   3135         if (pStmt) sqlite3_finalize(pStmt);
  3136   3136         xCloser(sCtx.in);
  3137   3137         return 1;
  3138   3138       }
  3139         -    needCommit = sqlite3_get_autocommit(db);
  3140         -    if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
         3139  +    needCommit = sqlite3_get_autocommit(p->db);
         3140  +    if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
  3141   3141       do{
  3142   3142         int startLine = sCtx.nLine;
  3143   3143         for(i=0; i<nCol; i++){
  3144   3144           char *z = xRead(&sCtx);
  3145   3145           /*
  3146   3146           ** Did we reach end-of-file before finding any columns?
  3147   3147           ** If so, stop instead of NULL filling the remaining columns.
................................................................................
  3172   3172                           sCtx.zFile, startLine, nCol, i);
  3173   3173         }
  3174   3174         if( i>=nCol ){
  3175   3175           sqlite3_step(pStmt);
  3176   3176           rc = sqlite3_reset(pStmt);
  3177   3177           if( rc!=SQLITE_OK ){
  3178   3178             fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
  3179         -                  sqlite3_errmsg(db));
         3179  +                  sqlite3_errmsg(p->db));
  3180   3180           }
  3181   3181         }
  3182   3182       }while( sCtx.cTerm!=EOF );
  3183   3183   
  3184   3184       xCloser(sCtx.in);
  3185   3185       sqlite3_free(sCtx.z);
  3186   3186       sqlite3_finalize(pStmt);
  3187         -    if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
         3187  +    if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
  3188   3188     }else
  3189   3189   
  3190   3190     if( c=='i' && (strncmp(azArg[0], "indices", n)==0
  3191   3191                    || strncmp(azArg[0], "indexes", n)==0) ){
  3192   3192       ShellState data;
  3193   3193       char *zErrMsg = 0;
  3194   3194       open_db(p, 0);
................................................................................
  3926   3926         sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
  3927   3927       }else{
  3928   3928         sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
  3929   3929       }
  3930   3930       while( sqlite3_step(pStmt)==SQLITE_ROW ){
  3931   3931         if( nRow>=nAlloc ){
  3932   3932           char **azNew;
  3933         -        int n = nAlloc*2 + 10;
  3934         -        azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
         3933  +        int n2 = nAlloc*2 + 10;
         3934  +        azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n2);
  3935   3935           if( azNew==0 ){
  3936   3936             fprintf(stderr, "Error: out of memory\n");
  3937   3937             break;
  3938   3938           }
  3939         -        nAlloc = n;
         3939  +        nAlloc = n2;
  3940   3940           azResult = azNew;
  3941   3941         }
  3942   3942         azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
  3943   3943         if( azResult[nRow] ) nRow++;
  3944   3944       }
  3945   3945       sqlite3_finalize(pStmt);        
  3946   3946       if( nRow>0 ){
................................................................................
  3985   3985         { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
  3986   3986         { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },
  3987   3987         { "byteorder",             SQLITE_TESTCTRL_BYTEORDER              },
  3988   3988         { "never_corrupt",         SQLITE_TESTCTRL_NEVER_CORRUPT          },
  3989   3989         { "imposter",              SQLITE_TESTCTRL_IMPOSTER               },
  3990   3990       };
  3991   3991       int testctrl = -1;
  3992         -    int rc = 0;
  3993         -    int i, n;
         3992  +    int rc2 = 0;
         3993  +    int i, n2;
  3994   3994       open_db(p, 0);
  3995   3995   
  3996   3996       /* convert testctrl text option to value. allow any unique prefix
  3997   3997       ** of the option name, or a numerical value. */
  3998         -    n = strlen30(azArg[1]);
         3998  +    n2 = strlen30(azArg[1]);
  3999   3999       for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
  4000         -      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
         4000  +      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
  4001   4001           if( testctrl<0 ){
  4002   4002             testctrl = aCtrl[i].ctrlCode;
  4003   4003           }else{
  4004   4004             fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
  4005   4005             testctrl = -1;
  4006   4006             break;
  4007   4007           }
................................................................................
  4014   4014         switch(testctrl){
  4015   4015   
  4016   4016           /* sqlite3_test_control(int, db, int) */
  4017   4017           case SQLITE_TESTCTRL_OPTIMIZATIONS:
  4018   4018           case SQLITE_TESTCTRL_RESERVE:             
  4019   4019             if( nArg==3 ){
  4020   4020               int opt = (int)strtol(azArg[2], 0, 0);        
  4021         -            rc = sqlite3_test_control(testctrl, p->db, opt);
  4022         -            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
         4021  +            rc2 = sqlite3_test_control(testctrl, p->db, opt);
         4022  +            fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
  4023   4023             } else {
  4024   4024               fprintf(stderr,"Error: testctrl %s takes a single int option\n",
  4025   4025                       azArg[1]);
  4026   4026             }
  4027   4027             break;
  4028   4028   
  4029   4029           /* sqlite3_test_control(int) */
  4030   4030           case SQLITE_TESTCTRL_PRNG_SAVE:
  4031   4031           case SQLITE_TESTCTRL_PRNG_RESTORE:
  4032   4032           case SQLITE_TESTCTRL_PRNG_RESET:
  4033   4033           case SQLITE_TESTCTRL_BYTEORDER:
  4034   4034             if( nArg==2 ){
  4035         -            rc = sqlite3_test_control(testctrl);
  4036         -            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
         4035  +            rc2 = sqlite3_test_control(testctrl);
         4036  +            fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
  4037   4037             } else {
  4038   4038               fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
  4039   4039             }
  4040   4040             break;
  4041   4041   
  4042   4042           /* sqlite3_test_control(int, uint) */
  4043   4043           case SQLITE_TESTCTRL_PENDING_BYTE:        
  4044   4044             if( nArg==3 ){
  4045   4045               unsigned int opt = (unsigned int)integerValue(azArg[2]);
  4046         -            rc = sqlite3_test_control(testctrl, opt);
  4047         -            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
         4046  +            rc2 = sqlite3_test_control(testctrl, opt);
         4047  +            fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
  4048   4048             } else {
  4049   4049               fprintf(stderr,"Error: testctrl %s takes a single unsigned"
  4050   4050                              " int option\n", azArg[1]);
  4051   4051             }
  4052   4052             break;
  4053   4053             
  4054   4054           /* sqlite3_test_control(int, int) */
  4055   4055           case SQLITE_TESTCTRL_ASSERT:              
  4056   4056           case SQLITE_TESTCTRL_ALWAYS:      
  4057   4057           case SQLITE_TESTCTRL_NEVER_CORRUPT:        
  4058   4058             if( nArg==3 ){
  4059   4059               int opt = booleanValue(azArg[2]);        
  4060         -            rc = sqlite3_test_control(testctrl, opt);
  4061         -            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
         4060  +            rc2 = sqlite3_test_control(testctrl, opt);
         4061  +            fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
  4062   4062             } else {
  4063   4063               fprintf(stderr,"Error: testctrl %s takes a single int option\n",
  4064   4064                               azArg[1]);
  4065   4065             }
  4066   4066             break;
  4067   4067   
  4068   4068           /* sqlite3_test_control(int, char *) */
  4069   4069   #ifdef SQLITE_N_KEYWORD
  4070   4070           case SQLITE_TESTCTRL_ISKEYWORD:           
  4071   4071             if( nArg==3 ){
  4072   4072               const char *opt = azArg[2];        
  4073         -            rc = sqlite3_test_control(testctrl, opt);
  4074         -            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
         4073  +            rc2 = sqlite3_test_control(testctrl, opt);
         4074  +            fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
  4075   4075             } else {
  4076   4076               fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
  4077   4077                               azArg[1]);
  4078   4078             }
  4079   4079             break;
  4080   4080   #endif
  4081   4081   
  4082   4082           case SQLITE_TESTCTRL_IMPOSTER:
  4083   4083             if( nArg==5 ){
  4084         -            rc = sqlite3_test_control(testctrl, p->db, 
         4084  +            rc2 = sqlite3_test_control(testctrl, p->db, 
  4085   4085                             azArg[2],
  4086   4086                             integerValue(azArg[3]),
  4087   4087                             integerValue(azArg[4]));
  4088         -            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
         4088  +            fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
  4089   4089             }else{
  4090   4090               fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
  4091   4091             }
  4092   4092             break;
  4093   4093   
  4094   4094           case SQLITE_TESTCTRL_BITVEC_TEST:         
  4095   4095           case SQLITE_TESTCTRL_FAULT_INSTALL:       

Changes to src/sqliteInt.h.

  2784   2784    * "SELECT" statement. The meanings of the other members is determined by the 
  2785   2785    * value of "op" as follows:
  2786   2786    *
  2787   2787    * (op == TK_INSERT)
  2788   2788    * orconf    -> stores the ON CONFLICT algorithm
  2789   2789    * pSelect   -> If this is an INSERT INTO ... SELECT ... statement, then
  2790   2790    *              this stores a pointer to the SELECT statement. Otherwise NULL.
  2791         - * target    -> A token holding the quoted name of the table to insert into.
         2791  + * zTarget   -> Dequoted name of the table to insert into.
  2792   2792    * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
  2793   2793    *              this stores values to be inserted. Otherwise NULL.
  2794   2794    * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
  2795   2795    *              statement, then this stores the column-names to be
  2796   2796    *              inserted into.
  2797   2797    *
  2798   2798    * (op == TK_DELETE)
  2799         - * target    -> A token holding the quoted name of the table to delete from.
         2799  + * zTarget   -> Dequoted name of the table to delete from.
  2800   2800    * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
  2801   2801    *              Otherwise NULL.
  2802   2802    * 
  2803   2803    * (op == TK_UPDATE)
  2804         - * target    -> A token holding the quoted name of the table to update rows of.
         2804  + * zTarget   -> Dequoted name of the table to update.
  2805   2805    * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
  2806   2806    *              Otherwise NULL.
  2807   2807    * pExprList -> A list of the columns to update and the expressions to update
  2808   2808    *              them to. See sqlite3Update() documentation of "pChanges"
  2809   2809    *              argument.
  2810   2810    * 
  2811   2811    */
  2812   2812   struct TriggerStep {
  2813   2813     u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
  2814   2814     u8 orconf;           /* OE_Rollback etc. */
  2815   2815     Trigger *pTrig;      /* The trigger that this step is a part of */
  2816         -  Select *pSelect;     /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
  2817         -  Token target;        /* Target table for DELETE, UPDATE, INSERT */
         2816  +  Select *pSelect;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
         2817  +  char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
  2818   2818     Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
  2819   2819     ExprList *pExprList; /* SET clause for UPDATE. */
  2820   2820     IdList *pIdList;     /* Column names for INSERT */
  2821   2821     TriggerStep *pNext;  /* Next in the link-list */
  2822   2822     TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
  2823   2823   };
  2824   2824   

Changes to src/tclsqlite.c.

  1231   1231       const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
  1232   1232       if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
  1233   1233         Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
  1234   1234         if( pVar ){
  1235   1235           int n;
  1236   1236           u8 *data;
  1237   1237           const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
  1238         -        char c = zType[0];
         1238  +        c = zType[0];
  1239   1239           if( zVar[0]=='@' ||
  1240   1240              (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
  1241   1241             /* Load a BLOB type if the Tcl variable is a bytearray and
  1242   1242             ** it has no string representation or the host
  1243   1243             ** parameter name begins with "@". */
  1244   1244             data = Tcl_GetByteArrayFromObj(pVar, &n);
  1245   1245             sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
................................................................................
  2379   2379         dbEvalFinalize(&sEval);
  2380   2380         if( rc==TCL_BREAK ){
  2381   2381           Tcl_SetObjResult(interp, pRet);
  2382   2382           rc = TCL_OK;
  2383   2383         }
  2384   2384         Tcl_DecrRefCount(pRet);
  2385   2385       }else{
  2386         -      ClientData cd[2];
         2386  +      ClientData cd2[2];
  2387   2387         DbEvalContext *p;
  2388   2388         Tcl_Obj *pArray = 0;
  2389   2389         Tcl_Obj *pScript;
  2390   2390   
  2391   2391         if( objc==5 && *(char *)Tcl_GetString(objv[3]) ){
  2392   2392           pArray = objv[3];
  2393   2393         }
  2394   2394         pScript = objv[objc-1];
  2395   2395         Tcl_IncrRefCount(pScript);
  2396   2396         
  2397   2397         p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
  2398   2398         dbEvalInit(p, pDb, objv[2], pArray);
  2399   2399   
  2400         -      cd[0] = (void *)p;
  2401         -      cd[1] = (void *)pScript;
  2402         -      rc = DbEvalNextCmd(cd, interp, TCL_OK);
         2400  +      cd2[0] = (void *)p;
         2401  +      cd2[1] = (void *)pScript;
         2402  +      rc = DbEvalNextCmd(cd2, interp, TCL_OK);
  2403   2403       }
  2404   2404       break;
  2405   2405     }
  2406   2406   
  2407   2407     /*
  2408   2408     **     $db function NAME [-argcount N] [-deterministic] SCRIPT
  2409   2409     **

Changes to src/test_malloc.c.

   207    207       if( rc==SQLITE_OK ){
   208    208         rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
   209    209       }
   210    210       sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 
   211    211           faultsimBeginBenign, faultsimEndBenign
   212    212       );
   213    213     }else{
   214         -    sqlite3_mem_methods m;
          214  +    sqlite3_mem_methods m2;
   215    215       assert(memfault.m.xMalloc);
   216    216   
   217    217       /* One should be able to reset the default memory allocator by storing
   218    218       ** a zeroed allocator then calling GETMALLOC. */
   219         -    memset(&m, 0, sizeof(m));
   220         -    sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
   221         -    sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m);
   222         -    assert( memcmp(&m, &memfault.m, sizeof(m))==0 );
          219  +    memset(&m2, 0, sizeof(m2));
          220  +    sqlite3_config(SQLITE_CONFIG_MALLOC, &m2);
          221  +    sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m2);
          222  +    assert( memcmp(&m2, &memfault.m, sizeof(m2))==0 );
   223    223   
   224    224       rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
   225    225       sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
   226    226     }
   227    227   
   228    228     if( rc==SQLITE_OK ){
   229    229       memfault.isInstalled = 1;

Changes to src/test_multiplex.c.

   564    564       pGroup->flags = flags;
   565    565       rc = multiplexSubFilename(pGroup, 1);
   566    566       if( rc==SQLITE_OK ){
   567    567         pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags, 0);
   568    568         if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN;
   569    569       }
   570    570       if( rc==SQLITE_OK ){
   571         -      sqlite3_int64 sz;
          571  +      sqlite3_int64 sz64;
   572    572   
   573         -      rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
          573  +      rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz64);
   574    574         if( rc==SQLITE_OK && zName ){
   575    575           int bExists;
   576    576           if( flags & SQLITE_OPEN_MASTER_JOURNAL ){
   577    577             pGroup->bEnabled = 0;
   578    578           }else
   579         -        if( sz==0 ){
          579  +        if( sz64==0 ){
   580    580             if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
   581    581               /* If opening a main journal file and the first chunk is zero
   582    582               ** bytes in size, delete any subsequent chunks from the 
   583    583               ** file-system. */
   584    584               int iChunk = 1;
   585    585               do {
   586    586                 rc = pOrigVfs->xAccess(pOrigVfs, 
................................................................................
   603    603             ** larger than the chunk size, that means the chunk size is too small.
   604    604             ** But we have no way of determining the intended chunk size, so 
   605    605             ** just disable the multiplexor all togethre.
   606    606             */
   607    607             rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
   608    608                 SQLITE_ACCESS_EXISTS, &bExists);
   609    609             bExists = multiplexSubSize(pGroup, 1, &rc)>0;
   610         -          if( rc==SQLITE_OK && bExists  && sz==(sz&0xffff0000) && sz>0
   611         -              && sz!=pGroup->szChunk ){
   612         -            pGroup->szChunk = (int)sz;
   613         -          }else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){
          610  +          if( rc==SQLITE_OK && bExists && sz64==(sz64&0xffff0000) && sz64>0
          611  +              && sz64!=pGroup->szChunk ){
          612  +            pGroup->szChunk = (int)sz64;
          613  +          }else if( rc==SQLITE_OK && !bExists && sz64>pGroup->szChunk ){
   614    614               pGroup->bEnabled = 0;
   615    615             }
   616    616           }
   617    617         }
   618    618       }
   619    619   
   620    620       if( rc==SQLITE_OK ){

Changes to src/test_onefile.c.

   591    591     fs_file *p = (fs_file *)pFile;
   592    592     fs_real_file *pReal = 0;
   593    593     int eType;
   594    594     int nName;
   595    595     int rc = SQLITE_OK;
   596    596   
   597    597     if( 0==(flags&(SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_MAIN_JOURNAL)) ){
   598         -    tmp_file *p = (tmp_file *)pFile;
   599         -    memset(p, 0, sizeof(*p));
   600         -    p->base.pMethods = &tmp_io_methods;
          598  +    tmp_file *p2 = (tmp_file *)pFile;
          599  +    memset(p2, 0, sizeof(*p2));
          600  +    p2->base.pMethods = &tmp_io_methods;
   601    601       return SQLITE_OK;
   602    602     }
   603    603   
   604    604     eType = ((flags&(SQLITE_OPEN_MAIN_DB))?DATABASE_FILE:JOURNAL_FILE);
   605    605     p->base.pMethods = &fs_io_methods;
   606    606     p->eType = eType;
   607    607   

Changes to src/test_osinst.c.

  1127   1127     }
  1128   1128     if( Tcl_GetIndexFromObj(interp, objv[1], strs, "sub-command", 0, &iSub) ){
  1129   1129       return TCL_ERROR;
  1130   1130     }
  1131   1131   
  1132   1132     switch( (enum VL_enum)iSub ){
  1133   1133       case VL_ANNOTATE: {
  1134         -      int rc;
  1135   1134         char *zVfs;
  1136   1135         char *zMsg;
  1137   1136         if( objc!=4 ){
  1138   1137           Tcl_WrongNumArgs(interp, 3, objv, "VFS");
  1139   1138           return TCL_ERROR;
  1140   1139         }
  1141   1140         zVfs = Tcl_GetString(objv[2]);
................................................................................
  1144   1143         if( rc!=SQLITE_OK ){
  1145   1144           Tcl_AppendResult(interp, "failed", 0);
  1146   1145           return TCL_ERROR;
  1147   1146         }
  1148   1147         break;
  1149   1148       }
  1150   1149       case VL_FINALIZE: {
  1151         -      int rc;
  1152   1150         char *zVfs;
  1153   1151         if( objc!=3 ){
  1154   1152           Tcl_WrongNumArgs(interp, 2, objv, "VFS");
  1155   1153           return TCL_ERROR;
  1156   1154         }
  1157   1155         zVfs = Tcl_GetString(objv[2]);
  1158   1156         rc = sqlite3_vfslog_finalize(zVfs);
................................................................................
  1160   1158           Tcl_AppendResult(interp, "failed", 0);
  1161   1159           return TCL_ERROR;
  1162   1160         }
  1163   1161         break;
  1164   1162       };
  1165   1163   
  1166   1164       case VL_NEW: {
  1167         -      int rc;
  1168   1165         char *zVfs;
  1169   1166         char *zParent;
  1170   1167         char *zLog;
  1171   1168         if( objc!=5 ){
  1172   1169           Tcl_WrongNumArgs(interp, 2, objv, "VFS PARENT LOGFILE");
  1173   1170           return TCL_ERROR;
  1174   1171         }

Changes to src/test_vfs.c.

  1076   1076       return TCL_ERROR;
  1077   1077     }
  1078   1078     Tcl_ResetResult(interp);
  1079   1079   
  1080   1080     switch( aSubcmd[i].eCmd ){
  1081   1081       case CMD_SHM: {
  1082   1082         Tcl_Obj *pObj;
  1083         -      int i, rc;
         1083  +      int rc;
  1084   1084         TestvfsBuffer *pBuffer;
  1085   1085         char *zName;
  1086   1086         if( objc!=3 && objc!=4 ){
  1087   1087           Tcl_WrongNumArgs(interp, 2, objv, "FILE ?VALUE?");
  1088   1088           return TCL_ERROR;
  1089   1089         }
  1090   1090         zName = ckalloc(p->pParent->mxPathname);
................................................................................
  1156   1156           { "xFullPathname",      TESTVFS_FULLPATHNAME_MASK },
  1157   1157           { "xUnlock",            TESTVFS_UNLOCK_MASK },
  1158   1158           { "xLock",              TESTVFS_LOCK_MASK },
  1159   1159           { "xCheckReservedLock", TESTVFS_CKLOCK_MASK },
  1160   1160         };
  1161   1161         Tcl_Obj **apElem = 0;
  1162   1162         int nElem = 0;
  1163         -      int i;
  1164   1163         int mask = 0;
  1165   1164         if( objc!=3 ){
  1166   1165           Tcl_WrongNumArgs(interp, 2, objv, "LIST");
  1167   1166           return TCL_ERROR;
  1168   1167         }
  1169   1168         if( Tcl_ListObjGetElements(interp, objv[2], &nElem, &apElem) ){
  1170   1169           return TCL_ERROR;

Changes to src/trigger.c.

   368    368   static TriggerStep *triggerStepAllocate(
   369    369     sqlite3 *db,                /* Database connection */
   370    370     u8 op,                      /* Trigger opcode */
   371    371     Token *pName                /* The target name */
   372    372   ){
   373    373     TriggerStep *pTriggerStep;
   374    374   
   375         -  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
          375  +  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
   376    376     if( pTriggerStep ){
   377    377       char *z = (char*)&pTriggerStep[1];
   378    378       memcpy(z, pName->z, pName->n);
   379         -    pTriggerStep->target.z = z;
   380         -    pTriggerStep->target.n = pName->n;
          379  +    sqlite3Dequote(z);
          380  +    pTriggerStep->zTarget = z;
   381    381       pTriggerStep->op = op;
   382    382     }
   383    383     return pTriggerStep;
   384    384   }
   385    385   
   386    386   /*
   387    387   ** Build a trigger step out of an INSERT statement.  Return a pointer
................................................................................
   656    656     if( pMask ){
   657    657       *pMask = mask;
   658    658     }
   659    659     return (mask ? pList : 0);
   660    660   }
   661    661   
   662    662   /*
   663         -** Convert the pStep->target token into a SrcList and return a pointer
          663  +** Convert the pStep->zTarget string into a SrcList and return a pointer
   664    664   ** to that SrcList.
   665    665   **
   666    666   ** This routine adds a specific database name, if needed, to the target when
   667    667   ** forming the SrcList.  This prevents a trigger in one database from
   668    668   ** referring to a target in another database.  An exception is when the
   669    669   ** trigger is in TEMP in which case it can refer to any other database it
   670    670   ** wants.
   671    671   */
   672    672   static SrcList *targetSrcList(
   673    673     Parse *pParse,       /* The parsing context */
   674    674     TriggerStep *pStep   /* The trigger containing the target token */
   675    675   ){
          676  +  sqlite3 *db = pParse->db;
   676    677     int iDb;             /* Index of the database to use */
   677    678     SrcList *pSrc;       /* SrcList to be returned */
   678    679   
   679         -  pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
          680  +  pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
   680    681     if( pSrc ){
   681    682       assert( pSrc->nSrc>0 );
   682         -    iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
          683  +    pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
          684  +    iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
   683    685       if( iDb==0 || iDb>=2 ){
   684         -      sqlite3 *db = pParse->db;
   685         -      assert( iDb<pParse->db->nDb );
          686  +      assert( iDb<db->nDb );
   686    687         pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
   687    688       }
   688    689     }
   689    690     return pSrc;
   690    691   }
   691    692   
   692    693   /*

Changes to src/vdbemem.c.

  1642   1642   void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
  1643   1643     if( pRec ){
  1644   1644       int i;
  1645   1645       int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
  1646   1646       Mem *aMem = pRec->aMem;
  1647   1647       sqlite3 *db = aMem[0].db;
  1648   1648       for(i=0; i<nCol; i++){
  1649         -      if( aMem[i].szMalloc ) sqlite3DbFree(db, aMem[i].zMalloc);
         1649  +      sqlite3VdbeMemRelease(&aMem[i]);
  1650   1650       }
  1651   1651       sqlite3KeyInfoUnref(pRec->pKeyInfo);
  1652   1652       sqlite3DbFree(db, pRec);
  1653   1653     }
  1654   1654   }
  1655   1655   #endif /* ifdef SQLITE_ENABLE_STAT4 */
  1656   1656   

Changes to src/where.c.

   251    251   ** does is make slot[] entries point to substructure within pExpr.
   252    252   **
   253    253   ** In the previous sentence and in the diagram, "slot[]" refers to
   254    254   ** the WhereClause.a[] array.  The slot[] array grows as needed to contain
   255    255   ** all terms of the WHERE clause.
   256    256   */
   257    257   static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
          258  +  Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
   258    259     pWC->op = op;
   259         -  if( pExpr==0 ) return;
   260         -  if( pExpr->op!=op ){
          260  +  if( pE2==0 ) return;
          261  +  if( pE2->op!=op ){
   261    262       whereClauseInsert(pWC, pExpr, 0);
   262    263     }else{
   263         -    whereSplit(pWC, pExpr->pLeft, op);
   264         -    whereSplit(pWC, pExpr->pRight, op);
          264  +    whereSplit(pWC, pE2->pLeft, op);
          265  +    whereSplit(pWC, pE2->pRight, op);
   265    266     }
   266    267   }
   267    268   
   268    269   /*
   269    270   ** Initialize a WhereMaskSet object
   270    271   */
   271    272   #define initMaskSet(P)  (P)->n=0
................................................................................
  6642   6643        pWInfo->revMask = (Bitmask)(-1);
  6643   6644     }
  6644   6645     if( pParse->nErr || NEVER(db->mallocFailed) ){
  6645   6646       goto whereBeginError;
  6646   6647     }
  6647   6648   #ifdef WHERETRACE_ENABLED /* !=0 */
  6648   6649     if( sqlite3WhereTrace ){
  6649         -    int ii;
  6650   6650       sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
  6651   6651       if( pWInfo->nOBSat>0 ){
  6652   6652         sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
  6653   6653       }
  6654   6654       switch( pWInfo->eDistinct ){
  6655   6655         case WHERE_DISTINCT_UNIQUE: {
  6656   6656           sqlite3DebugPrintf("  DISTINCT=unique");

Changes to test/analyze3.test.

    12     12   # This file implements regression tests for SQLite library. This file 
    13     13   # implements tests for range and LIKE constraints that use bound variables
    14     14   # instead of literal constant arguments.
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
           19  +set testprefix analyze3
    19     20   
    20     21   ifcapable !stat4&&!stat3 {
    21     22     finish_test
    22     23     return
    23     24   }
    24     25   
    25     26   #----------------------------------------------------------------------
................................................................................
    41     42   #               within sqlite3Reprepare() are handled correctly.
    42     43   #
    43     44   # analyze3-5.*: Check that the query plans of applicable statements are
    44     45   #               invalidated if the values of SQL parameter are modified
    45     46   #               using the clear_bindings() or transfer_bindings() APIs.
    46     47   # 
    47     48   # analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
           49  +#
           50  +# analyze3-7.*: Test that some memory leaks discovered by fuzz testing 
           51  +#               have been fixed.
    48     52   #
    49     53   
    50     54   proc getvar {varname} { uplevel #0 set $varname }
    51     55   db function var getvar
    52     56   
    53     57   proc eqp {sql {db db}} {
    54     58     uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
................................................................................
   657    661   do_eqp_test analyze3-6-3 {
   658    662     SELECT * FROM t1 WHERE a = 5 AND c = 13;
   659    663   } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
   660    664   
   661    665   do_eqp_test analyze3-6-2 {
   662    666     SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
   663    667   } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
          668  +
          669  +#-----------------------------------------------------------------------------
          670  +# 2015-04-20.
          671  +# Memory leak in sqlite3Stat4ProbeFree().  (Discovered while fuzzing.)
          672  +#
          673  +do_execsql_test analyze-7.1 {
          674  +  DROP TABLE IF EXISTS t1;
          675  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          676  +  INSERT INTO t1 VALUES(1,1,'0000');
          677  +  CREATE INDEX t0b ON t1(b);
          678  +  ANALYZE;
          679  +  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
          680  +} {}
          681  +
          682  +# At one point duplicate stat1 entries were causing a memory leak.
          683  +#
          684  +reset_db
          685  +do_execsql_test 7.2 {
          686  +  CREATE TABLE t1(a,b,c);
          687  +  CREATE INDEX t1a ON t1(a);
          688  +  ANALYZE;
          689  +  SELECT * FROM sqlite_stat1;
          690  +  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
          691  +  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
          692  +  ANALYZE sqlite_master;
          693  +}
   664    694   
   665    695   finish_test

Changes to test/count.test.

   187    187   
   188    188   do_execsql_test count-5.1 {
   189    189     CREATE TABLE t5(a TEXT PRIMARY KEY, b VARCHAR(50)) WITHOUT ROWID;
   190    190     INSERT INTO t5 VALUES('bison','jazz');
   191    191     SELECT count(*) FROM t5;
   192    192   } {1}
   193    193   
          194  +do_catchsql_test count-6.1 {
          195  +  CREATE TABLE t6(x);
          196  +  SELECT count(DISTINCT) FROM t6 GROUP BY x;
          197  +} {1 {DISTINCT aggregates must have exactly one argument}}
          198  +
   194    199   finish_test

Changes to test/fkey1.test.

   116    116   } [concat                        \
   117    117     {0 0 t5 d {} {SET DEFAULT} CASCADE NONE} \
   118    118     {0 1 t5 e {} {SET DEFAULT} CASCADE NONE} \
   119    119   ]
   120    120   do_test fkey1-3.5 {
   121    121     sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
   122    122   } {0 0 0}
          123  +
          124  +# Stress the dequoting logic.  The first test is not so bad.
          125  +do_execsql_test fkey1-4.0 {
          126  +  PRAGMA foreign_keys=ON;
          127  +  CREATE TABLE "xx1"("xx2" TEXT PRIMARY KEY, "xx3" TEXT);
          128  +  INSERT INTO "xx1"("xx2","xx3") VALUES('abc','def');
          129  +  CREATE TABLE "xx4"("xx5" TEXT REFERENCES "xx1" ON DELETE CASCADE);
          130  +  INSERT INTO "xx4"("xx5") VALUES('abc');
          131  +  INSERT INTO "xx1"("xx2","xx3") VALUES('uvw','xyz');
          132  +  SELECT 1, "xx5" FROM "xx4";
          133  +  DELETE FROM "xx1";
          134  +  SELECT 2, "xx5" FROM "xx4";
          135  +} {1 abc}
          136  +
          137  +# This case is identical to the previous except the "xx" in each name
          138  +# is changed to a single escaped double-quote character.
          139  +do_execsql_test fkey1-4.1 {
          140  +  PRAGMA foreign_keys=ON;
          141  +  CREATE TABLE """1"("""2" TEXT PRIMARY KEY, """3" TEXT);
          142  +  INSERT INTO """1"("""2","""3") VALUES('abc','def');
          143  +  CREATE TABLE """4"("""5" TEXT REFERENCES """1" ON DELETE CASCADE);
          144  +  INSERT INTO """4"("""5") VALUES('abc');
          145  +  INSERT INTO """1"("""2","""3") VALUES('uvw','xyz');
          146  +  SELECT 1, """5" FROM """4";
          147  +  DELETE FROM """1";
          148  +  SELECT 2, """5" FROM """4";
          149  +} {1 abc}
          150  +do_execsql_test fkey1-4.2 {
          151  +  PRAGMA table_info="""1";
          152  +} {0 {"2} TEXT 0 {} 1 1 {"3} TEXT 0 {} 0}
   123    153   
   124    154   finish_test

Added test/fts3expr5.test.

            1  +# 2006 September 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 script is testing the FTS3 module.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set testprefix fts3expr5
           18  +
           19  +# If SQLITE_ENABLE_FTS3 is defined, omit this file.
           20  +ifcapable !fts3 {
           21  +  finish_test
           22  +  return
           23  +}
           24  +
           25  +#-------------------------------------------------------------------------
           26  +# Various forms of empty phrase expressions.
           27  +#
           28  +do_execsql_test 1.0 {
           29  +  CREATE VIRTUAL TABLE t0 USING fts3(x);
           30  +  SELECT rowid FROM t0 WHERE x MATCH '';
           31  +} {}
           32  +do_execsql_test 1.1 {
           33  +  SELECT rowid FROM t0 WHERE x MATCH '""';
           34  +} {}
           35  +do_execsql_test 1.2 {
           36  +  SELECT rowid FROM t0 WHERE x MATCH '"" ""';
           37  +} {}
           38  +do_execsql_test 1.3 {
           39  +  SELECT rowid FROM t0 WHERE x MATCH '"" OR ""';
           40  +} {}
           41  +do_execsql_test 1.4 {
           42  +  SELECT rowid FROM t0 WHERE x MATCH '"" NOT ""';
           43  +} {}
           44  +do_execsql_test 1.5 {
           45  +  SELECT rowid FROM t0 WHERE x MATCH '""""';
           46  +} {}
           47  +
           48  +finish_test

Changes to test/fts4check.test.

   174    174     db close
   175    175     sqlite3 db test.db
   176    176     catchsql {
   177    177       INSERT INTO t4(t4) VALUES('integrity-check');
   178    178     }
   179    179   } {1 {database disk image is malformed}}
   180    180   reset_db
          181  +
          182  +#--------------------------------------------------------------------------
          183  +# Test case 5.*
          184  +#
          185  +# Test that the integrity-check works if there is uncommitted data.
          186  +#
          187  +do_execsql_test 5.0 {
          188  +  BEGIN;
          189  +  CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
          190  +  INSERT INTO t5 VALUES('And down by Kosiosko, where the reed-banks sweep');
          191  +  INSERT INTO t5 VALUES('and sway, and the rolling plains are wide, the');
          192  +  INSERT INTO t5 VALUES('man from snowy river is a household name today,');
          193  +  INSERT INTO t5 VALUES('and the stockmen tell the story of his ride');
          194  +}
          195  +
          196  +do_execsql_test 5.1 {
          197  +  INSERT INTO t5(t5) VALUES('integrity-check');
          198  +} {}
          199  +
          200  +do_catchsql_test 5.2 {
          201  +  INSERT INTO t5_content VALUES(5, 'his hardy mountain pony');
          202  +  INSERT INTO t5(t5) VALUES('integrity-check');
          203  +} {1 {database disk image is malformed}}
          204  +
          205  +do_execsql_test 5.3 ROLLBACK
          206  +
          207  +do_execsql_test 5.4 {
          208  +  CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
          209  +  INSERT INTO t5(t5) VALUES('integrity-check');
          210  +} {}
   181    211   
   182    212   finish_test
   183    213   

Changes to test/insert2.test.

    12     12   # focus of this file is testing the INSERT statement that takes is
    13     13   # result from a SELECT.
    14     14   #
    15     15   # $Id: insert2.test,v 1.19 2008/01/16 18:20:42 danielk1977 Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
           19  +set testprefix insert2
    19     20   
    20     21   # Create some tables with data that we can select against
    21     22   #
    22     23   do_test insert2-1.0 {
    23     24     execsql {CREATE TABLE d1(n int, log int);}
    24     25     for {set i 1} {$i<=20} {incr i} {
    25     26       for {set j 0} {(1<<$j)<$i} {incr j} {}
................................................................................
   270    271     do_test insert2-5.2 {
   271    272       execsql {
   272    273         INSERT INTO t2 SELECT (SELECT a FROM t2), 4;
   273    274         SELECT * FROM t2;
   274    275       }
   275    276     } {1 2 1 3 1 4}
   276    277   }
          278  +
          279  +do_execsql_test 6.0 { 
          280  +  CREATE TABLE t5(a, b, c DEFAULT 'c', d);
          281  +}
          282  +do_execsql_test 6.1 {
          283  +  INSERT INTO t5(a) SELECT 456 UNION ALL SELECT 123 ORDER BY 1;
          284  +  SELECT * FROM t5 ORDER BY rowid;
          285  +} {123 {} c {}   456 {} c {}}
          286  +
          287  +ifcapable fts3 {
          288  +  do_execsql_test 6.2 {
          289  +    CREATE VIRTUAL TABLE t0 USING fts4(a);
          290  +  }
          291  +  do_execsql_test 6.3 {
          292  +    INSERT INTO t0 SELECT 0 UNION SELECT 0 AS 'x' ORDER BY x;
          293  +    SELECT * FROM t0;
          294  +  } {0}
          295  +}
          296  +
   277    297   
   278    298   finish_test

Changes to test/resolver01.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   # This file tests features of the name resolver (the component that
    13     13   # figures out what identifiers in the SQL statement refer to) that
    14         -# were fixed by ticket [2500cdb9be]
           14  +# were fixed by ticket [2500cdb9be].
    15     15   #
    16     16   # See also tickets [1c69be2daf] and [f617ea3125] from 2013-08-14.
           17  +#
           18  +# Also a fuzzer-discovered problem on 2015-04-23.
    17     19   #
    18     20   
    19     21   set testdir [file dirname $argv0]
    20     22   source $testdir/tester.tcl
    21     23   
    22     24   # "ORDER BY y" binds to the output result-set column named "y"
    23     25   # if available.  If no output column is named "y", then try to
................................................................................
   197    199     INSERT INTO t63 VALUES ('abc');
   198    200     SELECT count(),
   199    201          NULLIF(name,'abc') AS name
   200    202       FROM t63
   201    203      GROUP BY lower(name);
   202    204   } {1 {} 1 {}}
   203    205   
          206  +do_execsql_test resolver01-7.1 {
          207  +  SELECT 2 AS x WHERE (SELECT x AS y WHERE 3>y);
          208  +} {2}
          209  +do_execsql_test resolver01-7.2 {
          210  +  SELECT 2 AS x WHERE (SELECT x AS y WHERE 1>y);
          211  +} {}
   204    212   
   205    213   
   206    214   
   207    215   
   208    216   finish_test

Changes to test/select4.test.

   889    889   } {1 2}
   890    890   do_execsql_test select4-14.13 {
   891    891     VALUES(1),(2),(3) EXCEPT VALUES(2);
   892    892   } {1 3}
   893    893   do_execsql_test select4-14.14 {
   894    894     VALUES(1),(2),(3) EXCEPT VALUES(1),(3);
   895    895   } {2}
          896  +do_execsql_test select4-14.15 {
          897  +  SELECT * FROM (SELECT 123), (SELECT 456) ON likely(0 OR 1) OR 0;
          898  +} {123 456}
   896    899   
   897    900   finish_test

Changes to test/subquery.test.

   579    579   } {30101 30102 30103}
   580    580   do_test subquery-7.11 {
   581    581     execsql {
   582    582       SELECT (SELECT (SELECT max(c7)+max(c8)+max(c9) FROM t9) FROM t8) FROM t7
   583    583     }
   584    584   } {30303}
   585    585   }  ;############# Disabled
          586  +
          587  +# 2015-04-21.
          588  +# Verify that a memory leak in the table column type and collation analysis
          589  +# is plugged.
          590  +#
          591  +do_execsql_test subquery-8.1 {
          592  +  CREATE TABLE t8(a TEXT, b INT);
          593  +  SELECT (SELECT 0 FROM (SELECT * FROM t1)) AS x WHERE x;
          594  +  SELECT (SELECT 0 FROM (SELECT * FROM (SELECT 0))) AS x WHERE x;
          595  +} {}
   586    596   
   587    597   finish_test

Changes to test/trace2.test.

   139    139       "-- SELECT level, idx, end_block FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ? ORDER BY level DESC, idx ASC"
   140    140     }
   141    141   
   142    142     do_trace_test 2.3 {
   143    143       INSERT INTO x1(x1) VALUES('optimize');
   144    144     } {
   145    145       "INSERT INTO x1(x1) VALUES('optimize');"
   146         -    "-- SELECT DISTINCT level / (1024 * ?) FROM 'main'.'x1_segdir'"
          146  +    "-- SELECT ? UNION SELECT level / (1024 * ?) FROM 'main'.'x1_segdir'"
   147    147       "-- SELECT idx, start_block, leaves_end_block, end_block, root FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?ORDER BY level DESC, idx ASC"
   148    148       "-- SELECT max(level) FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?"
   149    149       "-- SELECT coalesce((SELECT max(blockid) FROM 'main'.'x1_segments') + 1, 1)"
   150    150       "-- DELETE FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?"
   151    151       "-- REPLACE INTO 'main'.'x1_segdir' VALUES(?,?,?,?,?,?)"
   152    152     }
   153    153   }
   154    154   
   155    155   finish_test

Changes to test/triggerC.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
           15  +set testprefix triggerC
    15     16   ifcapable {!trigger} {
    16     17     finish_test
    17     18     return
    18     19   }
    19     20   
    20     21   #-------------------------------------------------------------------------
    21     22   # Test organization:
................................................................................
   988    989   }
   989    990   
   990    991   reset_db
   991    992   do_execsql_test triggerC-14.1 $SQL {1 2 3}
   992    993   reset_db
   993    994   optimization_control db factor-constants 0
   994    995   do_execsql_test triggerC-14.2 $SQL {1 2 3}
          996  +
          997  +#-------------------------------------------------------------------------
          998  +# Check that table names used by trigger programs are dequoted exactly
          999  +# once.
         1000  +#
         1001  +do_execsql_test 15.1.1 {
         1002  +  PRAGMA recursive_triggers = 1;
         1003  +  CREATE TABLE node(
         1004  +      id int not null primary key, 
         1005  +      pid int not null default 0 references node,
         1006  +      key varchar not null, 
         1007  +      path varchar default '',
         1008  +      unique(pid, key)
         1009  +      );
         1010  +  CREATE TRIGGER node_delete_referencing AFTER DELETE ON "node"
         1011  +    BEGIN
         1012  +    DELETE FROM "node" WHERE pid = old."id";
         1013  +  END;
         1014  +}
         1015  +do_execsql_test 15.1.2 {
         1016  +  INSERT INTO node(id, pid, key) VALUES(9, 0, 'test');
         1017  +  INSERT INTO node(id, pid, key) VALUES(90, 9, 'test1');
         1018  +  INSERT INTO node(id, pid, key) VALUES(900, 90, 'test2');
         1019  +  DELETE FROM node WHERE id=9;
         1020  +  SELECT * FROM node;
         1021  +}
         1022  +
         1023  +do_execsql_test 15.2.1 {
         1024  +  CREATE TABLE   x1  (x);
         1025  +
         1026  +  CREATE TABLE   x2  (a, b);
         1027  +  CREATE TABLE '"x2"'(a, b);
         1028  +
         1029  +  INSERT INTO x2 VALUES(1, 2);
         1030  +  INSERT INTO x2 VALUES(3, 4);
         1031  +  INSERT INTO '"x2"' SELECT * FROM x2;
         1032  +
         1033  +  CREATE TRIGGER x1ai AFTER INSERT ON x1 BEGIN
         1034  +    INSERT INTO """x2""" VALUES('x', 'y');
         1035  +    DELETE FROM """x2""" WHERE a=1;
         1036  +    UPDATE """x2""" SET b = 11 WHERE a = 3;
         1037  +  END;
         1038  +
         1039  +  INSERT INTO x1 VALUES('go!');
         1040  +}
         1041  +
         1042  +do_execsql_test 15.2.2 { SELECT * FROM x2;       } {1 2 3 4}
         1043  +do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}
   995   1044   
   996   1045   finish_test

Changes to tool/build-all-msvc.bat.

    24     24   REM                        CD /D C:\dev\sqlite\core
    25     25   REM                        tool\build-all-msvc.bat C:\Temp
    26     26   REM
    27     27   REM In the example above, "C:\dev\sqlite\core" represents the root of the
    28     28   REM source tree for SQLite and "C:\Temp" represents the final destination
    29     29   REM directory for the generated output files.
    30     30   REM
           31  +REM Please note that the SQLite build process performed by the Makefile
           32  +REM associated with this batch script requires both Gawk ^(gawk.exe^) and Tcl
           33  +REM 8.5 ^(tclsh85.exe^) to be present in a directory contained in the PATH
           34  +REM environment variable unless a pre-existing amalgamation file is used.
           35  +REM
    31     36   REM There are several environment variables that may be set to modify the
    32     37   REM behavior of this batch script and its associated Makefile.  The list of
    33     38   REM platforms to build may be overriden by using the PLATFORMS environment
    34     39   REM variable, which should contain a list of platforms ^(e.g. x86 x86_amd64
    35     40   REM x86_arm^).  All platforms must be supported by the version of Visual Studio
    36     41   REM being used.  The list of configurations to build may be overridden by
    37     42   REM setting the CONFIGURATIONS environment variable, which should contain a
    38     43   REM list of configurations to build ^(e.g. Debug Retail^).  Neither of these
    39     44   REM variable values may contain any double quotes, surrounding or embedded.
    40         -REM Finally, the NCRTLIBPATH and NSDKLIBPATH environment variables may be set
    41         -REM to specify the location of the CRT and SDK, respectively, needed to compile
    42         -REM executables native to the architecture of the build machine during any
    43         -REM cross-compilation that may be necessary, depending on the platforms to be
    44         -REM built.  These values in these two variables should be surrounded by double
    45         -REM quotes if they contain spaces.
    46         -REM
    47         -REM Please note that the SQLite build process performed by the Makefile
    48         -REM associated with this batch script requires both Gawk ^(gawk.exe^) and Tcl
    49         -REM 8.5 ^(tclsh85.exe^) to be present in a directory contained in the PATH
    50         -REM environment variable unless a pre-existing amalgamation file is used.
           45  +REM
           46  +REM Finally, the NCRTLIBPATH, NUCRTLIBPATH, and NSDKLIBPATH environment
           47  +REM variables may be set to specify the location of the CRT, Universal CRT, and
           48  +REM Windows SDK, respectively, that may be needed to compile executables native
           49  +REM to the architecture of the build machine during any cross-compilation that
           50  +REM may be necessary, depending on the platforms to be built.  These values in
           51  +REM these three variables should be surrounded by double quotes if they contain
           52  +REM spaces.
           53  +REM
           54  +REM There are a few other environment variables that impact the build process
           55  +REM when set ^(to anything^), they are:
           56  +REM
           57  +REM                        NOCLEAN
           58  +REM
           59  +REM When set, the "clean" target will not be used during each build iteration.
           60  +REM However, the target binaries, if any, will still be deleted manually prior
           61  +REM to being rebuilt.  Setting this environment variable is only rarely needed
           62  +REM and could cause issues in some circumstances; therefore, setting it is not
           63  +REM recommended.
           64  +REM
           65  +REM                        NOSYMBOLS
           66  +REM
           67  +REM When set, copying of symbol files ^(*.pdb^) created during the build will
           68  +REM be skipped and they will not appear in the final destination directory.
           69  +REM Setting this environment variable is never strictly needed and could cause
           70  +REM issues in some circumstances; therefore, setting it is not recommended.
           71  +REM
           72  +REM                        BUILD_ALL_SHELL
           73  +REM
           74  +REM When set, the command line shell will be built for each selected platform
           75  +REM and configuration as well.  In addition, the command line shell binaries
           76  +REM will be copied, with their symbols, to the final destination directory.
           77  +REM
           78  +REM                        USE_WINV63_NSDKLIBPATH
           79  +REM
           80  +REM When set, modifies how the NSDKLIBPATH environment variable is built, based
           81  +REM on the WindowsSdkDir environment variable.  It forces this batch script to
           82  +REM assume the Windows 8.1 SDK location should be used.
           83  +REM
           84  +REM                        USE_WINV100_NSDKLIBPATH
           85  +REM
           86  +REM When set, modifies how the NSDKLIBPATH environment variable is built, based
           87  +REM on the WindowsSdkDir environment variable.  It causes this batch script to
           88  +REM assume the Windows 10.0 SDK location should be used.
           89  +REM
           90  +REM                        NMAKE_ARGS
           91  +REM
           92  +REM When set, the value is expanded and passed to the NMAKE command line, after
           93  +REM its other arguments.  This is used to specify additional NMAKE options, for
           94  +REM example:
           95  +REM
           96  +REM                        SET NMAKE_ARGS=FOR_WINRT=1
    51     97   REM
    52     98   SETLOCAL
    53     99   
    54    100   REM SET __ECHO=ECHO
    55    101   REM SET __ECHO2=ECHO
    56    102   REM SET __ECHO3=ECHO
    57    103   IF NOT DEFINED _AECHO (SET _AECHO=REM)
................................................................................
   213    259   REM       external tools were found in the search above.
   214    260   REM
   215    261   SET TOOLPATH=%gawk.exe_PATH%;%tclsh85.exe_PATH%
   216    262   
   217    263   %_VECHO% ToolPath = '%TOOLPATH%'
   218    264   
   219    265   REM
   220         -REM NOTE: Check for MSVC 2012/2013 because the Windows SDK directory handling
   221         -REM       is slightly different for those versions.
          266  +REM NOTE: Setting the Windows SDK library path is only required for MSVC
          267  +REM       2012, 2013, and 2015.
          268  +REM
          269  +CALL :fn_UnsetVariable SET_NSDKLIBPATH
          270  +
          271  +REM
          272  +REM NOTE: Setting the Universal CRT library path is only required for MSVC
          273  +REM       2015.
          274  +REM
          275  +CALL :fn_UnsetVariable SET_NUCRTLIBPATH
          276  +
          277  +REM
          278  +REM NOTE: Check for MSVC 2012, 2013, and 2015 specially because the Windows
          279  +REM       SDK directory handling is slightly different for those versions.
   222    280   REM
   223    281   IF "%VisualStudioVersion%" == "11.0" (
   224    282     REM
   225    283     REM NOTE: If the Windows SDK library path has already been set, do not set
   226    284     REM       it to something else later on.
   227    285     REM
   228    286     IF NOT DEFINED NSDKLIBPATH (
................................................................................
   232    290     REM
   233    291     REM NOTE: If the Windows SDK library path has already been set, do not set
   234    292     REM       it to something else later on.
   235    293     REM
   236    294     IF NOT DEFINED NSDKLIBPATH (
   237    295       SET SET_NSDKLIBPATH=1
   238    296     )
   239         -) ELSE (
   240         -  CALL :fn_UnsetVariable SET_NSDKLIBPATH
          297  +) ELSE IF "%VisualStudioVersion%" == "14.0" (
          298  +  REM
          299  +  REM NOTE: If the Windows SDK library path has already been set, do not set
          300  +  REM       it to something else later on.
          301  +  REM
          302  +  IF NOT DEFINED NSDKLIBPATH (
          303  +    SET SET_NSDKLIBPATH=1
          304  +  )
          305  +
          306  +  REM
          307  +  REM NOTE: If the Universal CRT library path has already been set, do not set
          308  +  REM       it to something else later on.
          309  +  REM
          310  +  IF NOT DEFINED NUCRTLIBPATH (
          311  +    SET SET_NUCRTLIBPATH=1
          312  +  )
   241    313   )
   242    314   
   243    315   REM
   244    316   REM NOTE: Check if this is the Windows Phone SDK.  If so, a different batch
   245    317   REM       file is necessary to setup the build environment.  Since the variable
   246    318   REM       values involved here may contain parenthesis, using GOTO instead of
   247    319   REM       an IF block is required.
................................................................................
   290    362       CALL :fn_UnsetVariable FrameworkVersion
   291    363       CALL :fn_UnsetVariable FrameworkVersion32
   292    364       CALL :fn_UnsetVariable FSHARPINSTALLDIR
   293    365       CALL :fn_UnsetVariable INCLUDE
   294    366       CALL :fn_UnsetVariable LIB
   295    367       CALL :fn_UnsetVariable LIBPATH
   296    368       CALL :fn_UnsetVariable Platform
          369  +    CALL :fn_UnsetVariable UniversalCRTSdkDir
   297    370       REM CALL :fn_UnsetVariable VCINSTALLDIR
   298    371       CALL :fn_UnsetVariable VSINSTALLDIR
   299    372       CALL :fn_UnsetVariable WindowsPhoneKitDir
   300    373       CALL :fn_UnsetVariable WindowsSdkDir
   301    374       CALL :fn_UnsetVariable WindowsSdkDir_35
   302    375       CALL :fn_UnsetVariable WindowsSdkDir_old
   303    376       CALL :fn_UnsetVariable WindowsSDK_ExecutablePath_x86
................................................................................
   381    454                 ECHO Cannot build, Windows SDK not found for platform %%P.
   382    455                 GOTO errors
   383    456               )
   384    457             )
   385    458           )
   386    459   
   387    460           REM
   388         -        REM NOTE: When using MSVC 2012 and/or 2013, the native SDK path cannot
   389         -        REM       simply use the "lib" sub-directory beneath the location
          461  +        REM NOTE: When using MSVC 2012, 2013, or 2015, the native SDK path
          462  +        REM       cannot simply be the "lib" sub-directory beneath the location
   390    463           REM       specified in the WindowsSdkDir environment variable because
   391    464           REM       that location does not actually contain the necessary library
   392    465           REM       files for x86.  This must be done for each iteration because
   393    466           REM       it relies upon the WindowsSdkDir environment variable being
   394    467           REM       set by the batch file used to setup the MSVC environment.
   395    468           REM
   396    469           IF DEFINED SET_NSDKLIBPATH (
................................................................................
   401    474             IF DEFINED WindowsPhoneKitDir (
   402    475               CALL :fn_CopyVariable WindowsPhoneKitDir NSDKLIBPATH
   403    476               CALL :fn_AppendVariable NSDKLIBPATH \lib\x86
   404    477             ) ELSE IF DEFINED WindowsSdkDir (
   405    478               CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
   406    479   
   407    480               REM
   408         -            REM NOTE: The Windows 8.1 SDK has a slightly different directory
   409         -            REM       naming convention.
          481  +            REM NOTE: The Windows 8.x and Windows 10.0 SDKs have a slightly
          482  +            REM       different directory naming conventions.
   410    483               REM
   411         -            IF DEFINED USE_WINV63_NSDKLIBPATH (
          484  +            IF DEFINED USE_WINV100_NSDKLIBPATH (
          485  +              CALL :fn_AppendVariable NSDKLIBPATH \..\10\lib\10.0.10030.0\um\x86
          486  +              CALL :fn_CopyVariable UniversalCRTSdkDir PSDKLIBPATH
          487  +              CALL :fn_AppendVariable PSDKLIBPATH Lib\10.0.10030.0\um\%%D
          488  +            ) ELSE IF DEFINED USE_WINV63_NSDKLIBPATH (
   412    489                 CALL :fn_AppendVariable NSDKLIBPATH \lib\winv6.3\um\x86
   413    490               ) ELSE IF "%VisualStudioVersion%" == "12.0" (
          491  +              CALL :fn_AppendVariable NSDKLIBPATH \..\8.0\lib\win8\um\x86
          492  +            ) ELSE IF "%VisualStudioVersion%" == "14.0" (
   414    493                 CALL :fn_AppendVariable NSDKLIBPATH \..\8.0\lib\win8\um\x86
   415    494               ) ELSE (
   416    495                 CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
   417    496               )
   418    497             )
   419    498           )
          499  +
          500  +        REM
          501  +        REM NOTE: When using MSVC 2015, setting the Universal CRT library path
          502  +        REM       for x86 may be required as well.  This must also be done for
          503  +        REM       each iteration because it relies upon the UniversalCRTSdkDir
          504  +        REM       environment variable being set by the batch file used to
          505  +        REM       setup the MSVC environment.
          506  +        REM
          507  +        IF DEFINED SET_NUCRTLIBPATH (
          508  +          IF DEFINED UniversalCRTSdkDir (
          509  +            CALL :fn_CopyVariable UniversalCRTSdkDir NUCRTLIBPATH
          510  +            CALL :fn_AppendVariable NUCRTLIBPATH \lib\winv10.0\ucrt\x86
          511  +          )
          512  +        )
   420    513   
   421    514           REM
   422    515           REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
   423    516           REM       makefile to clean any stale build output from previous
   424    517           REM       iterations of this loop and/or previous runs of this batch
   425    518           REM       file, etc.
   426    519           REM
................................................................................
   570    663     GOTO errors
   571    664   )
   572    665   
   573    666   REM
   574    667   REM NOTE: If we get to this point, we have succeeded.
   575    668   REM
   576    669   GOTO no_errors
          670  +
          671  +:fn_ShowVariable
          672  +  SETLOCAL
          673  +  SET __ECHO_CMD=ECHO %%%2%%
          674  +  FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
          675  +    IF NOT "%%V" == "" (
          676  +      IF NOT "%%V" == "%%%2%%" (
          677  +        %_VECHO% %1 = '%%V'
          678  +      )
          679  +    )
          680  +  )
          681  +  ENDLOCAL
          682  +  GOTO :EOF
   577    683   
   578    684   :fn_ResetErrorLevel
   579    685     VERIFY > NUL
   580    686     GOTO :EOF
   581    687   
   582    688   :fn_SetErrorLevel
   583    689     VERIFY MAYBE 2> NUL

Changes to tool/fuzzershell.c.

    27     27   **
    28     28   **    (3)  The main in-memory database can be initialized from a template
    29     29   **         disk database so that the fuzzer starts with a database containing
    30     30   **         content.
    31     31   **
    32     32   **    (4)  The eval() SQL function is added, allowing the fuzzer to do 
    33     33   **         interesting recursive operations.
           34  +**
           35  +** 2015-04-20: The input text can be divided into separate SQL chunks using
           36  +** lines of the form:
           37  +**
           38  +**       |****<...>****|
           39  +**
           40  +** where the "..." is arbitrary text, except the "|" should really be "/".
           41  +** ("|" is used here to avoid compiler warnings about nested comments.)
           42  +** Each such SQL comment is printed as it is encountered.  A separate 
           43  +** in-memory SQLite database is created to run each chunk of SQL.  This
           44  +** feature allows the "queue" of AFL to be captured into a single big
           45  +** file using a command like this:
           46  +**
           47  +**    (for i in id:*; do echo '|****<'$i'>****|'; cat $i; done) >~/all-queue.txt
           48  +**
           49  +** (Once again, change the "|" to "/") Then all elements of the AFL queue
           50  +** can be run in a single go (for regression testing, for example) by typing:
           51  +**
           52  +**    fuzzershell -f ~/all-queue.txt >out.txt
           53  +**
           54  +** After running each chunk of SQL, the database connection is closed.  The
           55  +** program aborts if the close fails or if there is any unfreed memory after
           56  +** the close.
    34     57   */
    35     58   #include <stdio.h>
    36     59   #include <stdlib.h>
    37     60   #include <string.h>
    38     61   #include <stdarg.h>
           62  +#include <ctype.h>
    39     63   #include "sqlite3.h"
    40     64   
    41     65   /*
    42     66   ** All global variables are gathered into the "g" singleton.
    43     67   */
    44     68   struct GlobalVars {
    45     69     const char *zArgv0;         /* Name of program */
................................................................................
    69     93     fprintf(stderr, "%s: ", g.zArgv0);
    70     94     va_start(ap, zFormat);
    71     95     vfprintf(stderr, zFormat, ap);
    72     96     va_end(ap);
    73     97     fprintf(stderr, "\n");
    74     98     exit(1);
    75     99   }
          100  +
          101  +/*
          102  +** Evaluate some SQL.  Abort if unable.
          103  +*/
          104  +static void sqlexec(sqlite3 *db, const char *zFormat, ...){
          105  +  va_list ap;
          106  +  char *zSql;
          107  +  char *zErrMsg = 0;
          108  +  int rc;
          109  +  va_start(ap, zFormat);
          110  +  zSql = sqlite3_vmprintf(zFormat, ap);
          111  +  va_end(ap);
          112  +  rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg);
          113  +  if( rc ) abendError("failed sql [%s]: %s", zSql, zErrMsg);
          114  +  sqlite3_free(zSql);
          115  +}
    76    116   
    77    117   /*
    78    118   ** This callback is invoked by sqlite3_log().
    79    119   */
    80    120   static void shellLog(void *pNotUsed, int iErrCode, const char *zMsg){
    81    121     printf("LOG: (%d) %s\n", iErrCode, zMsg);
    82    122   }
................................................................................
   199    239   ** Print sketchy documentation for this utility program
   200    240   */
   201    241   static void showHelp(void){
   202    242     printf("Usage: %s [options]\n", g.zArgv0);
   203    243     printf(
   204    244   "Read SQL text from standard input and evaluate it.\n"
   205    245   "Options:\n"
          246  +"  --autovacuum        Enable AUTOVACUUM mode\n"
   206    247   "  -f FILE             Read SQL text from FILE instead of standard input\n"
          248  +"  --heap SZ MIN       Memory allocator uses SZ bytes & min allocation MIN\n"
   207    249   "  --help              Show this help text\n"    
   208    250   "  --initdb DBFILE     Initialize the in-memory database using template DBFILE\n"
          251  +"  --lookaside N SZ    Configure lookaside for N slots of SZ bytes each\n"
          252  +"  --pagesize N        Set the page size to N\n"
          253  +"  --pcache N SZ       Configure N pages of pagecache each of size SZ bytes\n"
          254  +"  --scratch N SZ      Configure scratch memory for N slots of SZ bytes each\n"
          255  +"  --utf16be           Set text encoding to UTF-16BE\n"
          256  +"  --utf16le           Set text encoding to UTF-16LE\n"
   209    257     );
   210    258   }
   211    259   
          260  +/*
          261  +** Return the value of a hexadecimal digit.  Return -1 if the input
          262  +** is not a hex digit.
          263  +*/
          264  +static int hexDigitValue(char c){
          265  +  if( c>='0' && c<='9' ) return c - '0';
          266  +  if( c>='a' && c<='f' ) return c - 'a' + 10;
          267  +  if( c>='A' && c<='F' ) return c - 'A' + 10;
          268  +  return -1;
          269  +}
          270  +
          271  +/*
          272  +** Interpret zArg as an integer value, possibly with suffixes.
          273  +*/
          274  +static int integerValue(const char *zArg){
          275  +  sqlite3_int64 v = 0;
          276  +  static const struct { char *zSuffix; int iMult; } aMult[] = {
          277  +    { "KiB", 1024 },
          278  +    { "MiB", 1024*1024 },
          279  +    { "GiB", 1024*1024*1024 },
          280  +    { "KB",  1000 },
          281  +    { "MB",  1000000 },
          282  +    { "GB",  1000000000 },
          283  +    { "K",   1000 },
          284  +    { "M",   1000000 },
          285  +    { "G",   1000000000 },
          286  +  };
          287  +  int i;
          288  +  int isNeg = 0;
          289  +  if( zArg[0]=='-' ){
          290  +    isNeg = 1;
          291  +    zArg++;
          292  +  }else if( zArg[0]=='+' ){
          293  +    zArg++;
          294  +  }
          295  +  if( zArg[0]=='0' && zArg[1]=='x' ){
          296  +    int x;
          297  +    zArg += 2;
          298  +    while( (x = hexDigitValue(zArg[0]))>=0 ){
          299  +      v = (v<<4) + x;
          300  +      zArg++;
          301  +    }
          302  +  }else{
          303  +    while( isdigit(zArg[0]) ){
          304  +      v = v*10 + zArg[0] - '0';
          305  +      zArg++;
          306  +    }
          307  +  }
          308  +  for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
          309  +    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
          310  +      v *= aMult[i].iMult;
          311  +      break;
          312  +    }
          313  +  }
          314  +  if( v>0x7fffffff ) abendError("parameter too large - max 2147483648");
          315  +  return (int)(isNeg? -v : v);
          316  +}
          317  +
          318  +/*
          319  +** Various operating modes
          320  +*/
          321  +#define FZMODE_Generic   1
          322  +#define FZMODE_Strftime  2
          323  +#define FZMODE_Printf    3
          324  +#define FZMODE_Glob      4
          325  +
   212    326   
   213    327   int main(int argc, char **argv){
   214    328     char *zIn = 0;          /* Input text */
   215    329     int nAlloc = 0;         /* Number of bytes allocated for zIn[] */
   216    330     int nIn = 0;            /* Number of bytes of zIn[] used */
   217    331     size_t got;             /* Bytes read from input */
   218    332     FILE *in = stdin;       /* Where to read SQL text from */
   219    333     int rc = SQLITE_OK;     /* Result codes from API functions */
   220    334     int i;                  /* Loop counter */
          335  +  int iNext;              /* Next block of SQL */
   221    336     sqlite3 *db;            /* Open database */
   222         -  sqlite3 *dbInit;        /* On-disk database used to initialize the in-memory db */
          337  +  sqlite3 *dbInit = 0;    /* On-disk database used to initialize the in-memory db */
   223    338     const char *zInitDb = 0;/* Name of the initialization database file */
   224    339     char *zErrMsg = 0;      /* Error message returned from sqlite3_exec() */
          340  +  const char *zEncoding = 0;    /* --utf16be or --utf16le */
          341  +  int nHeap = 0, mnHeap = 0;    /* Heap size from --heap */
          342  +  int nLook = 0, szLook = 0;    /* --lookaside configuration */
          343  +  int nPCache = 0, szPCache = 0;/* --pcache configuration */
          344  +  int nScratch = 0, szScratch=0;/* --scratch configuration */
          345  +  int pageSize = 0;             /* Desired page size.  0 means default */
          346  +  void *pHeap = 0;              /* Allocated heap space */
          347  +  void *pLook = 0;              /* Allocated lookaside space */
          348  +  void *pPCache = 0;            /* Allocated storage for pcache */
          349  +  void *pScratch = 0;           /* Allocated storage for scratch */
          350  +  int doAutovac = 0;            /* True for --autovacuum */
          351  +  char *zSql;                   /* SQL to run */
          352  +  char *zToFree = 0;            /* Call sqlite3_free() on this afte running zSql */
          353  +  int iMode = FZMODE_Generic;   /* Operating mode */
          354  +  const char *zCkGlob = 0;      /* Inputs must match this glob */
          355  +
   225    356   
   226    357     g.zArgv0 = argv[0];
   227    358     for(i=1; i<argc; i++){
   228    359       const char *z = argv[i];
   229    360       if( z[0]=='-' ){
   230    361         z++;
   231    362         if( z[0]=='-' ) z++;
   232         -      if( strcmp(z,"help")==0 ){
   233         -        showHelp();
   234         -        return 0;
          363  +      if( strcmp(z,"autovacuum")==0 ){
          364  +        doAutovac = 1;
   235    365         }else
   236    366         if( strcmp(z, "f")==0 && i+1<argc ){
   237    367           if( in!=stdin ) abendError("only one -f allowed");
   238    368           in = fopen(argv[++i],"rb");
   239    369           if( in==0 )  abendError("cannot open input file \"%s\"", argv[i]);
          370  +      }else
          371  +      if( strcmp(z,"heap")==0 ){
          372  +        if( i>=argc-2 ) abendError("missing arguments on %s\n", argv[i]);
          373  +        nHeap = integerValue(argv[i+1]);
          374  +        mnHeap = integerValue(argv[i+2]);
          375  +        i += 2;
          376  +      }else
          377  +      if( strcmp(z,"help")==0 ){
          378  +        showHelp();
          379  +        return 0;
   240    380         }else
   241    381         if( strcmp(z, "initdb")==0 && i+1<argc ){
   242    382           if( zInitDb!=0 ) abendError("only one --initdb allowed");
   243    383           zInitDb = argv[++i];
          384  +      }else
          385  +      if( strcmp(z,"lookaside")==0 ){
          386  +        if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
          387  +        nLook = integerValue(argv[i+1]);
          388  +        szLook = integerValue(argv[i+2]);
          389  +        i += 2;
          390  +      }else
          391  +      if( strcmp(z,"mode")==0 ){
          392  +        if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
          393  +        z = argv[++i];
          394  +        if( strcmp(z,"generic")==0 ){
          395  +          iMode = FZMODE_Printf;
          396  +          zCkGlob = 0;
          397  +        }else if( strcmp(z, "glob")==0 ){
          398  +          iMode = FZMODE_Glob;
          399  +          zCkGlob = "'*','*'";
          400  +        }else if( strcmp(z, "printf")==0 ){
          401  +          iMode = FZMODE_Printf;
          402  +          zCkGlob = "'*',*";
          403  +        }else if( strcmp(z, "strftime")==0 ){
          404  +          iMode = FZMODE_Strftime;
          405  +          zCkGlob = "'*',*";
          406  +        }else{
          407  +          abendError("unknown --mode: %s", z);
          408  +        }
          409  +      }else
          410  +      if( strcmp(z,"pagesize")==0 ){
          411  +        if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
          412  +        pageSize = integerValue(argv[++i]);
          413  +      }else
          414  +      if( strcmp(z,"pcache")==0 ){
          415  +        if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
          416  +        nPCache = integerValue(argv[i+1]);
          417  +        szPCache = integerValue(argv[i+2]);
          418  +        i += 2;
          419  +      }else
          420  +      if( strcmp(z,"scratch")==0 ){
          421  +        if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
          422  +        nScratch = integerValue(argv[i+1]);
          423  +        szScratch = integerValue(argv[i+2]);
          424  +        i += 2;
          425  +      }else
          426  +      if( strcmp(z,"utf16le")==0 ){
          427  +        zEncoding = "utf16le";
          428  +      }else
          429  +      if( strcmp(z,"utf16be")==0 ){
          430  +        zEncoding = "utf16be";
   244    431         }else
   245    432         {
   246    433           abendError("unknown option: %s", argv[i]);
   247    434         }
   248    435       }else{
   249    436         abendError("unknown argument: %s", argv[i]);
   250    437       }
   251    438     }
   252    439     sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 0);
   253         -  rc = sqlite3_open_v2(
   254         -    "main.db", &db,
   255         -    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
   256         -    0);
   257         -  if( rc!=SQLITE_OK ){
   258         -    abendError("Unable to open the in-memory database");
          440  +  if( nHeap>0 ){
          441  +    pHeap = malloc( nHeap );
          442  +    if( pHeap==0 ) fatalError("cannot allocate %d-byte heap\n", nHeap);
          443  +    rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
          444  +    if( rc ) abendError("heap configuration failed: %d\n", rc);
   259    445     }
   260         -  if( zInitDb ){
   261         -    sqlite3_backup *pBackup;
   262         -    rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0);
   263         -    if( rc!=SQLITE_OK ){
   264         -      abendError("unable to open initialization database \"%s\"", zInitDb);
          446  +  if( nLook>0 ){
          447  +    sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
          448  +    if( szLook>0 ){
          449  +      pLook = malloc( nLook*szLook );
          450  +      if( pLook==0 ) fatalError("out of memory");
   265    451       }
   266         -    pBackup = sqlite3_backup_init(db, "main", dbInit, "main");
   267         -    rc = sqlite3_backup_step(pBackup, -1);
   268         -    if( rc!=SQLITE_DONE ){
   269         -      abendError("attempt to initialize the in-memory database failed (rc=%d)",rc);
   270         -    }
   271         -    sqlite3_backup_finish(pBackup);
   272         -    sqlite3_close(dbInit);
          452  +  }
          453  +  if( nScratch>0 && szScratch>0 ){
          454  +    pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
          455  +    if( pScratch==0 ) fatalError("cannot allocate %lld-byte scratch",
          456  +                                 nScratch*(sqlite3_int64)szScratch);
          457  +    rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
          458  +    if( rc ) abendError("scratch configuration failed: %d\n", rc);
          459  +  }
          460  +  if( nPCache>0 && szPCache>0 ){
          461  +    pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
          462  +    if( pPCache==0 ) fatalError("cannot allocate %lld-byte pcache",
          463  +                                 nPCache*(sqlite3_int64)szPCache);
          464  +    rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
          465  +    if( rc ) abendError("pcache configuration failed: %d", rc);
   273    466     }
   274         -  sqlite3_trace(db, traceCallback, 0);
   275         -  sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
   276         -  sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
   277    467     while( !feof(in) ){
   278         -    nAlloc += 1000;
   279         -    zIn = sqlite3_realloc(zIn, nAlloc);
          468  +    nAlloc += nAlloc+1000;
          469  +    zIn = realloc(zIn, nAlloc);
   280    470       if( zIn==0 ) fatalError("out of memory");
   281    471       got = fread(zIn+nIn, 1, nAlloc-nIn-1, in); 
   282    472       nIn += (int)got;
   283    473       zIn[nIn] = 0;
   284    474       if( got==0 ) break;
   285    475     }
   286         -  printf("INPUT (%d bytes): [%s]\n", nIn, zIn);
   287         -  rc = sqlite3_exec(db, zIn, execCallback, 0, &zErrMsg);
   288         -  printf("RESULT-CODE: %d\n", rc);
   289         -  if( zErrMsg ){
   290         -    printf("ERROR-MSG: [%s]\n", zErrMsg);
   291         -    sqlite3_free(zErrMsg);
          476  +  if( zInitDb ){
          477  +    rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0);
          478  +    if( rc!=SQLITE_OK ){
          479  +      abendError("unable to open initialization database \"%s\"", zInitDb);
          480  +    }
          481  +  }
          482  +  for(i=0; i<nIn; i=iNext){
          483  +    char cSaved;
          484  +    if( strncmp(&zIn[i], "/****<",6)==0 ){
          485  +      char *z = strstr(&zIn[i], ">****/");
          486  +      if( z ){
          487  +        z += 6;
          488  +        printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]);
          489  +        i += (int)(z-&zIn[i]);
          490  +      }
          491  +    }
          492  +    for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){}
          493  +    cSaved = zIn[iNext];
          494  +    zIn[iNext] = 0;
          495  +    if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){
          496  +      zIn[iNext] = cSaved;
          497  +      continue;
          498  +    }
          499  +    rc = sqlite3_open_v2(
          500  +      "main.db", &db,
          501  +      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
          502  +      0);
          503  +    if( rc!=SQLITE_OK ){
          504  +      abendError("Unable to open the in-memory database");
          505  +    }
          506  +    if( pLook ){
          507  +      rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook, nLook);
          508  +      if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc);
          509  +    }
          510  +    if( zInitDb ){
          511  +      sqlite3_backup *pBackup;
          512  +      pBackup = sqlite3_backup_init(db, "main", dbInit, "main");
          513  +      rc = sqlite3_backup_step(pBackup, -1);
          514  +      if( rc!=SQLITE_DONE ){
          515  +        abendError("attempt to initialize the in-memory database failed (rc=%d)",
          516  +                   rc);
          517  +      }
          518  +      sqlite3_backup_finish(pBackup);
          519  +    }
          520  +    sqlite3_trace(db, traceCallback, 0);
          521  +    sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
          522  +    sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
          523  +    sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
          524  +    if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
          525  +    if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
          526  +    if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
          527  +    printf("INPUT (offset: %d, size: %d): [%s]\n",
          528  +            i, (int)strlen(&zIn[i]), &zIn[i]);
          529  +    zSql = &zIn[i];
          530  +    switch( iMode ){
          531  +      case FZMODE_Glob:
          532  +        zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql);
          533  +        break;
          534  +      case FZMODE_Printf:
          535  +        zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql);
          536  +        break;
          537  +      case FZMODE_Strftime:
          538  +        zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql);
          539  +        break;
          540  +    }
          541  +    rc = sqlite3_exec(db, zSql, execCallback, 0, &zErrMsg);
          542  +    if( zToFree ){
          543  +      sqlite3_free(zToFree);
          544  +      zToFree = 0;
          545  +    }
          546  +    zIn[iNext] = cSaved;
          547  +
          548  +    printf("RESULT-CODE: %d\n", rc);
          549  +    if( zErrMsg ){
          550  +      printf("ERROR-MSG: [%s]\n", zErrMsg);
          551  +      sqlite3_free(zErrMsg);
          552  +    }
          553  +    rc = sqlite3_close(db);
          554  +    if( rc ){
          555  +      abendError("sqlite3_close() failed with rc=%d", rc);
          556  +    }
          557  +    if( sqlite3_memory_used()>0 ){
          558  +      abendError("memory in use after close: %lld bytes", sqlite3_memory_used());
          559  +    }
   292    560     }
   293         -  return rc!=SQLITE_OK;
          561  +  free(zIn);
          562  +  free(pHeap);
          563  +  free(pLook);
          564  +  free(pScratch);
          565  +  free(pPCache);
          566  +  return 0;
   294    567   }

Changes to tool/lemon.c.

  1110   1110     ** finite state machine) an action to ACCEPT if the lookahead is the
  1111   1111     ** start nonterminal.  */
  1112   1112     Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0);
  1113   1113   
  1114   1114     /* Resolve conflicts */
  1115   1115     for(i=0; i<lemp->nstate; i++){
  1116   1116       struct action *ap, *nap;
  1117         -    struct state *stp;
  1118   1117       stp = lemp->sorted[i];
  1119   1118       /* assert( stp->ap ); */
  1120   1119       stp->ap = Action_sort(stp->ap);
  1121   1120       for(ap=stp->ap; ap && ap->next; ap=ap->next){
  1122   1121         for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
  1123   1122            /* The two actions "ap" and "nap" have the same lookahead.
  1124   1123            ** Figure out which one should be used */
................................................................................
  3744   3743     }
  3745   3744     lineno = 1;
  3746   3745     tplt_xfer(lemp->name,in,out,&lineno);
  3747   3746   
  3748   3747     /* Generate the include code, if any */
  3749   3748     tplt_print(out,lemp,lemp->include,&lineno);
  3750   3749     if( mhflag ){
  3751         -    char *name = file_makename(lemp, ".h");
  3752         -    fprintf(out,"#include \"%s\"\n", name); lineno++;
  3753         -    free(name);
         3750  +    char *incName = file_makename(lemp, ".h");
         3751  +    fprintf(out,"#include \"%s\"\n", incName); lineno++;
         3752  +    free(incName);
  3754   3753     }
  3755   3754     tplt_xfer(lemp->name,in,out,&lineno);
  3756   3755   
  3757   3756     /* Generate #defines for all tokens */
  3758   3757     if( mhflag ){
  3759   3758       const char *prefix;
  3760   3759       fprintf(out,"#if INTERFACE\n"); lineno++;
................................................................................
  3787   3786     }
  3788   3787     fprintf(out, "#endif\n"); lineno++;
  3789   3788     if( mhflag ){
  3790   3789       fprintf(out,"#if INTERFACE\n"); lineno++;
  3791   3790     }
  3792   3791     name = lemp->name ? lemp->name : "Parse";
  3793   3792     if( lemp->arg && lemp->arg[0] ){
  3794         -    int i;
  3795   3793       i = lemonStrlen(lemp->arg);
  3796   3794       while( i>=1 && isspace(lemp->arg[i-1]) ) i--;
  3797   3795       while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;
  3798   3796       fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg);  lineno++;
  3799   3797       fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg);  lineno++;
  3800   3798       fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n",
  3801   3799                    name,lemp->arg,&lemp->arg[i]);  lineno++;
................................................................................
  4475   4473         /* Fail because overwrite is not allows. */
  4476   4474         return 0;
  4477   4475       }
  4478   4476       np = np->next;
  4479   4477     }
  4480   4478     if( x1a->count>=x1a->size ){
  4481   4479       /* Need to make the hash table bigger */
  4482         -    int i,size;
         4480  +    int i,arrSize;
  4483   4481       struct s_x1 array;
  4484         -    array.size = size = x1a->size*2;
         4482  +    array.size = arrSize = x1a->size*2;
  4485   4483       array.count = x1a->count;
  4486         -    array.tbl = (x1node*)calloc(size, sizeof(x1node) + sizeof(x1node*));
         4484  +    array.tbl = (x1node*)calloc(arrSize, sizeof(x1node) + sizeof(x1node*));
  4487   4485       if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
  4488         -    array.ht = (x1node**)&(array.tbl[size]);
  4489         -    for(i=0; i<size; i++) array.ht[i] = 0;
         4486  +    array.ht = (x1node**)&(array.tbl[arrSize]);
         4487  +    for(i=0; i<arrSize; i++) array.ht[i] = 0;
  4490   4488       for(i=0; i<x1a->count; i++){
  4491   4489         x1node *oldnp, *newnp;
  4492   4490         oldnp = &(x1a->tbl[i]);
  4493         -      h = strhash(oldnp->data) & (size-1);
         4491  +      h = strhash(oldnp->data) & (arrSize-1);
  4494   4492         newnp = &(array.tbl[i]);
  4495   4493         if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
  4496   4494         newnp->next = array.ht[h];
  4497   4495         newnp->data = oldnp->data;
  4498   4496         newnp->from = &(array.ht[h]);
  4499   4497         array.ht[h] = newnp;
  4500   4498       }
................................................................................
  4642   4640         /* Fail because overwrite is not allows. */
  4643   4641         return 0;
  4644   4642       }
  4645   4643       np = np->next;
  4646   4644     }
  4647   4645     if( x2a->count>=x2a->size ){
  4648   4646       /* Need to make the hash table bigger */
  4649         -    int i,size;
         4647  +    int i,arrSize;
  4650   4648       struct s_x2 array;
  4651         -    array.size = size = x2a->size*2;
         4649  +    array.size = arrSize = x2a->size*2;
  4652   4650       array.count = x2a->count;
  4653         -    array.tbl = (x2node*)calloc(size, sizeof(x2node) + sizeof(x2node*));
         4651  +    array.tbl = (x2node*)calloc(arrSize, sizeof(x2node) + sizeof(x2node*));
  4654   4652       if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
  4655         -    array.ht = (x2node**)&(array.tbl[size]);
  4656         -    for(i=0; i<size; i++) array.ht[i] = 0;
         4653  +    array.ht = (x2node**)&(array.tbl[arrSize]);
         4654  +    for(i=0; i<arrSize; i++) array.ht[i] = 0;
  4657   4655       for(i=0; i<x2a->count; i++){
  4658   4656         x2node *oldnp, *newnp;
  4659   4657         oldnp = &(x2a->tbl[i]);
  4660         -      h = strhash(oldnp->key) & (size-1);
         4658  +      h = strhash(oldnp->key) & (arrSize-1);
  4661   4659         newnp = &(array.tbl[i]);
  4662   4660         if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
  4663   4661         newnp->next = array.ht[h];
  4664   4662         newnp->key = oldnp->key;
  4665   4663         newnp->data = oldnp->data;
  4666   4664         newnp->from = &(array.ht[h]);
  4667   4665         array.ht[h] = newnp;
................................................................................
  4718   4716   
  4719   4717   /* Return an array of pointers to all data in the table.
  4720   4718   ** The array is obtained from malloc.  Return NULL if memory allocation
  4721   4719   ** problems, or if the array is empty. */
  4722   4720   struct symbol **Symbol_arrayof()
  4723   4721   {
  4724   4722     struct symbol **array;
  4725         -  int i,size;
         4723  +  int i,arrSize;
  4726   4724     if( x2a==0 ) return 0;
  4727         -  size = x2a->count;
  4728         -  array = (struct symbol **)calloc(size, sizeof(struct symbol *));
         4725  +  arrSize = x2a->count;
         4726  +  array = (struct symbol **)calloc(arrSize, sizeof(struct symbol *));
  4729   4727     if( array ){
  4730         -    for(i=0; i<size; i++) array[i] = x2a->tbl[i].data;
         4728  +    for(i=0; i<arrSize; i++) array[i] = x2a->tbl[i].data;
  4731   4729     }
  4732   4730     return array;
  4733   4731   }
  4734   4732   
  4735   4733   /* Compare two configurations */
  4736   4734   int Configcmp(const char *_a,const char *_b)
  4737   4735   {
................................................................................
  4839   4837         /* Fail because overwrite is not allows. */
  4840   4838         return 0;
  4841   4839       }
  4842   4840       np = np->next;
  4843   4841     }
  4844   4842     if( x3a->count>=x3a->size ){
  4845   4843       /* Need to make the hash table bigger */
  4846         -    int i,size;
         4844  +    int i,arrSize;
  4847   4845       struct s_x3 array;
  4848         -    array.size = size = x3a->size*2;
         4846  +    array.size = arrSize = x3a->size*2;
  4849   4847       array.count = x3a->count;
  4850         -    array.tbl = (x3node*)calloc(size, sizeof(x3node) + sizeof(x3node*));
         4848  +    array.tbl = (x3node*)calloc(arrSize, sizeof(x3node) + sizeof(x3node*));
  4851   4849       if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
  4852         -    array.ht = (x3node**)&(array.tbl[size]);
  4853         -    for(i=0; i<size; i++) array.ht[i] = 0;
         4850  +    array.ht = (x3node**)&(array.tbl[arrSize]);
         4851  +    for(i=0; i<arrSize; i++) array.ht[i] = 0;
  4854   4852       for(i=0; i<x3a->count; i++){
  4855   4853         x3node *oldnp, *newnp;
  4856   4854         oldnp = &(x3a->tbl[i]);
  4857         -      h = statehash(oldnp->key) & (size-1);
         4855  +      h = statehash(oldnp->key) & (arrSize-1);
  4858   4856         newnp = &(array.tbl[i]);
  4859   4857         if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
  4860   4858         newnp->next = array.ht[h];
  4861   4859         newnp->key = oldnp->key;
  4862   4860         newnp->data = oldnp->data;
  4863   4861         newnp->from = &(array.ht[h]);
  4864   4862         array.ht[h] = newnp;
................................................................................
  4897   4895   
  4898   4896   /* Return an array of pointers to all data in the table.
  4899   4897   ** The array is obtained from malloc.  Return NULL if memory allocation
  4900   4898   ** problems, or if the array is empty. */
  4901   4899   struct state **State_arrayof()
  4902   4900   {
  4903   4901     struct state **array;
  4904         -  int i,size;
         4902  +  int i,arrSize;
  4905   4903     if( x3a==0 ) return 0;
  4906         -  size = x3a->count;
  4907         -  array = (struct state **)calloc(size, sizeof(struct state *));
         4904  +  arrSize = x3a->count;
         4905  +  array = (struct state **)calloc(arrSize, sizeof(struct state *));
  4908   4906     if( array ){
  4909         -    for(i=0; i<size; i++) array[i] = x3a->tbl[i].data;
         4907  +    for(i=0; i<arrSize; i++) array[i] = x3a->tbl[i].data;
  4910   4908     }
  4911   4909     return array;
  4912   4910   }
  4913   4911   
  4914   4912   /* Hash a configuration */
  4915   4913   PRIVATE unsigned confighash(struct config *a)
  4916   4914   {
................................................................................
  4979   4977         /* Fail because overwrite is not allows. */
  4980   4978         return 0;
  4981   4979       }
  4982   4980       np = np->next;
  4983   4981     }
  4984   4982     if( x4a->count>=x4a->size ){
  4985   4983       /* Need to make the hash table bigger */
  4986         -    int i,size;
         4984  +    int i,arrSize;
  4987   4985       struct s_x4 array;
  4988         -    array.size = size = x4a->size*2;
         4986  +    array.size = arrSize = x4a->size*2;
  4989   4987       array.count = x4a->count;
  4990         -    array.tbl = (x4node*)calloc(size, sizeof(x4node) + sizeof(x4node*));
         4988  +    array.tbl = (x4node*)calloc(arrSize, sizeof(x4node) + sizeof(x4node*));
  4991   4989       if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
  4992         -    array.ht = (x4node**)&(array.tbl[size]);
  4993         -    for(i=0; i<size; i++) array.ht[i] = 0;
         4990  +    array.ht = (x4node**)&(array.tbl[arrSize]);
         4991  +    for(i=0; i<arrSize; i++) array.ht[i] = 0;
  4994   4992       for(i=0; i<x4a->count; i++){
  4995   4993         x4node *oldnp, *newnp;
  4996   4994         oldnp = &(x4a->tbl[i]);
  4997         -      h = confighash(oldnp->data) & (size-1);
         4995  +      h = confighash(oldnp->data) & (arrSize-1);
  4998   4996         newnp = &(array.tbl[i]);
  4999   4997         if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
  5000   4998         newnp->next = array.ht[h];
  5001   4999         newnp->data = oldnp->data;
  5002   5000         newnp->from = &(array.ht[h]);
  5003   5001         array.ht[h] = newnp;
  5004   5002       }

Changes to tool/mkvsix.tcl.

   170    170     set file_id [open $fileName {WRONLY CREAT TRUNC}]
   171    171     fconfigure $file_id -encoding binary -translation binary
   172    172     puts -nonewline $file_id $data
   173    173     close $file_id
   174    174     return ""
   175    175   }
   176    176   
          177  +#
          178  +# TODO: Modify this procedure when a new version of Visual Studio is released.
          179  +#
   177    180   proc getMinVsVersionXmlChunk { vsVersion } {
   178    181     switch -exact $vsVersion {
   179    182       2012 {
   180    183         return [appendArgs \
   181    184             "\r\n    " {MinVSVersion="11.0"}]
   182    185       }
   183    186       2013 {
   184    187         return [appendArgs \
   185    188             "\r\n    " {MinVSVersion="12.0"}]
   186    189       }
          190  +    2015 {
          191  +      return [appendArgs \
          192  +          "\r\n    " {MinVSVersion="14.0"}]
          193  +    }
   187    194       default {
   188    195         return ""
   189    196       }
   190    197     }
   191    198   }
   192    199   
          200  +#
          201  +# TODO: Modify this procedure when a new version of Visual Studio is released.
          202  +#
   193    203   proc getMaxPlatformVersionXmlChunk { packageFlavor vsVersion } {
   194    204     #
   195         -  # NOTE: Only Visual Studio 2013 supports this SDK manifest attribute.
          205  +  # NOTE: Only Visual Studio 2013 and later support this attribute within the
          206  +  #       SDK manifest.
   196    207     #
   197         -  if {![string equal $vsVersion 2013]} then {
          208  +  if {![string equal $vsVersion 2013] && \
          209  +      ![string equal $vsVersion 2015]} then {
   198    210       return ""
   199    211     }
   200    212   
   201    213     switch -exact $packageFlavor {
   202    214       WinRT {
   203    215         return [appendArgs \
   204    216             "\r\n    " {MaxPlatformVersion="8.0"}]
................................................................................
   217    229       }
   218    230       default {
   219    231         return ""
   220    232       }
   221    233     }
   222    234   }
   223    235   
          236  +#
          237  +# TODO: Modify this procedure when a new version of Visual Studio is released.
          238  +#
   224    239   proc getExtraFileListXmlChunk { packageFlavor vsVersion } {
   225    240     #
   226    241     # NOTE: Windows Phone 8.0 does not require any extra attributes in its VSIX
   227    242     #       package SDK manifests; however, it appears that Windows Phone 8.1
   228    243     #       does.
   229    244     #
   230    245     if {[string equal $packageFlavor WP80]} then {
................................................................................
   241    256             "\r\n    " {DependsOn="Microsoft.VCLibs, version=11.0"}]
   242    257       }
   243    258       2013 {
   244    259         return [appendArgs \
   245    260             "\r\n    " AppliesTo=\" $appliesTo \" \
   246    261             "\r\n    " {DependsOn="Microsoft.VCLibs, version=12.0"}]
   247    262       }
          263  +    2015 {
          264  +      #
          265  +      # TODO: Is the ".AppLocal" suffix always needed here?
          266  +      #
          267  +      return [appendArgs \
          268  +          "\r\n    " AppliesTo=\" $appliesTo \" \
          269  +          "\r\n    " {DependsOn="Microsoft.VCLibs.AppLocal, version=14.0"}]
          270  +    }
   248    271       default {
   249    272         return ""
   250    273       }
   251    274     }
   252    275   }
   253    276   
   254    277   proc replaceFileNameTokens { fileName name buildName platformName } {
................................................................................
   350    373     set vsVersion 2012
   351    374   }
   352    375   
   353    376   if {[string length $vsVersion] == 0} then {
   354    377     fail "invalid Visual Studio version"
   355    378   }
   356    379   
   357         -if {![string equal $vsVersion 2012] && ![string equal $vsVersion 2013]} then {
          380  +if {![string equal $vsVersion 2012] && ![string equal $vsVersion 2013] && \
          381  +    ![string equal $vsVersion 2015]} then {
   358    382     fail [appendArgs \
   359    383         "unsupported Visual Studio version, must be one of: " \
   360         -      [list 2012 2013]]
          384  +      [list 2012 2013 2015]]
   361    385   }
   362    386   
   363    387   set shortNames(WinRT,2012) SQLite.WinRT
   364    388   set shortNames(WinRT,2013) SQLite.WinRT.2013
   365    389   set shortNames(WinRT81,2013) SQLite.WinRT81
   366    390   set shortNames(WP80,2012) SQLite.WP80
   367    391   set shortNames(WP80,2013) SQLite.WP80.2013
   368    392   set shortNames(WP81,2013) SQLite.WP81
   369    393   set shortNames(Win32,2012) SQLite.Win32
   370    394   set shortNames(Win32,2013) SQLite.Win32.2013
          395  +set shortNames(UAP,2015) SQLite.UAP.2015
   371    396   
   372    397   set displayNames(WinRT,2012) "SQLite for Windows Runtime"
   373    398   set displayNames(WinRT,2013) "SQLite for Windows Runtime"
   374    399   set displayNames(WinRT81,2013) "SQLite for Windows Runtime (Windows 8.1)"
   375    400   set displayNames(WP80,2012) "SQLite for Windows Phone"
   376    401   set displayNames(WP80,2013) "SQLite for Windows Phone"
   377    402   set displayNames(WP81,2013) "SQLite for Windows Phone 8.1"
   378    403   set displayNames(Win32,2012) "SQLite for Windows"
   379    404   set displayNames(Win32,2013) "SQLite for Windows"
          405  +set displayNames(UAP,2015) "SQLite for Universal App Platform"
   380    406   
   381    407   if {[string equal $packageFlavor WinRT]} then {
   382    408     set shortName $shortNames($packageFlavor,$vsVersion)
   383    409     set displayName $displayNames($packageFlavor,$vsVersion)
   384    410     set targetPlatformIdentifier Windows
   385    411     set targetPlatformVersion v8.0
   386    412     set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
................................................................................
   426    452     set displayName $displayNames($packageFlavor,$vsVersion)
   427    453     set targetPlatformIdentifier WindowsPhoneApp
   428    454     set targetPlatformVersion v8.1
   429    455     set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
   430    456     set maxPlatformVersion \
   431    457         [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
   432    458     set extraSdkPath "\\..\\$targetPlatformIdentifier"
          459  +  set extraFileListAttributes \
          460  +      [getExtraFileListXmlChunk $packageFlavor $vsVersion]
          461  +} elseif {[string equal $packageFlavor UAP]} then {
          462  +  if {$vsVersion ne "2015"} then {
          463  +    fail [appendArgs \
          464  +        "unsupported combination, package flavor " $packageFlavor \
          465  +        " is only supported with Visual Studio 2015"]
          466  +  }
          467  +  set shortName $shortNames($packageFlavor,$vsVersion)
          468  +  set displayName $displayNames($packageFlavor,$vsVersion)
          469  +  set targetPlatformIdentifier UAP
          470  +  set targetPlatformVersion v0.8.0.0
          471  +  set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
          472  +  set maxPlatformVersion \
          473  +      [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
          474  +  set extraSdkPath "\\..\\$targetPlatformIdentifier"
   433    475     set extraFileListAttributes \
   434    476         [getExtraFileListXmlChunk $packageFlavor $vsVersion]
   435    477   } elseif {[string equal $packageFlavor Win32]} then {
   436    478     set shortName $shortNames($packageFlavor,$vsVersion)
   437    479     set displayName $displayNames($packageFlavor,$vsVersion)
   438    480     set targetPlatformIdentifier Windows
   439    481     set targetPlatformVersion v8.0
................................................................................
   442    484         [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
   443    485     set extraSdkPath ""
   444    486     set extraFileListAttributes \
   445    487         [getExtraFileListXmlChunk $packageFlavor $vsVersion]
   446    488   } else {
   447    489     fail [appendArgs \
   448    490         "unsupported package flavor, must be one of: " \
   449         -      [list WinRT WinRT81 WP80 WP81 Win32]]
          491  +      [list WinRT WinRT81 WP80 WP81 UAP Win32]]
   450    492   }
   451    493   
   452    494   ###############################################################################
   453    495   
   454    496   #
   455    497   # NOTE: Evaluate the user-specific customizations file, if it exists.
   456    498   #