/ Check-in [553258c2]
Login

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

Overview
Comment:Merge recent fixes and enhancements from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | 2-size-lookaside
Files: files | file ages | folders
SHA3-256: 553258c2ed85cb3a539d7562bf6fcf58bb601a7c459e408a2188794ea4bb2f2c
User & Date: drh 2019-10-09 17:38:56
Context
2019-10-18
22:54
Use an allocation count and freelist instead of a membership bitfield in the mini lookaside allocator Leaf check-in: 9496b4d3 user: numist tags: 2-size-lookaside
2019-10-09
17:38
Merge recent fixes and enhancements from trunk. check-in: 553258c2 user: drh tags: 2-size-lookaside
17:06
An alternative, experimental lookaside memory allocator that uses two different slot sizes. check-in: 5ba8cee8 user: sperry tags: 2-size-lookaside
15:37
An improved fix for the dbsqlfuzz-discovered ALWAYS() failure following OOM in sqlite3ExprCollSeq(). This time with a test case (engineered by Dan). check-in: 907f7965 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

  1244   1244   	./testfixture$(TEXE) $(TOP)/test/full.test
  1245   1245   
  1246   1246   # Fuzz testing
  1247   1247   fuzztest:	fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
  1248   1248   	./fuzzcheck$(TEXE) $(FUZZDATA)
  1249   1249   	./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
  1250   1250   
  1251         -fastfuzztest:	fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
  1252         -	./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
  1253         -	./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
  1254         -
  1255   1251   valgrindfuzz:	fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
  1256   1252   	valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
  1257   1253   	valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
  1258   1254   
  1259   1255   # The veryquick.test TCL tests.
  1260   1256   #
  1261   1257   tcltest:	./testfixture$(TEXE)
................................................................................
  1265   1261   #
  1266   1262   quicktest:	./testfixture$(TEXE)
  1267   1263   	./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS)
  1268   1264   
  1269   1265   # This is the common case.  Run many tests that do not take too long,
  1270   1266   # including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
  1271   1267   #
  1272         -test:	fastfuzztest sourcetest $(TESTPROGS) tcltest
         1268  +test:	fuzztest sourcetest $(TESTPROGS) tcltest
  1273   1269   
  1274   1270   # Run a test using valgrind.  This can take a really long time
  1275   1271   # because valgrind is so much slower than a native machine.
  1276   1272   #
  1277   1273   valgrindtest:	$(TESTPROGS) valgrindfuzz
  1278   1274   	OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS)
  1279   1275   

Changes to Makefile.msc.

  2406   2406   queryplantest:	testfixture.exe shell
  2407   2407   	@set PATH=$(LIBTCLPATH);$(PATH)
  2408   2408   	.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
  2409   2409   
  2410   2410   fuzztest:	fuzzcheck.exe
  2411   2411   	.\fuzzcheck.exe $(FUZZDATA)
  2412   2412   
  2413         -fastfuzztest:	fuzzcheck.exe
  2414         -	.\fuzzcheck.exe --limit-mem 100M $(FUZZDATA)
  2415         -
  2416   2413   # Minimal testing that runs in less than 3 minutes (on a fast machine)
  2417   2414   #
  2418   2415   quicktest:	testfixture.exe sourcetest
  2419   2416   	@set PATH=$(LIBTCLPATH);$(PATH)
  2420   2417   	.\testfixture.exe $(TOP)\test\extraquick.test $(TESTOPTS)
  2421   2418   
  2422   2419   # This is the common case.  Run many tests that do not take too long,
  2423   2420   # including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
  2424   2421   #
  2425         -test:	$(TESTPROGS) sourcetest fastfuzztest
         2422  +test:	$(TESTPROGS) sourcetest fuzztest
  2426   2423   	@set PATH=$(LIBTCLPATH);$(PATH)
  2427   2424   	.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
  2428   2425   
  2429   2426   smoketest:	$(TESTPROGS)
  2430   2427   	@set PATH=$(LIBTCLPATH);$(PATH)
  2431   2428   	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
  2432   2429   

