/ Check-in [c5ab4378]
Login

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

Overview
Comment:Merge updates from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | winHdr
Files: files | file ages | folders
SHA1:c5ab4378756965b0c2ab218e5ec59c40898b89ea
User & Date: mistachkin 2013-11-26 00:33:25
Context
2013-11-26
01:00
Further work on Windows header file reform. check-in: 540f5525 user: mistachkin tags: winHdr
00:33
Merge updates from trunk. check-in: c5ab4378 user: mistachkin tags: winHdr
00:28
Better support for UTF-8 paths on Cygwin. check-in: 9954327c user: mistachkin tags: trunk
2013-11-25
09:37
Correct line-endings in the new header file. check-in: 94219b9f user: mistachkin tags: winHdr
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  4215   4215     u32 nLocal;
  4216   4216   
  4217   4217     assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
  4218   4218     assert( pCur->eState==CURSOR_VALID );
  4219   4219     assert( cursorHoldsMutex(pCur) );
  4220   4220     pPage = pCur->apPage[pCur->iPage];
  4221   4221     assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  4222         -  if( NEVER(pCur->info.nSize==0) ){
         4222  +  if( pCur->info.nSize==0 ){
  4223   4223       btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
  4224   4224                      &pCur->info);
  4225   4225     }
  4226   4226     aPayload = pCur->info.pCell;
  4227   4227     aPayload += pCur->info.nHeader;
  4228   4228     if( pPage->intKey ){
  4229   4229       nKey = 0;
................................................................................
  4643   4643     if( pCur->eState==CURSOR_INVALID ){
  4644   4644       *pRes = -1;
  4645   4645       assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
  4646   4646       return SQLITE_OK;
  4647   4647     }
  4648   4648     assert( pCur->apPage[0]->intKey || pIdxKey );
  4649   4649     for(;;){
  4650         -    int lwr, upr, idx;
         4650  +    int lwr, upr, idx, c;
  4651   4651       Pgno chldPg;
  4652   4652       MemPage *pPage = pCur->apPage[pCur->iPage];
  4653         -    int c;
         4653  +    u8 *pCell;                          /* Pointer to current cell in pPage */
  4654   4654   
  4655   4655       /* pPage->nCell must be greater than zero. If this is the root-page
  4656   4656       ** the cursor would have been INVALID above and this for(;;) loop
  4657   4657       ** not run. If this is not the root-page, then the moveToChild() routine
  4658   4658       ** would have already detected db corruption. Similarly, pPage must
  4659   4659       ** be the right kind (index or table) of b-tree page. Otherwise
  4660   4660       ** a moveToChild() or moveToRoot() call would have detected corruption.  */
  4661   4661       assert( pPage->nCell>0 );
  4662   4662       assert( pPage->intKey==(pIdxKey==0) );
  4663   4663       lwr = 0;
  4664   4664       upr = pPage->nCell-1;
  4665         -    if( biasRight ){
  4666         -      pCur->aiIdx[pCur->iPage] = (u16)(idx = upr);
  4667         -    }else{
  4668         -      pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2);
  4669         -    }
  4670         -    for(;;){
  4671         -      u8 *pCell;                          /* Pointer to current cell in pPage */
  4672         -
  4673         -      assert( idx==pCur->aiIdx[pCur->iPage] );
  4674         -      pCur->info.nSize = 0;
  4675         -      pCell = findCell(pPage, idx) + pPage->childPtrSize;
  4676         -      if( pPage->intKey ){
         4665  +    assert( biasRight==0 || biasRight==1 );
         4666  +    idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
         4667  +    pCur->aiIdx[pCur->iPage] = (u16)idx;
         4668  +    if( pPage->intKey ){
         4669  +      for(;;){
  4677   4670           i64 nCellKey;
         4671  +        pCell = findCell(pPage, idx) + pPage->childPtrSize;
  4678   4672           if( pPage->hasData ){
  4679         -          u32 dummy;
  4680         -          pCell += getVarint32(pCell, dummy);
         4673  +          while( 0x80 <= *(pCell++) ){
         4674  +            if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
         4675  +          }
  4681   4676           }
  4682   4677           getVarint(pCell, (u64*)&nCellKey);
  4683         -        if( nCellKey==intKey ){
  4684         -          c = 0;
  4685         -        }else if( nCellKey<intKey ){
  4686         -          c = -1;
         4678  +        if( nCellKey<intKey ){
         4679  +          lwr = idx+1;
         4680  +          if( lwr>upr ){ c = -1; break; }
         4681  +        }else if( nCellKey>intKey ){
         4682  +          upr = idx-1;
         4683  +          if( lwr>upr ){ c = +1; break; }
  4687   4684           }else{
  4688         -          assert( nCellKey>intKey );
  4689         -          c = +1;
         4685  +          assert( nCellKey==intKey );
         4686  +          pCur->validNKey = 1;
         4687  +          pCur->info.nKey = nCellKey;
         4688  +          pCur->aiIdx[pCur->iPage] = (u16)idx;
         4689  +          if( !pPage->leaf ){
         4690  +            lwr = idx;
         4691  +            goto moveto_next_layer;
         4692  +          }else{
         4693  +            *pRes = 0;
         4694  +            rc = SQLITE_OK;
         4695  +            goto moveto_finish;
         4696  +          }
  4690   4697           }
  4691         -        pCur->validNKey = 1;
  4692         -        pCur->info.nKey = nCellKey;
  4693         -      }else{
         4698  +        assert( lwr+upr>=0 );
         4699  +        idx = (lwr+upr)>>1;  /* idx = (lwr+upr)/2; */
         4700  +      }
         4701  +    }else{
         4702  +      for(;;){
         4703  +        int nCell;
         4704  +        pCell = findCell(pPage, idx) + pPage->childPtrSize;
         4705  +
  4694   4706           /* The maximum supported page-size is 65536 bytes. This means that
  4695   4707           ** the maximum number of record bytes stored on an index B-Tree
  4696   4708           ** page is less than 16384 bytes and may be stored as a 2-byte
  4697   4709           ** varint. This information is used to attempt to avoid parsing 
  4698   4710           ** the entire cell by checking for the cases where the record is 
  4699   4711           ** stored entirely within the b-tree page by inspecting the first 
  4700   4712           ** 2 bytes of the cell.
  4701   4713           */
  4702         -        int nCell = pCell[0];
         4714  +        nCell = pCell[0];
  4703   4715           if( nCell<=pPage->max1bytePayload
  4704   4716            /* && (pCell+nCell)<pPage->aDataEnd */
  4705   4717           ){
  4706   4718             /* This branch runs if the record-size field of the cell is a
  4707   4719             ** single byte varint and the record fits entirely on the main
  4708   4720             ** b-tree page.  */
  4709   4721             testcase( pCell+nCell+1==pPage->aDataEnd );
................................................................................
  4726   4738             btreeParseCellPtr(pPage, pCellBody, &pCur->info);
  4727   4739             nCell = (int)pCur->info.nKey;
  4728   4740             pCellKey = sqlite3Malloc( nCell );
  4729   4741             if( pCellKey==0 ){
  4730   4742               rc = SQLITE_NOMEM;
  4731   4743               goto moveto_finish;
  4732   4744             }
         4745  +          pCur->aiIdx[pCur->iPage] = (u16)idx;
  4733   4746             rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
  4734   4747             if( rc ){
  4735   4748               sqlite3_free(pCellKey);
  4736   4749               goto moveto_finish;
  4737   4750             }
  4738   4751             c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
  4739   4752             sqlite3_free(pCellKey);
  4740   4753           }
  4741         -      }
  4742         -      if( c==0 ){
  4743         -        if( pPage->intKey && !pPage->leaf ){
  4744         -          lwr = idx;
  4745         -          break;
         4754  +        if( c<0 ){
         4755  +          lwr = idx+1;
         4756  +        }else if( c>0 ){
         4757  +          upr = idx-1;
  4746   4758           }else{
         4759  +          assert( c==0 );
  4747   4760             *pRes = 0;
  4748   4761             rc = SQLITE_OK;
         4762  +          pCur->aiIdx[pCur->iPage] = (u16)idx;
  4749   4763             goto moveto_finish;
  4750   4764           }
         4765  +        if( lwr>upr ) break;
         4766  +        assert( lwr+upr>=0 );
         4767  +        idx = (lwr+upr)>>1;  /* idx = (lwr+upr)/2 */
  4751   4768         }
  4752         -      if( c<0 ){
  4753         -        lwr = idx+1;
  4754         -      }else{
  4755         -        upr = idx-1;
  4756         -      }
  4757         -      if( lwr>upr ){
  4758         -        break;
  4759         -      }
  4760         -      pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
  4761   4769       }
  4762   4770       assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
  4763   4771       assert( pPage->isInit );
  4764   4772       if( pPage->leaf ){
  4765         -      chldPg = 0;
  4766         -    }else if( lwr>=pPage->nCell ){
  4767         -      chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
  4768         -    }else{
  4769         -      chldPg = get4byte(findCell(pPage, lwr));
  4770         -    }
  4771         -    if( chldPg==0 ){
  4772   4773         assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
         4774  +      pCur->aiIdx[pCur->iPage] = (u16)idx;
  4773   4775         *pRes = c;
  4774   4776         rc = SQLITE_OK;
  4775   4777         goto moveto_finish;
  4776   4778       }
         4779  +moveto_next_layer:
         4780  +    if( lwr>=pPage->nCell ){
         4781  +      chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
         4782  +    }else{
         4783  +      chldPg = get4byte(findCell(pPage, lwr));
         4784  +    }
  4777   4785       pCur->aiIdx[pCur->iPage] = (u16)lwr;
  4778         -    pCur->info.nSize = 0;
  4779         -    pCur->validNKey = 0;
  4780   4786       rc = moveToChild(pCur, chldPg);
  4781         -    if( rc ) goto moveto_finish;
         4787  +    if( rc ) break;
  4782   4788     }
  4783   4789   moveto_finish:
         4790  +  pCur->info.nSize = 0;
         4791  +  pCur->validNKey = 0;
  4784   4792     return rc;
  4785   4793   }
  4786   4794   
  4787   4795   
  4788   4796   /*
  4789   4797   ** Return TRUE if the cursor is not pointing at an entry of the table.
  4790   4798   **

Changes to src/main.c.

   510    510         }
   511    511         sqlite3GlobalConfig.mxMmap = mxMmap;
   512    512         if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
   513    513         if( szMmap>mxMmap) szMmap = mxMmap;
   514    514         sqlite3GlobalConfig.szMmap = szMmap;
   515    515         break;
   516    516       }
          517  +
          518  +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC)
          519  +    case SQLITE_CONFIG_WIN32_HEAPSIZE: {
          520  +      sqlite3GlobalConfig.nHeap = va_arg(ap, int);
          521  +      break;
          522  +    }
          523  +#endif
   517    524   
   518    525       default: {
   519    526         rc = SQLITE_ERROR;
   520    527         break;
   521    528       }
   522    529     }
   523    530     va_end(ap);

Changes to src/os_win.c.

  1397   1397   
  1398   1398     if( !pWinMemData ) return SQLITE_ERROR;
  1399   1399     assert( pWinMemData->magic1==WINMEM_MAGIC1 );
  1400   1400     assert( pWinMemData->magic2==WINMEM_MAGIC2 );
  1401   1401   
  1402   1402   #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
  1403   1403     if( !pWinMemData->hHeap ){
         1404  +    DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
         1405  +    DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
         1406  +    if( dwMaximumSize==0 ){
         1407  +      dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
         1408  +    }else if( dwInitialSize>dwMaximumSize ){
         1409  +      dwInitialSize = dwMaximumSize;
         1410  +    }
  1404   1411       pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
  1405         -                                      SQLITE_WIN32_HEAP_INIT_SIZE,
  1406         -                                      SQLITE_WIN32_HEAP_MAX_SIZE);
         1412  +                                      dwInitialSize, dwMaximumSize);
  1407   1413       if( !pWinMemData->hHeap ){
  1408   1414         sqlite3_log(SQLITE_NOMEM,
  1409         -          "failed to HeapCreate (%lu), flags=%u, initSize=%u, maxSize=%u",
  1410         -          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
  1411         -          SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
         1415  +          "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
         1416  +          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
         1417  +          dwMaximumSize);
  1412   1418         return SQLITE_NOMEM;
  1413   1419       }
  1414   1420       pWinMemData->bOwned = TRUE;
  1415   1421       assert( pWinMemData->bOwned );
  1416   1422     }
  1417   1423   #else
  1418   1424     pWinMemData->hHeap = osGetProcessHeap();
................................................................................
  4064   4070   /****************************************************************************
  4065   4071   **************************** sqlite3_vfs methods ****************************
  4066   4072   **
  4067   4073   ** This division contains the implementation of methods on the
  4068   4074   ** sqlite3_vfs object.
  4069   4075   */
  4070   4076   
  4071         -#if 0
         4077  +#if defined(__CYGWIN__)
  4072   4078   /*
  4073   4079   ** Convert a filename from whatever the underlying operating system
  4074   4080   ** supports for filenames into UTF-8.  Space to hold the result is
  4075   4081   ** obtained from malloc and must be freed by the calling function.
  4076   4082   */
  4077   4083   static char *winConvertToUtf8Filename(const void *zFilename){
  4078   4084     char *zConverted = 0;
................................................................................
  4240   4246                                "winGetTempname2", zDir);
  4241   4247           }
  4242   4248           if( winIsDir(zConverted) ){
  4243   4249             /* At this point, we know the candidate directory exists and should
  4244   4250             ** be used.  However, we may need to convert the string containing
  4245   4251             ** its name into UTF-8 (i.e. if it is UTF-16 right now).
  4246   4252             */
  4247         -          if( osIsNT() ){
  4248         -            char *zUtf8 = winUnicodeToUtf8(zConverted);
  4249         -            if( !zUtf8 ){
  4250         -              sqlite3_free(zConverted);
  4251         -              sqlite3_free(zBuf);
  4252         -              OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4253         -              return SQLITE_IOERR_NOMEM;
  4254         -            }
  4255         -            sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
  4256         -            sqlite3_free(zUtf8);
         4253  +          char *zUtf8 = winConvertToUtf8Filename(zConverted);
         4254  +          if( !zUtf8 ){
  4257   4255               sqlite3_free(zConverted);
  4258         -            break;
  4259         -          }else{
  4260         -            sqlite3_snprintf(nMax, zBuf, "%s", zConverted);
  4261         -            sqlite3_free(zConverted);
  4262         -            break;
         4256  +            sqlite3_free(zBuf);
         4257  +            OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
         4258  +            return SQLITE_IOERR_NOMEM;
  4263   4259             }
         4260  +          sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
         4261  +          sqlite3_free(zUtf8);
         4262  +          sqlite3_free(zConverted);
         4263  +          break;
  4264   4264           }
  4265   4265           sqlite3_free(zConverted);
  4266   4266         }
  4267   4267       }
  4268   4268     }
  4269   4269   #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  4270   4270     else if( osIsNT() ){
