/ Check-in [acca97ef]
Login

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

Overview
Comment:Fix a problem with sorting large amounts of partially ordered data.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: acca97efda86a0c020854d2dd9da16f5879986b1
User & Date: dan 2015-04-11 20:20:29
Context
2015-04-11
20:44
Optimizations for VACUUM, CREATE INDEX and some cases of ORDER BY. check-in: 79326d6e user: dan tags: trunk
20:20
Fix a problem with sorting large amounts of partially ordered data. check-in: acca97ef user: dan tags: trunk
13:49
Add the --changeset option to the sqldiff utility program, for generating a sessions changeset file instead of an SQL diff. check-in: f9a3a839 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbesort.c.

   883    883   
   884    884   /*
   885    885   ** Free all resources owned by the object indicated by argument pTask. All 
   886    886   ** fields of *pTask are zeroed before returning.
   887    887   */
   888    888   static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
   889    889     sqlite3DbFree(db, pTask->pUnpacked);
   890         -  pTask->pUnpacked = 0;
   891    890   #if SQLITE_MAX_WORKER_THREADS>0
   892    891     /* pTask->list.aMemory can only be non-zero if it was handed memory
   893    892     ** from the main thread.  That only occurs SQLITE_MAX_WORKER_THREADS>0 */
   894    893     if( pTask->list.aMemory ){
   895    894       sqlite3_free(pTask->list.aMemory);
   896         -    pTask->list.aMemory = 0;
   897    895     }else
   898    896   #endif
   899    897     {
   900    898       assert( pTask->list.aMemory==0 );
   901    899       vdbeSorterRecordFree(0, pTask->list.pList);
   902    900     }
   903         -  pTask->list.pList = 0;
   904    901     if( pTask->file.pFd ){
   905    902       sqlite3OsCloseFree(pTask->file.pFd);
   906         -    pTask->file.pFd = 0;
   907         -    pTask->file.iEof = 0;
   908    903     }
   909    904     if( pTask->file2.pFd ){
   910    905       sqlite3OsCloseFree(pTask->file2.pFd);
   911         -    pTask->file2.pFd = 0;
   912         -    pTask->file2.iEof = 0;
   913    906     }
          907  +  memset(pTask, 0, sizeof(SortSubtask));
   914    908   }
   915    909   
   916    910   #ifdef SQLITE_DEBUG_SORTER_THREADS
   917    911   static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){
   918    912     i64 t;
   919    913     int iTask = (pTask - pTask->pSorter->aTask);
   920    914     sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
................................................................................
  1086   1080     }
  1087   1081   #endif
  1088   1082     vdbeMergeEngineFree(pSorter->pMerger);
  1089   1083     pSorter->pMerger = 0;
  1090   1084     for(i=0; i<pSorter->nTask; i++){
  1091   1085       SortSubtask *pTask = &pSorter->aTask[i];
  1092   1086       vdbeSortSubtaskCleanup(db, pTask);
         1087  +    pTask->pSorter = pSorter;
  1093   1088     }
  1094   1089     if( pSorter->list.aMemory==0 ){
  1095   1090       vdbeSorterRecordFree(0, pSorter->list.pList);
  1096   1091     }
  1097   1092     pSorter->list.pList = 0;
  1098   1093     pSorter->list.szPMA = 0;
  1099   1094     pSorter->bUsePMA = 0;

Changes to test/orderby1.test.

   491    491     CREATE TABLE t7(a,b);
   492    492     CREATE INDEX t7a ON t7(a);
   493    493     CREATE INDEX t7ab ON t7(a,b);
   494    494     EXPLAIN QUERY PLAN
   495    495     SELECT * FROM t7 WHERE a=?1 ORDER BY rowid;
   496    496   } {~/ORDER BY/}
   497    497   
          498  +#-------------------------------------------------------------------------
          499  +# Test a partial sort large enough to cause the sorter to spill data
          500  +# to disk.
          501  +#
          502  +reset_db
          503  +do_execsql_test 8.0 {
          504  +  PRAGMA cache_size = 5;
          505  +  CREATE TABLE t1(a, b);
          506  +  CREATE INDEX i1 ON t1(a);
          507  +}
          508  +
          509  +do_eqp_test 8.1 {
          510  +  SELECT * FROM t1 ORDER BY a, b;
          511  +} {
          512  +  0 0 0 {SCAN TABLE t1 USING INDEX i1} 
          513  +  0 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
          514  +}
          515  +
          516  +do_execsql_test 8.2 {
          517  +  WITH cnt(i) AS (
          518  +    SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<10000
          519  +  )
          520  +  INSERT INTO t1 SELECT i%2, randomblob(500) FROM cnt;
          521  +}
          522  +
          523  +do_test 8.3 {
          524  +  db eval { SELECT * FROM t1 ORDER BY a, b } { incr res $a }
          525  +  set res
          526  +} 5000
   498    527   
   499    528   finish_test