Changes to ext/fts5/fts5_config.c.

    19     19   #define FTS5_DEFAULT_PAGE_SIZE   4050
    20     20   #define FTS5_DEFAULT_AUTOMERGE      4
    21     21   #define FTS5_DEFAULT_USERMERGE      4
    22     22   #define FTS5_DEFAULT_CRISISMERGE   16
    23     23   #define FTS5_DEFAULT_HASHSIZE    (1024*1024)
    24     24   
    25     25   /* Maximum allowed page size */
    26         -#define FTS5_MAX_PAGE_SIZE (128*1024)
           26  +#define FTS5_MAX_PAGE_SIZE (64*1024)
    27     27   
    28     28   static int fts5_iswhitespace(char x){
    29     29     return (x==' ');
    30     30   }
    31     31   
    32     32   static int fts5_isopenquote(char x){
    33     33     return (x=='"' || x=='\'' || x=='[' || x=='`');

Changes to ext/fts5/test/fts5misc.test.

   146    146     COMMIT;
   147    147   }
   148    148   
   149    149   do_execsql_test 4.4 {
   150    150     INSERT INTO vt0(vt0) VALUES('integrity-check');
   151    151   }
   152    152   
          153  +#-------------------------------------------------------------------------
          154  +# Ticket [81a7f7b9].
          155  +#
          156  +reset_db
          157  +do_execsql_test 5.0 {
          158  +  CREATE VIRTUAL TABLE vt0 USING fts5(c0, c1);
          159  +  INSERT INTO vt0(vt0, rank) VALUES('pgsz', '65536');
          160  +  WITH s(i) AS (
          161  +    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1236
          162  +  )
          163  +  INSERT INTO vt0(c0) SELECT '0' FROM s;
          164  +} {}
          165  +
          166  +do_execsql_test 5.1 {
          167  +  UPDATE vt0 SET c1 = 'T,D&p^y/7#3*v<b<4j7|f';
          168  +}
          169  +
          170  +do_execsql_test 5.2 {
          171  +  INSERT INTO vt0(vt0) VALUES('integrity-check');
          172  +}
          173  +
          174  +do_catchsql_test 5.3 {
          175  +  INSERT INTO vt0(vt0, rank) VALUES('pgsz', '65537');
          176  +} {1 {SQL logic error}}
   153    177   
   154    178   finish_test
   155    179   

Changes to main.mk.

   933    933   queryplantest:	testfixture$(EXE) sqlite3$(EXE)
   934    934   	./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS)
   935    935   
   936    936   fuzztest:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
   937    937   	./fuzzcheck$(EXE) $(FUZZDATA)
   938    938   	./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
   939    939   
   940         -fastfuzztest:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
   941         -	./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA)
   942         -	./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
   943         -
   944    940   valgrindfuzz:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
   945    941   	valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
   946    942   	valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
   947    943   
   948    944   # The veryquick.test TCL tests.
   949    945   #
   950    946   tcltest:	./testfixture$(EXE)
................................................................................
   954    950   # tests.  Designed to run in under 3 minutes on a workstation.
   955    951   #
   956    952   quicktest:	./testfixture$(EXE)
   957    953   	./testfixture$(EXE) $(TOP)/test/extraquick.test $(TESTOPTS)
   958    954   
   959    955   # The default test case.  Runs most of the faster standard TCL tests,
   960    956   # and fuzz tests, and sqlite3_analyzer and sqldiff tests.
   961         -test:	fastfuzztest sourcetest $(TESTPROGS) tcltest
          957  +test:	fuzztest sourcetest $(TESTPROGS) tcltest
   962    958   
   963    959   # Run a test using valgrind.  This can take a really long time
   964    960   # because valgrind is so much slower than a native machine.
   965    961   #
   966    962   valgrindtest:	$(TESTPROGS) valgrindfuzz
   967    963   	OMIT_MISUSE=1 valgrind -v \
   968    964   	./testfixture$(EXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS)

Changes to src/expr.c.

   182    182         }else{
   183    183           Expr *pNext  = p->pRight;
   184    184           /* The Expr.x union is never used at the same time as Expr.pRight */
   185    185           assert( p->x.pList==0 || p->pRight==0 );
   186    186           /* p->flags holds EP_Collate and p->pLeft->flags does not.  And
   187    187           ** p->x.pSelect cannot.  So if p->x.pLeft exists, it must hold at
   188    188           ** least one EP_Collate. Thus the following two ALWAYS. */
   189         -        if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
          189  +        if( p->x.pList!=0 
          190  +         && !db->mallocFailed
          191  +         && ALWAYS(!ExprHasProperty(p, EP_xIsSelect))
          192  +        ){
   190    193             int i;
   191    194             for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
   192    195               if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
   193    196                 pNext = p->x.pList->a[i].pExpr;
   194    197                 break;
   195    198               }
   196    199             }