................................................................................
  4941   4941       **       for converting the relative path name to an absolute
  4942   4942       **       one by prepending the data directory and a slash.
  4943   4943       */
  4944   4944       char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
  4945   4945       if( !zOut ){
  4946   4946         return SQLITE_IOERR_NOMEM;
  4947   4947       }
  4948         -    if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
  4949         -                         pVfs->mxPathname+1)<0 ){
         4948  +    if( cygwin_conv_path(
         4949  +            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
         4950  +            CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
  4950   4951         sqlite3_free(zOut);
  4951   4952         return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
  4952   4953                            "winFullPathname1", zRelative);
         4954  +    }else{
         4955  +      char *zUtf8 = winConvertToUtf8Filename(zOut);
         4956  +      if( !zUtf8 ){
         4957  +        sqlite3_free(zOut);
         4958  +        return SQLITE_IOERR_NOMEM;
         4959  +      }
         4960  +      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
         4961  +                       sqlite3_data_directory, winGetDirSep(), zUtf8);
         4962  +      sqlite3_free(zUtf8);
         4963  +      sqlite3_free(zOut);
  4953   4964       }
  4954         -    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
  4955         -                     sqlite3_data_directory, winGetDirSep(), zOut);
  4956         -    sqlite3_free(zOut);
  4957   4965     }else{
  4958         -    if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
         4966  +    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
         4967  +    if( !zOut ){
         4968  +      return SQLITE_IOERR_NOMEM;
         4969  +    }
         4970  +    if( cygwin_conv_path(
         4971  +            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
         4972  +            zRelative, zOut, pVfs->mxPathname+1)<0 ){
         4973  +      sqlite3_free(zOut);
  4959   4974         return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
  4960   4975                            "winFullPathname2", zRelative);
         4976  +    }else{
         4977  +      char *zUtf8 = winConvertToUtf8Filename(zOut);
         4978  +      if( !zUtf8 ){
         4979  +        sqlite3_free(zOut);
         4980  +        return SQLITE_IOERR_NOMEM;
         4981  +      }
         4982  +      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
         4983  +      sqlite3_free(zUtf8);
         4984  +      sqlite3_free(zOut);
  4961   4985       }
  4962   4986     }
  4963   4987     return SQLITE_OK;
  4964   4988   #endif
  4965   4989   
  4966   4990   #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
  4967   4991     SimulateIOError( return SQLITE_ERROR );

