SQLite

Check-in [917c410808]
Login

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

Overview
Comment:Version 3.8.4 for sessions (plus two minor fixes).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 917c410808756e1697bd628f4c9c57dd13d08ce7
User & Date: drh 2014-03-11 01:48:06.461
Context
2014-03-12
10:03
Bump the version number to 3.8.4.1., to conform with trunk. (check-in: 42c9d8fc5f user: drh tags: sessions)
2014-03-11
01:48
Version 3.8.4 for sessions (plus two minor fixes). (check-in: 917c410808 user: drh tags: sessions)
2014-03-10
20:12
Adjustments to the cost computation for the skip-scan query plan, to take into account the fact that a seek has to occur on each skip. (check-in: 0769eebd02 user: drh tags: trunk)
2014-03-07
14:36
Merge the fix for the journal_mode=PERSIST error recovery delay bug. (check-in: bb6a75f4bb user: drh tags: sessions)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/func.c.
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
static void charFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  unsigned char *z, *zOut;
  int i;
  zOut = z = sqlite3_malloc( argc*4 );
  if( z==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }
  for(i=0; i<argc; i++){
    sqlite3_int64 x;
    unsigned c;







|







1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
static void charFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  unsigned char *z, *zOut;
  int i;
  zOut = z = sqlite3_malloc( argc*4+1 );
  if( z==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }
  for(i=0; i<argc; i++){
    sqlite3_int64 x;
    unsigned c;
Changes to src/pager.c.
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899








4900
4901
4902
4903
4904
4905
4906
    ** in fact there is none.  This results in a false-positive which will
    ** be dealt with by the playback routine.  Ticket #3883.
    */
    rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
    if( rc==SQLITE_OK && !locked ){
      Pgno nPage;                 /* Number of pages in database file */

      /* Check the size of the database file. If it consists of 0 pages
      ** and the journal is not being persisted, then delete the journal
      ** file.  See the header comment above for the reasoning here.
      ** Delete the obsolete journal file under a RESERVED lock to avoid
      ** race conditions and to avoid violating [H33020].
      */
      rc = pagerPagecount(pPager, &nPage);
      if( rc==SQLITE_OK ){








        if( nPage==0 && !jrnlOpen ){
          sqlite3BeginBenignMalloc();
          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
            sqlite3OsDelete(pVfs, pPager->zJournal, 0);
            if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
          }
          sqlite3EndBenignMalloc();







<
<
<
<
<
<


>
>
>
>
>
>
>
>







4885
4886
4887
4888
4889
4890
4891






4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
    ** in fact there is none.  This results in a false-positive which will
    ** be dealt with by the playback routine.  Ticket #3883.
    */
    rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
    if( rc==SQLITE_OK && !locked ){
      Pgno nPage;                 /* Number of pages in database file */







      rc = pagerPagecount(pPager, &nPage);
      if( rc==SQLITE_OK ){
        /* If the database is zero pages in size, that means that either (1) the
        ** journal is a remnant from a prior database with the same name where
        ** the database file but not the journal was deleted, or (2) the initial
        ** transaction that populates a new database is being rolled back.
        ** In either case, the journal file can be deleted.  However, take care
        ** not to delete the journal file if it is already open due to
        ** journal_mode=PERSIST.
        */
        if( nPage==0 && !jrnlOpen ){
          sqlite3BeginBenignMalloc();
          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
            sqlite3OsDelete(pVfs, pPager->zJournal, 0);
            if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
          }
          sqlite3EndBenignMalloc();
Changes to src/pragma.c.
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
  ** Older versions of SQLite would set the default cache size to a
  ** negative number to indicate synchronous=OFF.  These days, synchronous
  ** is always on by default regardless of the sign of the default cache
  ** size.  But continue to take the absolute value of the default cache
  ** size of historical compatibility.
  */
  case PragTyp_DEFAULT_CACHE_SIZE: {
    static const int iLn = __LINE__+2;
    static const VdbeOpList getCacheSize[] = {
      { OP_Transaction, 0, 0,        0},                         /* 0 */
      { OP_ReadCookie,  0, 1,        BTREE_DEFAULT_CACHE_SIZE},  /* 1 */
      { OP_IfPos,       1, 8,        0},
      { OP_Integer,     0, 2,        0},
      { OP_Subtract,    1, 2,        1},
      { OP_IfPos,       1, 8,        0},







|







820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
  ** Older versions of SQLite would set the default cache size to a
  ** negative number to indicate synchronous=OFF.  These days, synchronous
  ** is always on by default regardless of the sign of the default cache
  ** size.  But continue to take the absolute value of the default cache
  ** size of historical compatibility.
  */
  case PragTyp_DEFAULT_CACHE_SIZE: {
    static const int iLn = VDBE_OFFSET_LINENO(2);
    static const VdbeOpList getCacheSize[] = {
      { OP_Transaction, 0, 0,        0},                         /* 0 */
      { OP_ReadCookie,  0, 1,        BTREE_DEFAULT_CACHE_SIZE},  /* 1 */
      { OP_IfPos,       1, 8,        0},
      { OP_Integer,     0, 2,        0},
      { OP_Subtract,    1, 2,        1},
      { OP_IfPos,       1, 8,        0},
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
      rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
      if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
        /* When setting the auto_vacuum mode to either "full" or 
        ** "incremental", write the value of meta[6] in the database
        ** file. Before writing to meta[6], check that meta[3] indicates
        ** that this really is an auto-vacuum capable database.
        */
        static const int iLn = __LINE__+2;
        static const VdbeOpList setMeta6[] = {
          { OP_Transaction,    0,         1,                 0},    /* 0 */
          { OP_ReadCookie,     0,         1,         BTREE_LARGEST_ROOT_PAGE},
          { OP_If,             1,         0,                 0},    /* 2 */
          { OP_Halt,           SQLITE_OK, OE_Abort,          0},    /* 3 */
          { OP_Integer,        0,         1,                 0},    /* 4 */
          { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 1},    /* 5 */







|







1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
      rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
      if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
        /* When setting the auto_vacuum mode to either "full" or 
        ** "incremental", write the value of meta[6] in the database
        ** file. Before writing to meta[6], check that meta[3] indicates
        ** that this really is an auto-vacuum capable database.
        */
        static const int iLn = VDBE_OFFSET_LINENO(2);
        static const VdbeOpList setMeta6[] = {
          { OP_Transaction,    0,         1,                 0},    /* 0 */
          { OP_ReadCookie,     0,         1,         BTREE_LARGEST_ROOT_PAGE},
          { OP_If,             1,         0,                 0},    /* 2 */
          { OP_Halt,           SQLITE_OK, OE_Abort,          0},    /* 3 */
          { OP_Integer,        0,         1,                 0},    /* 4 */
          { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 1},    /* 5 */
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
  case PragTyp_INTEGRITY_CHECK: {
    int i, j, addr, mxErr;

    /* Code that appears at the end of the integrity check.  If no error
    ** messages have been generated, output OK.  Otherwise output the
    ** error message
    */
    static const int iLn = __LINE__+2;
    static const VdbeOpList endCode[] = {
      { OP_AddImm,      1, 0,        0},    /* 0 */
      { OP_IfNeg,       1, 0,        0},    /* 1 */
      { OP_String8,     0, 3,        0},    /* 2 */
      { OP_ResultRow,   3, 1,        0},
    };








|







1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
  case PragTyp_INTEGRITY_CHECK: {
    int i, j, addr, mxErr;

    /* Code that appears at the end of the integrity check.  If no error
    ** messages have been generated, output OK.  Otherwise output the
    ** error message
    */
    static const int iLn = VDBE_OFFSET_LINENO(2);
    static const VdbeOpList endCode[] = {
      { OP_AddImm,      1, 0,        0},    /* 0 */
      { OP_IfNeg,       1, 0,        0},    /* 1 */
      { OP_String8,     0, 3,        0},    /* 2 */
      { OP_ResultRow,   3, 1,        0},
    };

Changes to src/trigger.c.
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
#endif

  /* Generate code to destroy the database record of the trigger.
  */
  assert( pTable!=0 );
  if( (v = sqlite3GetVdbe(pParse))!=0 ){
    int base;
    static const int iLn = __LINE__+2;
    static const VdbeOpList dropTrigger[] = {
      { OP_Rewind,     0, ADDR(9),  0},
      { OP_String8,    0, 1,        0}, /* 1 */
      { OP_Column,     0, 1,        2},
      { OP_Ne,         2, ADDR(8),  1},
      { OP_String8,    0, 1,        0}, /* 4: "trigger" */
      { OP_Column,     0, 0,        2},







|







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
#endif

  /* Generate code to destroy the database record of the trigger.
  */
  assert( pTable!=0 );
  if( (v = sqlite3GetVdbe(pParse))!=0 ){
    int base;
    static const int iLn = VDBE_OFFSET_LINENO(2);
    static const VdbeOpList dropTrigger[] = {
      { OP_Rewind,     0, ADDR(9),  0},
      { OP_String8,    0, 1,        0}, /* 1 */
      { OP_Column,     0, 1,        2},
      { OP_Ne,         2, ADDR(8),  1},
      { OP_String8,    0, 1,        0}, /* 4: "trigger" */
      { OP_Column,     0, 0,        2},
Changes to src/vdbe.h.
270
271
272
273
274
275
276

277
278
279
280
281

282
283
284
*/
#ifdef SQLITE_VDBE_COVERAGE
  void sqlite3VdbeSetLineNumber(Vdbe*,int);
# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);

#else
# define VdbeCoverage(v)
# define VdbeCoverageIf(v,x)
# define VdbeCoverageAlwaysTaken(v)
# define VdbeCoverageNeverTaken(v)

#endif

#endif







>





>



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
*/
#ifdef SQLITE_VDBE_COVERAGE
  void sqlite3VdbeSetLineNumber(Vdbe*,int);
# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
# define VDBE_OFFSET_LINENO(x) (__LINE__+x)
#else
# define VdbeCoverage(v)
# define VdbeCoverageIf(v,x)
# define VdbeCoverageAlwaysTaken(v)
# define VdbeCoverageNeverTaken(v)
# define VDBE_OFFSET_LINENO(x) 0
#endif

#endif
Changes to src/vdbeblob.c.
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  ** uses it to implement the blob_read(), blob_write() and 
  ** blob_bytes() functions.
  **
  ** The sqlite3_blob_close() function finalizes the vdbe program,
  ** which closes the b-tree cursor and (possibly) commits the 
  ** transaction.
  */
  static const int iLn = __LINE__+4;
  static const VdbeOpList openBlob[] = {
    /* {OP_Transaction, 0, 0, 0},  // 0: Inserted separately */
    {OP_TableLock, 0, 0, 0},       /* 1: Acquire a read or write lock */
    /* One of the following two instructions is replaced by an OP_Noop. */
    {OP_OpenRead, 0, 0, 0},        /* 2: Open cursor 0 for reading */
    {OP_OpenWrite, 0, 0, 0},       /* 3: Open cursor 0 for read/write */
    {OP_Variable, 1, 1, 1},        /* 4: Push the rowid to the stack */







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  ** uses it to implement the blob_read(), blob_write() and 
  ** blob_bytes() functions.
  **
  ** The sqlite3_blob_close() function finalizes the vdbe program,
  ** which closes the b-tree cursor and (possibly) commits the 
  ** transaction.
  */
  static const int iLn = VDBE_OFFSET_LINENO(4);
  static const VdbeOpList openBlob[] = {
    /* {OP_Transaction, 0, 0, 0},  // 0: Inserted separately */
    {OP_TableLock, 0, 0, 0},       /* 1: Acquire a read or write lock */
    /* One of the following two instructions is replaced by an OP_Noop. */
    {OP_OpenRead, 0, 0, 0},        /* 2: Open cursor 0 for reading */
    {OP_OpenWrite, 0, 0, 0},       /* 3: Open cursor 0 for read/write */
    {OP_Variable, 1, 1, 1},        /* 4: Push the rowid to the stack */
Changes to src/where.c.
3970
3971
3972
3973
3974
3975
3976


3977

3978
3979
3980
3981
3982
3983
3984
  ){
    LogEst nIter;
    pNew->u.btree.nEq++;
    pNew->u.btree.nSkip++;
    pNew->aLTerm[pNew->nLTerm++] = 0;
    pNew->wsFlags |= WHERE_SKIPSCAN;
    nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);


    whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);

  }
  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    int nIn = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    int nRecValid = pBuilder->nRecValid;
#endif
    if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)







>
>

>







3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
  ){
    LogEst nIter;
    pNew->u.btree.nEq++;
    pNew->u.btree.nSkip++;
    pNew->aLTerm[pNew->nLTerm++] = 0;
    pNew->wsFlags |= WHERE_SKIPSCAN;
    nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);
    pNew->rRun = rLogSize + nIter;
    pNew->nOut += nIter;
    whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
    pNew->nOut = saved_nOut;
  }
  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    int nIn = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    int nRecValid = pBuilder->nRecValid;
#endif
    if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
Changes to test/func.test.
1357
1358
1359
1360
1361
1362
1363





1364
  if {$i==0xfeff} continue
  do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
}
for {set i 65536} {$i<=0x10ffff} {incr i 139} {
  do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
}






finish_test







>
>
>
>
>

1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
  if {$i==0xfeff} continue
  do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
}
for {set i 65536} {$i<=0x10ffff} {incr i 139} {
  do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
}

# Test char().
#
do_execsql_test func-31.1 { 
  SELECT char(), length(char()), typeof(char()) 
} {{} 0 text}
finish_test
Changes to test/skipscan1.test.
204
205
206
207
208
209
210






































211
212
  SELECT i FROM t4 WHERE c=3;
  SELECT i FROM t4 WHERE d=4;
  SELECT i FROM t4 WHERE e=5;
  SELECT i FROM t4 WHERE f=6;
  SELECT i FROM t4 WHERE g=7;
  SELECT i FROM t4 WHERE h=8;
} {9 9 9 9 9 9 9 9}







































finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  SELECT i FROM t4 WHERE c=3;
  SELECT i FROM t4 WHERE d=4;
  SELECT i FROM t4 WHERE e=5;
  SELECT i FROM t4 WHERE f=6;
  SELECT i FROM t4 WHERE g=7;
  SELECT i FROM t4 WHERE h=8;
} {9 9 9 9 9 9 9 9}

# Make sure skip-scan cost computation in the query planner takes into
# account the fact that the seek must occur multiple times.
#
# Prior to 2014-03-10, the costs were computed incorrectly which would
# cause index t5i2 to be used instead of t5i1 on the skipscan1-5.3.
#
do_execsql_test skipscan1-5.1 {
  CREATE TABLE t5(
    id INTEGER PRIMARY KEY,
    loc TEXT,
    lang INTEGER,
    utype INTEGER,
    xa INTEGER,
    xd INTEGER,
    xh INTEGER
  );
  CREATE INDEX t5i1 on t5(loc, xh, xa, utype, lang);
  CREATE INDEX t5i2 ON t5(xd,loc,utype,lang);
  EXPLAIN QUERY PLAN
    SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N';
} {/.*COVERING INDEX t5i1 .*/}
do_execsql_test skipscan1-5.2 {
  ANALYZE;
  DELETE FROM sqlite_stat1;
  DROP TABLE IF EXISTS sqlite_stat4;
  DROP TABLE IF EXISTS sqlite_stat3;
  INSERT INTO sqlite_stat1 VALUES('t5','t5i1','2702931 3 2 2 2 2');
  INSERT INTO sqlite_stat1 VALUES('t5','t5i2','2702931 686 2 2 2');
  ANALYZE sqlite_master;
} {}
db cache flush
do_execsql_test skipscan1-5.3 {
  EXPLAIN QUERY PLAN
    SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N';
} {/.*COVERING INDEX t5i1 .*/}



finish_test