/ Check-in [39dd67af]
Login

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

Overview
Comment:Correctly interpret negative "PRAGMA cache_size" values when determining the cache-size used for sorting large amounts of data (i.e. the functionality in vdbesort.c).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | branch-3.12.0
Files: files | file ages | folders
SHA1: 39dd67afa508aea8f41387806b263b760512377f
User & Date: drh 2016-04-18 16:18:13
Context
2016-04-18
17:30
Version 3.12.2 Leaf check-in: 92dc59fd user: drh tags: release, branch-3.12.0, version-3.12.2
16:18
Correctly interpret negative "PRAGMA cache_size" values when determining the cache-size used for sorting large amounts of data (i.e. the functionality in vdbesort.c). check-in: 39dd67af user: drh tags: branch-3.12.0
16:12
Fix a problem in the code generator for joins on virtual tables where the outer loop of the join uses the IN operator. check-in: a2cf4968 user: drh tags: branch-3.12.0
2016-04-14
15:44
Correctly interpret negative "PRAGMA cache_size" values when determining the cache-size used for sorting large amounts of data (i.e. the functionality in vdbesort.c). check-in: 79147dca user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbesort.c.

   927    927   int sqlite3VdbeSorterInit(
   928    928     sqlite3 *db,                    /* Database connection (for malloc()) */
   929    929     int nField,                     /* Number of key fields in each record */
   930    930     VdbeCursor *pCsr                /* Cursor that holds the new sorter */
   931    931   ){
   932    932     int pgsz;                       /* Page size of main database */
   933    933     int i;                          /* Used to iterate through aTask[] */
   934         -  int mxCache;                    /* Cache size */
   935    934     VdbeSorter *pSorter;            /* The new sorter */
   936    935     KeyInfo *pKeyInfo;              /* Copy of pCsr->pKeyInfo with db==0 */
   937    936     int szKeyInfo;                  /* Size of pCsr->pKeyInfo in bytes */
   938    937     int sz;                         /* Size of pSorter in bytes */
   939    938     int rc = SQLITE_OK;
   940    939   #if SQLITE_MAX_WORKER_THREADS==0
   941    940   # define nWorker 0
................................................................................
   984    983       pSorter->db = db;
   985    984       for(i=0; i<pSorter->nTask; i++){
   986    985         SortSubtask *pTask = &pSorter->aTask[i];
   987    986         pTask->pSorter = pSorter;
   988    987       }
   989    988   
   990    989       if( !sqlite3TempInMemory(db) ){
          990  +      i64 mxCache;                /* Cache size in bytes*/
   991    991         u32 szPma = sqlite3GlobalConfig.szPma;
   992    992         pSorter->mnPmaSize = szPma * pgsz;
          993  +
   993    994         mxCache = db->aDb[0].pSchema->cache_size;
   994         -      if( mxCache<(int)szPma ) mxCache = (int)szPma;
   995         -      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
          995  +      if( mxCache<0 ){
          996  +        /* A negative cache-size value C indicates that the cache is abs(C)
          997  +        ** KiB in size.  */
          998  +        mxCache = mxCache * -1024;
          999  +      }else{
         1000  +        mxCache = mxCache * pgsz;
         1001  +      }
         1002  +      mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
         1003  +      pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
   996   1004   
   997   1005         /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
   998   1006         ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
   999   1007         ** large heap allocations.
  1000   1008         */
  1001   1009         if( sqlite3GlobalConfig.pScratch==0 ){
  1002   1010           assert( pSorter->iMemory==0 );

Changes to test/sort5.test.

    37     37   
    38     38   do_execsql_test 1.2 {
    39     39     CREATE INDEX i1 ON t1(b);
    40     40   }
    41     41   
    42     42   db close
    43     43   tvfs delete
           44  +
           45  +#-------------------------------------------------------------------------
           46  +# Test that the PMA size is determined correctly. The PMA size should be
           47  +# roughly the same amount of memory allocated to the main pager cache, or
           48  +# 250 pages if this is larger.
           49  +#
           50  +testvfs tvfs
           51  +tvfs script tv_callback
           52  +tvfs filter {xOpen xWrite}
           53  +
           54  +proc tv_callback {method args} {
           55  +  global iTemp
           56  +  global F
           57  +  switch $method {
           58  +    xOpen {
           59  +      if {[lindex $args 0]==""} { return "temp[incr iTemp]" }
           60  +      return "SQLITE_OK"
           61  +    }
           62  +
           63  +    xWrite {
           64  +      foreach {filename id off amt} $args {}
           65  +      if {[info exists F($id)]==0 || $F($id)<($off + $amt)} {
           66  +        set F($id) [expr $off+$amt]
           67  +      }
           68  +    }
           69  +  }
           70  +}
           71  +
           72  +catch { db close }
           73  +forcedelete test.db
           74  +sqlite3 db test.db -vfs tvfs
           75  +execsql { CREATE TABLE t1(x) }
           76  +
           77  +# Each iteration of the following loop attempts to sort 10001 records
           78  +# each a bit over 100 bytes in size. In total a little more than 1MiB 
           79  +# of data.
           80  +#
           81  +breakpoint
           82  +foreach {tn pgsz cachesz bTemp} {
           83  +  2 1024   1000  1
           84  +
           85  +  1 4096   1000  0
           86  +  2 1024   1000  1
           87  +
           88  +  3 4096  -1000  1
           89  +  4 1024  -1000  1
           90  +
           91  +  5 4096  -9000  0
           92  +  6 1024  -9000  0
           93  +} {
           94  +  do_execsql_test 2.$tn.0 "
           95  +    PRAGMA page_size = $pgsz;
           96  +    VACUUM;
           97  +    PRAGMA cache_size = $cachesz;
           98  +  "
           99  +
          100  +  do_test 2.$tn.1 {
          101  +    set ::iTemp 0
          102  +    catch { array unset F }
          103  +    execsql {
          104  +      WITH x(i, j) AS (
          105  +        SELECT 1, randomblob(100)
          106  +        UNION ALL
          107  +        SELECT i+1, randomblob(100) FROM x WHERE i<10000
          108  +      )
          109  +      SELECT * FROM x ORDER BY j;
          110  +    }
          111  +    expr {[array names F]!=""}
          112  +  } $bTemp
          113  +}
          114  +
    44    115   finish_test
          116  +