Changes to src/sqlite.h.in.

  1678   1678   ** either the [PRAGMA mmap_size] command, or by using the
  1679   1679   ** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
  1680   1680   ** cannot be changed at run-time.  Nor may the maximum allowed mmap size
  1681   1681   ** exceed the compile-time maximum mmap size set by the
  1682   1682   ** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
  1683   1683   ** ^If either argument to this option is negative, then that argument is
  1684   1684   ** changed to its compile-time default.
         1685  +**
         1686  +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
         1687  +** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
         1688  +** <dd>^This option is only available if SQLite is compiled for Windows
         1689  +** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
         1690  +** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
         1691  +** that specifies the maximum size of the created heap.
  1685   1692   ** </dl>
  1686   1693   */
  1687   1694   #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
  1688   1695   #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
  1689   1696   #define SQLITE_CONFIG_SERIALIZED    3  /* nil */
  1690   1697   #define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
  1691   1698   #define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
................................................................................
  1702   1709   #define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
  1703   1710   #define SQLITE_CONFIG_URI          17  /* int */
  1704   1711   #define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
  1705   1712   #define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
  1706   1713   #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
  1707   1714   #define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
  1708   1715   #define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
         1716  +#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
  1709   1717   
  1710   1718   /*
  1711   1719   ** CAPI3REF: Database Connection Configuration Options
  1712   1720   **
  1713   1721   ** These constants are the available integer configuration options that
  1714   1722   ** can be passed as the second argument to the [sqlite3_db_config()] interface.
  1715   1723   **

Changes to src/test_config.c.

    58     58   #endif
    59     59   
    60     60   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
    61     61     Tcl_SetVar2(interp, "sqlite_options", "curdir", "1", TCL_GLOBAL_ONLY);
    62     62   #else
    63     63     Tcl_SetVar2(interp, "sqlite_options", "curdir", "0", TCL_GLOBAL_ONLY);
    64     64   #endif
           65  +
           66  +#ifdef SQLITE_WIN32_MALLOC
           67  +  Tcl_SetVar2(interp, "sqlite_options", "win32malloc", "1", TCL_GLOBAL_ONLY);
           68  +#else
           69  +  Tcl_SetVar2(interp, "sqlite_options", "win32malloc", "0", TCL_GLOBAL_ONLY);
           70  +#endif
    65     71   
    66     72   #ifdef SQLITE_DEBUG
    67     73     Tcl_SetVar2(interp, "sqlite_options", "debug", "1", TCL_GLOBAL_ONLY);
    68     74   #else
    69     75     Tcl_SetVar2(interp, "sqlite_options", "debug", "0", TCL_GLOBAL_ONLY);
    70     76   #endif
    71     77   

Changes to src/test_malloc.c.

  1125   1125       zBuf = realloc(zBuf, nByte);
  1126   1126       rc = sqlite3_config(SQLITE_CONFIG_HEAP, zBuf, nByte, nMinAlloc);
  1127   1127     }
  1128   1128   
  1129   1129     Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
  1130   1130     return TCL_OK;
  1131   1131   }
         1132  +
         1133  +/*
         1134  +** Usage:    sqlite3_config_heap_size NBYTE
         1135  +*/
         1136  +static int test_config_heap_size(
         1137  +  void * clientData, 
         1138  +  Tcl_Interp *interp,
         1139  +  int objc,
         1140  +  Tcl_Obj *CONST objv[]
         1141  +){
         1142  +  int nByte;         /* Size to pass to sqlite3_config() */
         1143  +  int rc;            /* Return code of sqlite3_config() */
         1144  +
         1145  +  Tcl_Obj * CONST *aArg = &objv[1];
         1146  +  int nArg = objc-1;
         1147  +
         1148  +  if( nArg!=1 ){
         1149  +    Tcl_WrongNumArgs(interp, 1, objv, "NBYTE");
         1150  +    return TCL_ERROR;
         1151  +  }
         1152  +  if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR;
         1153  +
         1154  +  rc = sqlite3_config(SQLITE_CONFIG_WIN32_HEAPSIZE, nByte);
         1155  +
         1156  +  Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
         1157  +  return TCL_OK;
         1158  +}
  1132   1159   
  1133   1160   /*
  1134   1161   ** Usage:    sqlite3_config_error  [DB]
  1135   1162   **
  1136   1163   ** Invoke sqlite3_config() or sqlite3_db_config() with invalid
  1137   1164   ** opcodes and verify that they return errors.
  1138   1165   */