Changes to src/prepare.c.

   639    639         sParse.zTail = &zSql[nBytes];
   640    640       }
   641    641     }else{
   642    642       sqlite3RunParser(&sParse, zSql, &zErrMsg);
   643    643     }
   644    644     assert( 0==sParse.nQueryLoop );
   645    645   
   646         -  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
          646  +  if( sParse.rc==SQLITE_DONE ){
          647  +    sParse.rc = SQLITE_OK;
          648  +  }
   647    649     if( sParse.checkSchema ){
   648    650       schemaIsValid(&sParse);
   649    651     }
   650         -  if( db->mallocFailed ){
   651         -    sParse.rc = SQLITE_NOMEM_BKPT;
   652         -  }
   653    652     if( pzTail ){
   654    653       *pzTail = sParse.zTail;
   655    654     }
   656         -  rc = sParse.rc;
   657         -
   658         -#ifndef SQLITE_OMIT_EXPLAIN
   659         -  /* Justification for the ALWAYS(): The only way for rc to be SQLITE_OK and
   660         -  ** sParse.pVdbe to be NULL is if the input SQL is an empty string, but in
   661         -  ** that case, sParse.explain will be false. */
   662         -  if( sParse.explain && rc==SQLITE_OK && ALWAYS(sParse.pVdbe) ){
   663         -    static const char * const azColName[] = {
   664         -       "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
   665         -       "id", "parent", "notused", "detail"
   666         -    };
   667         -    int iFirst, mx;
   668         -    if( sParse.explain==2 ){
   669         -      sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
   670         -      iFirst = 8;
   671         -      mx = 12;
   672         -    }else{
   673         -      sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
   674         -      iFirst = 0;
   675         -      mx = 8;
   676         -    }
   677         -    for(i=iFirst; i<mx; i++){
   678         -      sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
   679         -                            azColName[i], SQLITE_STATIC);
   680         -    }
   681         -  }
   682         -#endif
   683    655   
   684    656     if( db->init.busy==0 ){
   685    657       sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
   686    658     }
   687         -  if( rc!=SQLITE_OK || db->mallocFailed ){
          659  +  if( db->mallocFailed ){
          660  +    sParse.rc = SQLITE_NOMEM_BKPT;
          661  +  }
          662  +  rc = sParse.rc;
          663  +  if( rc!=SQLITE_OK ){
   688    664       if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe);
   689    665       assert(!(*ppStmt));
   690    666     }else{
   691    667       *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
   692    668     }
   693    669   
   694    670     if( zErrMsg ){

Changes to src/vdbeaux.c.

  2219   2219     assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
  2220   2220     x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
  2221   2221     assert( x.nFree>=0 );
  2222   2222     assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
  2223   2223   
  2224   2224     resolveP2Values(p, &nArg);
  2225   2225     p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
  2226         -  if( pParse->explain && nMem<10 ){
  2227         -    nMem = 10;
         2226  +  if( pParse->explain ){
         2227  +    static const char * const azColName[] = {
         2228  +       "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
         2229  +       "id", "parent", "notused", "detail"
         2230  +    };
         2231  +    int iFirst, mx, i;
         2232  +    if( nMem<10 ) nMem = 10;
         2233  +    if( pParse->explain==2 ){
         2234  +      sqlite3VdbeSetNumCols(p, 4);
         2235  +      iFirst = 8;
         2236  +      mx = 12;
         2237  +    }else{
         2238  +      sqlite3VdbeSetNumCols(p, 8);
         2239  +      iFirst = 0;
         2240  +      mx = 8;
         2241  +    }
         2242  +    for(i=iFirst; i<mx; i++){
         2243  +      sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME,
         2244  +                            azColName[i], SQLITE_STATIC);
         2245  +    }
  2228   2246     }
  2229   2247     p->expired = 0;
  2230   2248   
  2231   2249     /* Memory for registers, parameters, cursor, etc, is allocated in one or two
  2232   2250     ** passes.  On the first pass, we try to reuse unused memory at the 
  2233   2251     ** end of the opcode array.  If we are unable to satisfy all memory
  2234   2252     ** requirements by reusing the opcode array tail, then the second

Changes to test/collate1.test.

   412    412   do_execsql_test 8.2 {
   413    413     DROP TABLE IF EXISTS t0;
   414    414     CREATE TABLE t0(c0 COLLATE RTRIM, c1 BLOB UNIQUE,
   415    415                     PRIMARY KEY (c0, c1)) WITHOUT ROWID;
   416    416     INSERT INTO t0 VALUES (123, 3), (' ', 1), ('	', 2), ('', 4);
   417    417     SELECT * FROM t0 WHERE c1 = 1;
   418    418   } {{ } 1}
          419  +
          420  +# 2019-10-09
          421  +# ALWAYS() macro fails following OOM
          422  +# Problem detected by dbsqlfuzz.
          423  +#
          424  +do_execsql_test 9.0 {
          425  +  CREATE TABLE t1(a, b);
          426  +  CREATE TABLE t2(c, d);
          427  +}
          428  +
          429  +do_faultsim_test 9.1 -faults oom* -body {
          430  +  execsql {
          431  +    SELECT * FROM (
          432  +        SELECT b COLLATE nocase IN (SELECT c FROM t2) FROM t1
          433  +    );
          434  +  }
          435  +} -test {
          436  +  faultsim_test_result {0 {}}
          437  +}
   419    438   
   420    439   finish_test

Changes to test/fuzzdata8.db.

cannot compute difference between binary files