................................................................................
  1469   1496        { "sqlite3_config_scratch",     test_config_scratch           ,0 },
  1470   1497        { "sqlite3_config_pagecache",   test_config_pagecache         ,0 },
  1471   1498        { "sqlite3_config_alt_pcache",  test_alt_pcache               ,0 },
  1472   1499        { "sqlite3_status",             test_status                   ,0 },
  1473   1500        { "sqlite3_db_status",          test_db_status                ,0 },
  1474   1501        { "install_malloc_faultsim",    test_install_malloc_faultsim  ,0 },
  1475   1502        { "sqlite3_config_heap",        test_config_heap              ,0 },
         1503  +     { "sqlite3_config_heap_size",   test_config_heap_size         ,0 },
  1476   1504        { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
  1477   1505        { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
  1478   1506        { "sqlite3_config_error",       test_config_error             ,0 },
  1479   1507        { "sqlite3_config_uri",         test_config_uri               ,0 },
  1480   1508        { "sqlite3_config_cis",         test_config_cis               ,0 },
  1481   1509        { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
  1482   1510        { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },

Changes to src/vdbe.c.

  4071   4071       nZero = pData->u.nZero;
  4072   4072     }else{
  4073   4073       nZero = 0;
  4074   4074     }
  4075   4075     sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
  4076   4076     rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
  4077   4077                             pData->z, pData->n, nZero,
  4078         -                          pOp->p5 & OPFLAG_APPEND, seekResult
         4078  +                          (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
  4079   4079     );
  4080   4080     pC->rowidIsValid = 0;
  4081   4081     pC->deferredMoveto = 0;
  4082   4082     pC->cacheStatus = CACHE_STALE;
  4083   4083   
  4084   4084     /* Invoke the update-hook if required. */
  4085   4085     if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){

Changes to src/vdbeaux.c.

  3110   3110     */
  3111   3111     /*  mem1.u.i = 0;  // not needed, here to silence compiler warning */
  3112   3112     
  3113   3113     idx1 = getVarint32(aKey1, szHdr1);
  3114   3114     d1 = szHdr1;
  3115   3115     assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField );
  3116   3116     assert( pKeyInfo->aSortOrder!=0 );
  3117         -  while( idx1<szHdr1 && i<pPKey2->nField ){
         3117  +  assert( idx1<szHdr1 && i<pPKey2->nField );
         3118  +  do{
  3118   3119       u32 serial_type1;
  3119   3120   
  3120   3121       /* Read the serial types for the next element in each key. */
  3121   3122       idx1 += getVarint32( aKey1+idx1, serial_type1 );
  3122   3123   
  3123   3124       /* Verify that there is enough key space remaining to avoid
  3124   3125       ** a buffer overread.  The "d1+serial_type1+2" subexpression will
................................................................................
  3143   3144         assert( mem1.zMalloc==0 );  /* See comment below */
  3144   3145         if( pKeyInfo->aSortOrder[i] ){
  3145   3146           rc = -rc;  /* Invert the result for DESC sort order. */
  3146   3147         }
  3147   3148         return rc;
  3148   3149       }
  3149   3150       i++;
  3150         -  }
         3151  +  }while( idx1<szHdr1 && i<pPKey2->nField );
  3151   3152   
  3152   3153     /* No memory allocation is ever used on mem1.  Prove this using
  3153   3154     ** the following assert().  If the assert() fails, it indicates a
  3154   3155     ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
  3155   3156     */
  3156   3157     assert( mem1.zMalloc==0 );
  3157   3158   

Added test/win32heap.test.

            1  +# 2013 November 22
            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 recovery from transient manditory locks
           13  +# that sometimes appear on database files due to anti-virus software.
           14  +#
           15  +
           16  +if {$tcl_platform(platform)!="windows"} return
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +
           21  +ifcapable !win32malloc {
           22  +  finish_test
           23  +  return
           24  +}
           25  +
           26  +set testprefix win32heap
           27  +
           28  +do_test 1.1 {
           29  +  catch {db close}
           30  +  sqlite3_shutdown
           31  +  sqlite3_config_heap_size 1048576
           32  +  sqlite3_initialize
           33  +} {SQLITE_OK}
           34  +
           35  +do_test 1.2 {
           36  +  sqlite3 db test.db
           37  +  catchsql {
           38  +    CREATE TABLE t1(x);
           39  +  }
           40  +} {0 {}}
           41  +
           42  +do_test 1.3 {
           43  +  catchsql {
           44  +    INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576));
           45  +  }
           46  +} {1 {out of memory}}
           47  +
           48  +do_test 1.4 {
           49  +  catchsql {
           50  +    SELECT COUNT(*) FROM t1;
           51  +  }
           52  +} {0 0}
           53  +
           54  +do_test 1.5 {
           55  +  catch {db close}
           56  +  sqlite3_shutdown
           57  +  sqlite3_config_heap_size 0
           58  +  sqlite3_initialize
           59  +} {SQLITE_OK}
           60  +
           61  +do_test 1.6 {
           62  +  sqlite3 db test.db
           63  +  catchsql {
           64  +    INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576));
           65  +  }
           66  +} {0 {}}
           67  +
           68  +do_test 1.7 {
           69  +  catchsql {
           70  +    SELECT COUNT(*) FROM t1;
           71  +  }
           72  +} {0 1}
           73  +
           74  +finish_test