/ Check-in [94fd5bb6]
Login

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

Overview
Comment:Merge all the latest trunk enhancements into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 94fd5bb6da5ef4d850c2ed4ad38afabc5569dae6
User & Date: drh 2011-03-18 12:35:36
Context
2011-03-18
13:05
Update comments in sqlite3session.h. More to come. check-in: e73e9082 user: dan tags: sessions
12:35
Merge all the latest trunk enhancements into the sessions branch. check-in: 94fd5bb6 user: drh tags: sessions
2011-03-17
19:20
Change to the session module to use user-defined primary keys instead of rowids when collecting changes. check-in: 6614cfcb user: dan tags: sessions
16:45
Update the implementation of ".testctrl" in the command-line shell to use a look-up table rather than a long sequence of if-elses. Shorten source code lines of shell.c to 80 characters or less. check-in: 54bacb95 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/rtree/rtree.c.

  3129   3129     for(ii=0; ii<NCELL(&node); ii++){
  3130   3130       char zCell[512];
  3131   3131       int nCell = 0;
  3132   3132       RtreeCell cell;
  3133   3133       int jj;
  3134   3134   
  3135   3135       nodeGetCell(&tree, &node, ii, &cell);
  3136         -    sqlite3_snprintf(512-nCell,&zCell[nCell],"%d", cell.iRowid);
         3136  +    sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
  3137   3137       nCell = strlen(zCell);
  3138   3138       for(jj=0; jj<tree.nDim*2; jj++){
  3139   3139         sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f);
  3140   3140         nCell = strlen(zCell);
  3141   3141       }
  3142   3142   
  3143   3143       if( zText ){

Added ext/rtree/rtreeB.test.

            1  +# 2011 March 2
            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  +# Make sure the rtreenode() testing function can handle entries with
           12  +# 64-bit rowids.
           13  +# 
           14  +
           15  +if {![info exists testdir]} {
           16  +  set testdir [file join [file dirname [info script]] .. .. test]
           17  +} 
           18  +source $testdir/tester.tcl
           19  +ifcapable !rtree { finish_test ; return }
           20  +
           21  +do_test rtreeB-1.1 {
           22  +  db eval {
           23  +    CREATE VIRTUAL TABLE t1 USING rtree(ii, x0, y0, x1, y1);
           24  +    INSERT INTO t1 VALUES(1073741824, 0.0, 0.0, 100.0, 100.0);
           25  +    INSERT INTO t1 VALUES(2147483646, 0.0, 0.0, 200.0, 200.0);
           26  +    INSERT INTO t1 VALUES(4294967296, 0.0, 0.0, 300.0, 300.0);
           27  +    INSERT INTO t1 VALUES(8589934592, 20.0, 20.0, 150.0, 150.0);
           28  +    INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400);
           29  +    SELECT rtreenode(2, data) FROM t1_node;
           30  +  }
           31  +} {{{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}}}
           32  +
           33  +
           34  +finish_test

install-sh became executable.


Changes to src/btree.c.

  4897   4897           if( rc ){
  4898   4898             goto end_allocate_page;
  4899   4899           }
  4900   4900           if( nearby>0 ){
  4901   4901             u32 i;
  4902   4902             int dist;
  4903   4903             closest = 0;
  4904         -          dist = get4byte(&aData[8]) - nearby;
  4905         -          if( dist<0 ) dist = -dist;
         4904  +          dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
  4906   4905             for(i=1; i<k; i++){
  4907         -            int d2 = get4byte(&aData[8+i*4]) - nearby;
  4908         -            if( d2<0 ) d2 = -d2;
         4906  +            int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
  4909   4907               if( d2<dist ){
  4910   4908                 closest = i;
  4911   4909                 dist = d2;
  4912   4910               }
  4913   4911             }
  4914   4912           }else{
  4915   4913             closest = 0;
................................................................................
  6175   6173       for(j=i+1; j<k; j++){
  6176   6174         if( apNew[j]->pgno<(unsigned)minV ){
  6177   6175           minI = j;
  6178   6176           minV = apNew[j]->pgno;
  6179   6177         }
  6180   6178       }
  6181   6179       if( minI>i ){
  6182         -      int t;
  6183   6180         MemPage *pT;
  6184         -      t = apNew[i]->pgno;
  6185   6181         pT = apNew[i];
  6186   6182         apNew[i] = apNew[minI];
  6187   6183         apNew[minI] = pT;
  6188   6184       }
  6189   6185     }
  6190   6186     TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
  6191   6187       apNew[0]->pgno, szNew[0],

Changes to src/ctime.c.

   297    297     "OMIT_TRACE",
   298    298   #endif
   299    299   #ifdef SQLITE_OMIT_TRIGGER
   300    300     "OMIT_TRIGGER",
   301    301   #endif
   302    302   #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
   303    303     "OMIT_TRUNCATE_OPTIMIZATION",
          304  +#endif
          305  +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
          306  +  "OMIT_UNIQUE_ENFORCEMENT",
   304    307   #endif
   305    308   #ifdef SQLITE_OMIT_UTF16
   306    309     "OMIT_UTF16",
   307    310   #endif
   308    311   #ifdef SQLITE_OMIT_VACUUM
   309    312     "OMIT_VACUUM",
   310    313   #endif

Changes to src/expr.c.

   385    385     int nExtra = 0;
   386    386     int iValue = 0;
   387    387   
   388    388     if( pToken ){
   389    389       if( op!=TK_INTEGER || pToken->z==0
   390    390             || sqlite3GetInt32(pToken->z, &iValue)==0 ){
   391    391         nExtra = pToken->n+1;
          392  +      assert( iValue>=0 );
   392    393       }
   393    394     }
   394    395     pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
   395    396     if( pNew ){
   396    397       pNew->op = (u8)op;
   397    398       pNew->iAgg = -1;
   398    399       if( pToken ){
................................................................................
   610    611   }
   611    612   
   612    613   /*
   613    614   ** Recursively delete an expression tree.
   614    615   */
   615    616   void sqlite3ExprDelete(sqlite3 *db, Expr *p){
   616    617     if( p==0 ) return;
          618  +  /* Sanity check: Assert that the IntValue is non-negative if it exists */
          619  +  assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
   617    620     if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
   618    621       sqlite3ExprDelete(db, p->pLeft);
   619    622       sqlite3ExprDelete(db, p->pRight);
   620    623       if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
   621    624         sqlite3DbFree(db, p->u.zToken);
   622    625       }
   623    626       if( ExprHasProperty(p, EP_xIsSelect) ){
................................................................................
  1219   1222           *pValue = -v;
  1220   1223           rc = 1;
  1221   1224         }
  1222   1225         break;
  1223   1226       }
  1224   1227       default: break;
  1225   1228     }
  1226         -  if( rc ){
  1227         -    assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly)
  1228         -               || (p->flags2 & EP2_MallocedToken)==0 );
  1229         -    p->op = TK_INTEGER;
  1230         -    p->flags |= EP_IntValue;
  1231         -    p->u.iValue = *pValue;
  1232         -  }
  1233   1229     return rc;
  1234   1230   }
  1235   1231   
  1236   1232   /*
  1237   1233   ** Return FALSE if there is no chance that the expression can be NULL.
  1238   1234   **
  1239   1235   ** If the expression might be NULL or if the expression is too complex
................................................................................
  1950   1946   **
  1951   1947   ** Expr.u.zToken is always UTF8 and zero-terminated.
  1952   1948   */
  1953   1949   static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
  1954   1950     Vdbe *v = pParse->pVdbe;
  1955   1951     if( pExpr->flags & EP_IntValue ){
  1956   1952       int i = pExpr->u.iValue;
         1953  +    assert( i>=0 );
  1957   1954       if( negFlag ) i = -i;
  1958   1955       sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
  1959   1956     }else{
  1960   1957       int c;
  1961   1958       i64 value;
  1962   1959       const char *z = pExpr->u.zToken;
  1963   1960       assert( z!=0 );
  1964   1961       c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
  1965   1962       if( c==0 || (c==2 && negFlag) ){
  1966   1963         char *zV;
  1967         -      if( negFlag ){ value = -value; }
         1964  +      if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
  1968   1965         zV = dup8bytes(v, (char*)&value);
  1969   1966         sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
  1970   1967       }else{
  1971   1968   #ifdef SQLITE_OMIT_FLOATING_POINT
  1972   1969         sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
  1973   1970   #else
  1974   1971         codeReal(v, z, negFlag, iMem);

Changes to src/fkey.c.

   683    683   void sqlite3FkCheck(
   684    684     Parse *pParse,                  /* Parse context */
   685    685     Table *pTab,                    /* Row is being deleted from this table */ 
   686    686     int regOld,                     /* Previous row data is stored here */
   687    687     int regNew                      /* New row data is stored here */
   688    688   ){
   689    689     sqlite3 *db = pParse->db;       /* Database handle */
   690         -  Vdbe *v;                        /* VM to write code to */
   691    690     FKey *pFKey;                    /* Used to iterate through FKs */
   692    691     int iDb;                        /* Index of database containing pTab */
   693    692     const char *zDb;                /* Name of database containing pTab */
   694    693     int isIgnoreErrors = pParse->disableTriggers;
   695    694   
   696    695     /* Exactly one of regOld and regNew should be non-zero. */
   697    696     assert( (regOld==0)!=(regNew==0) );
   698    697   
   699    698     /* If foreign-keys are disabled, this function is a no-op. */
   700    699     if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
   701    700   
   702         -  v = sqlite3GetVdbe(pParse);
   703    701     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   704    702     zDb = db->aDb[iDb].zName;
   705    703   
   706    704     /* Loop through all the foreign key constraints for which pTab is the
   707    705     ** child table (the table that the foreign key definition is part of).  */
   708    706     for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
   709    707       Table *pTo;                   /* Parent table of foreign key pFKey */

Changes to src/func.c.

  1235   1235     p = sqlite3_aggregate_context(context, sizeof(*p));
  1236   1236     type = sqlite3_value_numeric_type(argv[0]);
  1237   1237     if( p && type!=SQLITE_NULL ){
  1238   1238       p->cnt++;
  1239   1239       if( type==SQLITE_INTEGER ){
  1240   1240         i64 v = sqlite3_value_int64(argv[0]);
  1241   1241         p->rSum += v;
  1242         -      if( (p->approx|p->overflow)==0 ){
  1243         -        i64 iNewSum = p->iSum + v;
  1244         -        int s1 = (int)(p->iSum >> (sizeof(i64)*8-1));
  1245         -        int s2 = (int)(v       >> (sizeof(i64)*8-1));
  1246         -        int s3 = (int)(iNewSum >> (sizeof(i64)*8-1));
  1247         -        p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0;
  1248         -        p->iSum = iNewSum;
         1242  +      if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
         1243  +        p->overflow = 1;
  1249   1244         }
  1250   1245       }else{
  1251   1246         p->rSum += sqlite3_value_double(argv[0]);
  1252   1247         p->approx = 1;
  1253   1248       }
  1254   1249     }
  1255   1250   }

Changes to src/insert.c.

   461    461     /* Register allocations */
   462    462     int regFromSelect = 0;/* Base register for data coming from SELECT */
   463    463     int regAutoinc = 0;   /* Register holding the AUTOINCREMENT counter */
   464    464     int regRowCount = 0;  /* Memory cell used for the row counter */
   465    465     int regIns;           /* Block of regs holding rowid+data being inserted */
   466    466     int regRowid;         /* registers holding insert rowid */
   467    467     int regData;          /* register holding first column to insert */
   468         -  int regRecord;        /* Holds the assemblied row record */
   469    468     int regEof = 0;       /* Register recording end of SELECT data */
   470    469     int *aRegIdx = 0;     /* One register allocated to each index */
   471    470   
   472    471   #ifndef SQLITE_OMIT_TRIGGER
   473    472     int isView;                 /* True if attempting to insert into a view */
   474    473     Trigger *pTrigger;          /* List of triggers on pTab, if required */
   475    474     int tmask;                  /* Mask of trigger times */
................................................................................
   790    789       addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
   791    790       addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
   792    791     }
   793    792   
   794    793     /* Allocate registers for holding the rowid of the new row,
   795    794     ** the content of the new row, and the assemblied row record.
   796    795     */
   797         -  regRecord = ++pParse->nMem;
   798    796     regRowid = regIns = pParse->nMem+1;
   799    797     pParse->nMem += pTab->nCol + 1;
   800    798     if( IsVirtual(pTab) ){
   801    799       regRowid++;
   802    800       pParse->nMem++;
   803    801     }
   804    802     regData = regRowid+1;
................................................................................
  1184   1182           || onError==OE_Ignore || onError==OE_Replace );
  1185   1183       switch( onError ){
  1186   1184         case OE_Abort:
  1187   1185           sqlite3MayAbort(pParse);
  1188   1186         case OE_Rollback:
  1189   1187         case OE_Fail: {
  1190   1188           char *zMsg;
  1191         -        j1 = sqlite3VdbeAddOp3(v, OP_HaltIfNull,
         1189  +        sqlite3VdbeAddOp3(v, OP_HaltIfNull,
  1192   1190                                     SQLITE_CONSTRAINT, onError, regData+i);
  1193   1191           zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL",
  1194   1192                                 pTab->zName, pTab->aCol[i].zName);
  1195   1193           sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
  1196   1194           break;
  1197   1195         }
  1198   1196         case OE_Ignore: {
................................................................................
  1316   1314   
  1317   1315     /* Test all UNIQUE constraints by creating entries for each UNIQUE
  1318   1316     ** index and making sure that duplicate entries do not already exist.
  1319   1317     ** Add the new records to the indices as we go.
  1320   1318     */
  1321   1319     for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
  1322   1320       int regIdx;
         1321  +#ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT
  1323   1322       int regR;
  1324         -
         1323  +#endif
  1325   1324       if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */
  1326   1325   
  1327   1326       /* Create a key for accessing the index entry */
  1328   1327       regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
  1329   1328       for(i=0; i<pIdx->nColumn; i++){
  1330   1329         int idx = pIdx->aiColumn[i];
  1331   1330         if( idx==pTab->iPKey ){
................................................................................
  1334   1333           sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
  1335   1334         }
  1336   1335       }
  1337   1336       sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
  1338   1337       sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
  1339   1338       sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
  1340   1339       sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
         1340  +
         1341  +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
         1342  +    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
         1343  +    continue;  /* Treat pIdx as if it is not a UNIQUE index */
         1344  +#else
  1341   1345   
  1342   1346       /* Find out what action to take in case there is an indexing conflict */
  1343   1347       onError = pIdx->onError;
  1344   1348       if( onError==OE_None ){ 
  1345   1349         sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
  1346   1350         continue;  /* pIdx is not a UNIQUE index */
  1347   1351       }
................................................................................
  1408   1412           );
  1409   1413           seenReplace = 1;
  1410   1414           break;
  1411   1415         }
  1412   1416       }
  1413   1417       sqlite3VdbeJumpHere(v, j3);
  1414   1418       sqlite3ReleaseTempReg(pParse, regR);
         1419  +#endif
  1415   1420     }
  1416   1421     
  1417   1422     if( pbMayReplace ){
  1418   1423       *pbMayReplace = seenReplace;
  1419   1424     }
  1420   1425   }
  1421   1426   

Changes to src/main.c.

   370    370   
   371    371   #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
   372    372       case SQLITE_CONFIG_HEAP: {
   373    373         /* Designate a buffer for heap memory space */
   374    374         sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
   375    375         sqlite3GlobalConfig.nHeap = va_arg(ap, int);
   376    376         sqlite3GlobalConfig.mnReq = va_arg(ap, int);
          377  +
          378  +      if( sqlite3GlobalConfig.mnReq<1 ){
          379  +        sqlite3GlobalConfig.mnReq = 1;
          380  +      }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){
          381  +        /* cap min request size at 2^12 */
          382  +        sqlite3GlobalConfig.mnReq = (1<<12);
          383  +      }
   377    384   
   378    385         if( sqlite3GlobalConfig.pHeap==0 ){
   379    386           /* If the heap pointer is NULL, then restore the malloc implementation
   380    387           ** back to NULL pointers too.  This will cause the malloc to go
   381    388           ** back to its default implementation when sqlite3_initialize() is
   382    389           ** run.
   383    390           */

Changes to src/mem5.c.

   438    438   **             memsys5Log(4) -> 2
   439    439   **             memsys5Log(5) -> 3
   440    440   **             memsys5Log(8) -> 3
   441    441   **             memsys5Log(9) -> 4
   442    442   */
   443    443   static int memsys5Log(int iValue){
   444    444     int iLog;
   445         -  for(iLog=0; (1<<iLog)<iValue; iLog++);
          445  +  for(iLog=0; (iLog<((sizeof(int)*8)-1)) && (1<<iLog)<iValue; iLog++);
   446    446     return iLog;
   447    447   }
   448    448   
   449    449   /*
   450    450   ** Initialize the memory allocator.
   451    451   **
   452    452   ** This routine is not threadsafe.  The caller must be holding a mutex
................................................................................
   469    469     */
   470    470     assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );
   471    471   
   472    472     nByte = sqlite3GlobalConfig.nHeap;
   473    473     zByte = (u8*)sqlite3GlobalConfig.pHeap;
   474    474     assert( zByte!=0 );  /* sqlite3_config() does not allow otherwise */
   475    475   
          476  +  /* boundaries on sqlite3GlobalConfig.mnReq are enforced in sqlite3_config() */
   476    477     nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq);
   477    478     mem5.szAtom = (1<<nMinLog);
   478    479     while( (int)sizeof(Mem5Link)>mem5.szAtom ){
   479    480       mem5.szAtom = mem5.szAtom << 1;
   480    481     }
   481    482   
   482    483     mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));

Changes to src/mutex_os2.c.

    27     27   /*
    28     28   ** The mutex object
    29     29   ** Each recursive mutex is an instance of the following structure.
    30     30   */
    31     31   struct sqlite3_mutex {
    32     32     HMTX mutex;       /* Mutex controlling the lock */
    33     33     int  id;          /* Mutex type */
    34         -  int  nRef;        /* Number of references */
    35         -  TID  owner;       /* Thread holding this mutex */
           34  +#ifdef SQLITE_DEBUG
           35  + int   trace;       /* True to trace changes */
           36  +#endif
    36     37   };
    37     38   
    38         -#define OS2_MUTEX_INITIALIZER   0,0,0,0
           39  +#ifdef SQLITE_DEBUG
           40  +#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 }
           41  +#else
           42  +#define SQLITE3_MUTEX_INITIALIZER { 0, 0 }
           43  +#endif
    39     44   
    40     45   /*
    41     46   ** Initialize and deinitialize the mutex subsystem.
    42     47   */
    43     48   static int os2MutexInit(void){ return SQLITE_OK; }
    44     49   static int os2MutexEnd(void){ return SQLITE_OK; }
    45     50   
................................................................................
    47     52   ** The sqlite3_mutex_alloc() routine allocates a new
    48     53   ** mutex and returns a pointer to it.  If it returns NULL
    49     54   ** that means that a mutex could not be allocated. 
    50     55   ** SQLite will unwind its stack and return an error.  The argument
    51     56   ** to sqlite3_mutex_alloc() is one of these integer constants:
    52     57   **
    53     58   ** <ul>
    54         -** <li>  SQLITE_MUTEX_FAST               0
    55         -** <li>  SQLITE_MUTEX_RECURSIVE          1
    56         -** <li>  SQLITE_MUTEX_STATIC_MASTER      2
    57         -** <li>  SQLITE_MUTEX_STATIC_MEM         3
    58         -** <li>  SQLITE_MUTEX_STATIC_PRNG        4
           59  +** <li>  SQLITE_MUTEX_FAST
           60  +** <li>  SQLITE_MUTEX_RECURSIVE
           61  +** <li>  SQLITE_MUTEX_STATIC_MASTER
           62  +** <li>  SQLITE_MUTEX_STATIC_MEM
           63  +** <li>  SQLITE_MUTEX_STATIC_MEM2
           64  +** <li>  SQLITE_MUTEX_STATIC_PRNG
           65  +** <li>  SQLITE_MUTEX_STATIC_LRU
           66  +** <li>  SQLITE_MUTEX_STATIC_LRU2
    59     67   ** </ul>
    60     68   **
    61     69   ** The first two constants cause sqlite3_mutex_alloc() to create
    62     70   ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
    63     71   ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
    64     72   ** The mutex implementation does not need to make a distinction
    65     73   ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
    66     74   ** not want to.  But SQLite will only request a recursive mutex in
    67     75   ** cases where it really needs one.  If a faster non-recursive mutex
    68     76   ** implementation is available on the host platform, the mutex subsystem
    69     77   ** might return such a mutex in response to SQLITE_MUTEX_FAST.
    70     78   **
    71     79   ** The other allowed parameters to sqlite3_mutex_alloc() each return
    72         -** a pointer to a static preexisting mutex.  Three static mutexes are
           80  +** a pointer to a static preexisting mutex.  Six static mutexes are
    73     81   ** used by the current version of SQLite.  Future versions of SQLite
    74     82   ** may add additional static mutexes.  Static mutexes are for internal
    75     83   ** use by SQLite only.  Applications that use SQLite mutexes should
    76     84   ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
    77     85   ** SQLITE_MUTEX_RECURSIVE.
    78     86   **
    79     87   ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
................................................................................
    95    103             p = NULL;
    96    104           }
    97    105         }
    98    106         break;
    99    107       }
   100    108       default: {
   101    109         static volatile int isInit = 0;
   102         -      static sqlite3_mutex staticMutexes[] = {
   103         -        { OS2_MUTEX_INITIALIZER, },
   104         -        { OS2_MUTEX_INITIALIZER, },
   105         -        { OS2_MUTEX_INITIALIZER, },
   106         -        { OS2_MUTEX_INITIALIZER, },
   107         -        { OS2_MUTEX_INITIALIZER, },
   108         -        { OS2_MUTEX_INITIALIZER, },
          110  +      static sqlite3_mutex staticMutexes[6] = {
          111  +        SQLITE3_MUTEX_INITIALIZER,
          112  +        SQLITE3_MUTEX_INITIALIZER,
          113  +        SQLITE3_MUTEX_INITIALIZER,
          114  +        SQLITE3_MUTEX_INITIALIZER,
          115  +        SQLITE3_MUTEX_INITIALIZER,
          116  +        SQLITE3_MUTEX_INITIALIZER,
   109    117         };
   110    118         if ( !isInit ){
   111    119           APIRET rc;
   112    120           PTIB ptib;
   113    121           PPIB ppib;
   114    122           HMTX mutex;
   115    123           char name[32];
................................................................................
   147    155   
   148    156   
   149    157   /*
   150    158   ** This routine deallocates a previously allocated mutex.
   151    159   ** SQLite is careful to deallocate every mutex that it allocates.
   152    160   */
   153    161   static void os2MutexFree(sqlite3_mutex *p){
   154         -  if( p==0 ) return;
   155         -  assert( p->nRef==0 );
          162  +#ifdef SQLITE_DEBUG
          163  +  TID tid;
          164  +  PID pid;
          165  +  ULONG ulCount;
          166  +  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
          167  +  assert( ulCount==0 );
   156    168     assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
          169  +#endif
   157    170     DosCloseMutexSem( p->mutex );
   158    171     sqlite3_free( p );
   159    172   }
   160    173   
   161    174   #ifdef SQLITE_DEBUG
   162    175   /*
   163    176   ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
................................................................................
   164    177   ** intended for use inside assert() statements.
   165    178   */
   166    179   static int os2MutexHeld(sqlite3_mutex *p){
   167    180     TID tid;
   168    181     PID pid;
   169    182     ULONG ulCount;
   170    183     PTIB ptib;
   171         -  if( p!=0 ) {
   172         -    DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
   173         -  } else {
   174         -    DosGetInfoBlocks(&ptib, NULL);
   175         -    tid = ptib->tib_ptib2->tib2_ultid;
   176         -  }
   177         -  return p==0 || (p->nRef!=0 && p->owner==tid);
          184  +  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
          185  +  if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) )
          186  +    return 0;
          187  +  DosGetInfoBlocks(&ptib, NULL);
          188  +  return tid==ptib->tib_ptib2->tib2_ultid;
   178    189   }
   179    190   static int os2MutexNotheld(sqlite3_mutex *p){
   180    191     TID tid;
   181    192     PID pid;
   182    193     ULONG ulCount;
   183    194     PTIB ptib;
   184         -  if( p!= 0 ) {
   185         -    DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
   186         -  } else {
   187         -    DosGetInfoBlocks(&ptib, NULL);
   188         -    tid = ptib->tib_ptib2->tib2_ultid;
   189         -  }
   190         -  return p==0 || p->nRef==0 || p->owner!=tid;
          195  +  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
          196  +  if( ulCount==0 )
          197  +    return 1;
          198  +  DosGetInfoBlocks(&ptib, NULL);
          199  +  return tid!=ptib->tib_ptib2->tib2_ultid;
          200  +}
          201  +static void os2MutexTrace(sqlite3_mutex *p, char *pAction){
          202  +  TID   tid;
          203  +  PID   pid;
          204  +  ULONG ulCount;
          205  +  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
          206  +  printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount);
   191    207   }
   192    208   #endif
   193    209   
   194    210   /*
   195    211   ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
   196    212   ** to enter a mutex.  If another thread is already within the mutex,
   197    213   ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
................................................................................
   199    215   ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
   200    216   ** be entered multiple times by the same thread.  In such cases the,
   201    217   ** mutex must be exited an equal number of times before another thread
   202    218   ** can enter.  If the same thread tries to enter any other kind of mutex
   203    219   ** more than once, the behavior is undefined.
   204    220   */
   205    221   static void os2MutexEnter(sqlite3_mutex *p){
   206         -  TID tid;
   207         -  PID holder1;
   208         -  ULONG holder2;
   209         -  if( p==0 ) return;
   210    222     assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
   211    223     DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
   212         -  DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
   213         -  p->owner = tid;
   214         -  p->nRef++;
          224  +#ifdef SQLITE_DEBUG
          225  +  if( p->trace ) os2MutexTrace(p, "enter");
          226  +#endif
   215    227   }
   216    228   static int os2MutexTry(sqlite3_mutex *p){
   217         -  int rc;
   218         -  TID tid;
   219         -  PID holder1;
   220         -  ULONG holder2;
   221         -  if( p==0 ) return SQLITE_OK;
          229  +  int rc = SQLITE_BUSY;
   222    230     assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
   223         -  if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) {
   224         -    DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
   225         -    p->owner = tid;
   226         -    p->nRef++;
          231  +  if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) {
   227    232       rc = SQLITE_OK;
   228         -  } else {
   229         -    rc = SQLITE_BUSY;
          233  +#ifdef SQLITE_DEBUG
          234  +    if( p->trace ) os2MutexTrace(p, "try");
          235  +#endif
   230    236     }
   231         -
   232    237     return rc;
   233    238   }
   234    239   
   235    240   /*
   236    241   ** The sqlite3_mutex_leave() routine exits a mutex that was
   237    242   ** previously entered by the same thread.  The behavior
   238    243   ** is undefined if the mutex is not currently entered or
   239    244   ** is not currently allocated.  SQLite will never do either.
   240    245   */
   241    246   static void os2MutexLeave(sqlite3_mutex *p){
   242         -  TID tid;
   243         -  PID holder1;
   244         -  ULONG holder2;
   245         -  if( p==0 ) return;
   246         -  assert( p->nRef>0 );
   247         -  DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
   248         -  assert( p->owner==tid );
   249         -  p->nRef--;
   250         -  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
          247  +  assert( os2MutexHeld(p) );
   251    248     DosReleaseMutexSem(p->mutex);
          249  +#ifdef SQLITE_DEBUG
          250  +  if( p->trace ) os2MutexTrace(p, "leave");
          251  +#endif
   252    252   }
   253    253   
   254         -sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
          254  +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
   255    255     static const sqlite3_mutex_methods sMutex = {
   256    256       os2MutexInit,
   257    257       os2MutexEnd,
   258    258       os2MutexAlloc,
   259    259       os2MutexFree,
   260    260       os2MutexEnter,
   261    261       os2MutexTry,
   262    262       os2MutexLeave,
   263    263   #ifdef SQLITE_DEBUG
   264    264       os2MutexHeld,
   265    265       os2MutexNotheld
          266  +#else
          267  +    0,
          268  +    0
   266    269   #endif
   267    270     };
   268    271   
   269    272     return &sMutex;
   270    273   }
   271    274   #endif /* SQLITE_MUTEX_OS2 */

Changes to src/mutex_w32.c.

   276    276       rc = SQLITE_OK;
   277    277     }
   278    278   #else
   279    279     UNUSED_PARAMETER(p);
   280    280   #endif
   281    281   #ifdef SQLITE_DEBUG
   282    282     if( rc==SQLITE_OK && p->trace ){
   283         -    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
          283  +    printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   284    284     }
   285    285   #endif
   286    286     return rc;
   287    287   }
   288    288   
   289    289   /*
   290    290   ** The sqlite3_mutex_leave() routine exits a mutex that was

Changes to src/os_os2.c.

   642    642   }
   643    643   
   644    644   /*
   645    645   ** This vector defines all the methods that can operate on an
   646    646   ** sqlite3_file for os2.
   647    647   */
   648    648   static const sqlite3_io_methods os2IoMethod = {
   649         -  1,                        /* iVersion */
   650         -  os2Close,
   651         -  os2Read,
   652         -  os2Write,
   653         -  os2Truncate,
   654         -  os2Sync,
   655         -  os2FileSize,
   656         -  os2Lock,
   657         -  os2Unlock,
   658         -  os2CheckReservedLock,
   659         -  os2FileControl,
   660         -  os2SectorSize,
   661         -  os2DeviceCharacteristics
          649  +  1,                              /* iVersion */
          650  +  os2Close,                       /* xClose */
          651  +  os2Read,                        /* xRead */
          652  +  os2Write,                       /* xWrite */
          653  +  os2Truncate,                    /* xTruncate */
          654  +  os2Sync,                        /* xSync */
          655  +  os2FileSize,                    /* xFileSize */
          656  +  os2Lock,                        /* xLock */
          657  +  os2Unlock,                      /* xUnlock */
          658  +  os2CheckReservedLock,           /* xCheckReservedLock */
          659  +  os2FileControl,                 /* xFileControl */
          660  +  os2SectorSize,                  /* xSectorSize */
          661  +  os2DeviceCharacteristics,       /* xDeviceCharacteristics */
          662  +  0,                              /* xShmMap */
          663  +  0,                              /* xShmLock */
          664  +  0,                              /* xShmBarrier */
          665  +  0                               /* xShmUnmap */
   662    666   };
   663    667   
   664    668   /***************************************************************************
   665    669   ** Here ends the I/O methods that form the sqlite3_io_methods object.
   666    670   **
   667    671   ** The next block of code implements the VFS methods.
   668    672   ****************************************************************************/
................................................................................
   746    750   
   747    751   
   748    752   /*
   749    753   ** Open a file.
   750    754   */
   751    755   static int os2Open(
   752    756     sqlite3_vfs *pVfs,            /* Not used */
   753         -  const char *zName,            /* Name of the file */
          757  +  const char *zName,            /* Name of the file (UTF-8) */
   754    758     sqlite3_file *id,             /* Write the SQLite file handle here */
   755    759     int flags,                    /* Open mode flags */
   756    760     int *pOutFlags                /* Status return flags */
   757    761   ){
   758    762     HFILE h;
   759         -  ULONG ulFileAttribute = FILE_NORMAL;
   760    763     ULONG ulOpenFlags = 0;
   761    764     ULONG ulOpenMode = 0;
          765  +  ULONG ulAction = 0;
          766  +  ULONG rc;
   762    767     os2File *pFile = (os2File*)id;
   763         -  APIRET rc = NO_ERROR;
   764         -  ULONG ulAction;
          768  +  const char *zUtf8Name = zName;
   765    769     char *zNameCp;
   766         -  char zTmpname[CCHMAXPATH+1];    /* Buffer to hold name of temp file */
          770  +  char  zTmpname[CCHMAXPATH];
          771  +
          772  +  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
          773  +  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
          774  +  int isCreate     = (flags & SQLITE_OPEN_CREATE);
          775  +  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
          776  +#ifndef NDEBUG
          777  +  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
          778  +  int eType        = (flags & 0xFFFFFF00);
          779  +  int isOpenJournal = (isCreate && (
          780  +        eType==SQLITE_OPEN_MASTER_JOURNAL 
          781  +     || eType==SQLITE_OPEN_MAIN_JOURNAL 
          782  +     || eType==SQLITE_OPEN_WAL
          783  +  ));
          784  +#endif
          785  +
          786  +  UNUSED_PARAMETER(pVfs);
          787  +  assert( id!=0 );
          788  +
          789  +  /* Check the following statements are true: 
          790  +  **
          791  +  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
          792  +  **   (b) if CREATE is set, then READWRITE must also be set, and
          793  +  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
          794  +  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
          795  +  */
          796  +  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
          797  +  assert(isCreate==0 || isReadWrite);
          798  +  assert(isExclusive==0 || isCreate);
          799  +  assert(isDelete==0 || isCreate);
          800  +
          801  +  /* The main DB, main journal, WAL file and master journal are never 
          802  +  ** automatically deleted. Nor are they ever temporary files.  */
          803  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
          804  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
          805  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
          806  +  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
          807  +
          808  +  /* Assert that the upper layer has set one of the "file-type" flags. */
          809  +  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
          810  +       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
          811  +       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
          812  +       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
          813  +  );
          814  +
          815  +  memset( pFile, 0, sizeof(*pFile) );
          816  +  pFile->pMethod = &os2IoMethod;
   767    817   
   768    818     /* If the second argument to this function is NULL, generate a 
   769    819     ** temporary file name to use 
   770    820     */
   771         -  if( !zName ){
   772         -    int rc = getTempname(CCHMAXPATH+1, zTmpname);
          821  +  if( !zUtf8Name ){
          822  +    assert(isDelete && !isOpenJournal);
          823  +    rc = getTempname(CCHMAXPATH, zTmpname);
   773    824       if( rc!=SQLITE_OK ){
   774    825         return rc;
   775    826       }
   776         -    zName = zTmpname;
          827  +    zUtf8Name = zTmpname;
   777    828     }
   778    829   
   779         -
   780         -  memset( pFile, 0, sizeof(*pFile) );
   781         -
   782         -  OSTRACE(( "OPEN want %d\n", flags ));
   783         -
   784         -  if( flags & SQLITE_OPEN_READWRITE ){
          830  +  if( isReadWrite ){
   785    831       ulOpenMode |= OPEN_ACCESS_READWRITE;
   786         -    OSTRACE(( "OPEN read/write\n" ));
   787    832     }else{
   788    833       ulOpenMode |= OPEN_ACCESS_READONLY;
   789         -    OSTRACE(( "OPEN read only\n" ));
   790    834     }
   791    835   
   792         -  if( flags & SQLITE_OPEN_CREATE ){
   793         -    ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
   794         -    OSTRACE(( "OPEN open new/create\n" ));
   795         -  }else{
   796         -    ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
   797         -    OSTRACE(( "OPEN open existing\n" ));
   798         -  }
   799         -
   800         -  if( flags & SQLITE_OPEN_MAIN_DB ){
   801         -    ulOpenMode |= OPEN_SHARE_DENYNONE;
   802         -    OSTRACE(( "OPEN share read/write\n" ));
   803         -  }else{
   804         -    ulOpenMode |= OPEN_SHARE_DENYWRITE;
   805         -    OSTRACE(( "OPEN share read only\n" ));
   806         -  }
   807         -
   808         -  if( flags & SQLITE_OPEN_DELETEONCLOSE ){
   809         -    char pathUtf8[CCHMAXPATH];
   810         -#ifdef NDEBUG /* when debugging we want to make sure it is deleted */
   811         -    ulFileAttribute = FILE_HIDDEN;
   812         -#endif
   813         -    os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 );
   814         -    pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
   815         -    OSTRACE(( "OPEN hidden/delete on close file attributes\n" ));
   816         -  }else{
   817         -    pFile->pathToDel = NULL;
   818         -    OSTRACE(( "OPEN normal file attribute\n" ));
   819         -  }
   820         -
   821         -  /* always open in random access mode for possibly better speed */
          836  +  /* Open in random access mode for possibly better speed.  Allow full
          837  +  ** sharing because file locks will provide exclusive access when needed.
          838  +  */
   822    839     ulOpenMode |= OPEN_FLAGS_RANDOM;
   823    840     ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
   824    841     ulOpenMode |= OPEN_FLAGS_NOINHERIT;
          842  +  ulOpenMode |= OPEN_SHARE_DENYNONE;
   825    843   
   826         -  zNameCp = convertUtf8PathToCp( zName );
          844  +  /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 
          845  +  ** created. SQLite doesn't use it to indicate "exclusive access" 
          846  +  ** as it is usually understood.
          847  +  */
          848  +  if( isExclusive ){
          849  +    /* Creates a new file, only if it does not already exist. */
          850  +    /* If the file exists, it fails. */
          851  +    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
          852  +  }else if( isCreate ){
          853  +    /* Open existing file, or create if it doesn't exist */
          854  +    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
          855  +  }else{
          856  +    /* Opens a file, only if it exists. */
          857  +    ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
          858  +  }
          859  +
          860  +  /* For DELETEONCLOSE, save a pointer to the converted filename */
          861  +  if( isDelete ){
          862  +    char pathUtf8[CCHMAXPATH];
          863  +    os2FullPathname( pVfs, zUtf8Name, CCHMAXPATH, pathUtf8 );
          864  +    pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
          865  +  }
          866  +
          867  +  zNameCp = convertUtf8PathToCp( zUtf8Name );
   827    868     rc = DosOpen( (PSZ)zNameCp,
   828    869                   &h,
   829    870                   &ulAction,
   830    871                   0L,
   831         -                ulFileAttribute,
          872  +                FILE_NORMAL,
   832    873                   ulOpenFlags,
   833    874                   ulOpenMode,
   834    875                   (PEAOP2)NULL );
   835    876     free( zNameCp );
          877  +
   836    878     if( rc != NO_ERROR ){
   837         -    OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
   838         -              rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ));
          879  +    OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
          880  +              rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
   839    881       if( pFile->pathToDel )
   840    882         free( pFile->pathToDel );
   841    883       pFile->pathToDel = NULL;
   842         -    if( flags & SQLITE_OPEN_READWRITE ){
   843         -      OSTRACE(( "OPEN %d Invalid handle\n",
   844         -                ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) ));
          884  +
          885  +    if( isReadWrite ){
   845    886         return os2Open( pVfs, zName, id,
   846         -                      ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE),
          887  +                      ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
   847    888                         pOutFlags );
   848    889       }else{
   849    890         return SQLITE_CANTOPEN;
   850    891       }
   851    892     }
   852    893   
   853    894     if( pOutFlags ){
   854         -    *pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
          895  +    *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
   855    896     }
   856    897   
   857         -  pFile->pMethod = &os2IoMethod;
   858    898     pFile->h = h;
   859    899     OpenCounter(+1);
   860    900     OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
   861    901     return SQLITE_OK;
   862    902   }
   863    903   
   864    904   /*
................................................................................
   865    905   ** Delete the named file.
   866    906   */
   867    907   static int os2Delete(
   868    908     sqlite3_vfs *pVfs,                     /* Not used on os2 */
   869    909     const char *zFilename,                 /* Name of file to delete */
   870    910     int syncDir                            /* Not used on os2 */
   871    911   ){
   872         -  APIRET rc = NO_ERROR;
   873         -  char *zFilenameCp = convertUtf8PathToCp( zFilename );
          912  +  APIRET rc;
          913  +  char *zFilenameCp;
   874    914     SimulateIOError( return SQLITE_IOERR_DELETE );
          915  +  zFilenameCp = convertUtf8PathToCp( zFilename );
   875    916     rc = DosDelete( (PSZ)zFilenameCp );
   876    917     free( zFilenameCp );
   877    918     OSTRACE(( "DELETE \"%s\"\n", zFilename ));
   878         -  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_DELETE;
          919  +  return (rc == NO_ERROR ||
          920  +          rc == ERROR_FILE_NOT_FOUND ||
          921  +          rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE;
   879    922   }
   880    923   
   881    924   /*
   882    925   ** Check the existance and status of a file.
   883    926   */
   884    927   static int os2Access(
   885    928     sqlite3_vfs *pVfs,        /* Not used on os2 */
................................................................................
   936    979   /*
   937    980   ** A no-op since the error code is returned on the DosLoadModule call.
   938    981   ** os2Dlopen returns zero if DosLoadModule is not successful.
   939    982   */
   940    983   static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
   941    984   /* no-op */
   942    985   }
   943         -static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
          986  +static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
   944    987     PFN pfn;
   945    988     APIRET rc;
   946    989     rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);
   947    990     if( rc != NO_ERROR ){
   948    991       /* if the symbol itself was not found, search again for the same
   949    992        * symbol with an extra underscore, that might be needed depending
   950    993        * on the calling convention */
   951    994       char _zSymbol[256] = "_";
   952    995       strncat(_zSymbol, zSymbol, 255);
   953    996       rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn);
   954    997     }
   955         -  return rc != NO_ERROR ? 0 : (void*)pfn;
          998  +  return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
   956    999   }
   957   1000   static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
   958   1001     DosFreeModule((HMODULE)pHandle);
   959   1002   }
   960   1003   #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
   961   1004     #define os2DlOpen 0
   962   1005     #define os2DlError 0
................................................................................
  1052   1095   ** Find the current time (in Universal Coordinated Time).  Write the
  1053   1096   ** current time and date as a Julian Day number into *prNow and
  1054   1097   ** return 0.  Return 1 if the time and date cannot be found.
  1055   1098   */
  1056   1099   int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
  1057   1100     double now;
  1058   1101     SHORT minute; /* needs to be able to cope with negative timezone offset */
  1059         -  USHORT second, hour,
         1102  +  USHORT hundredths, second, hour,
  1060   1103            day, month, year;
  1061   1104     DATETIME dt;
  1062   1105     DosGetDateTime( &dt );
         1106  +  hundredths = (USHORT)dt.hundredths;
  1063   1107     second = (USHORT)dt.seconds;
  1064   1108     minute = (SHORT)dt.minutes + dt.timezone;
  1065   1109     hour = (USHORT)dt.hours;
  1066   1110     day = (USHORT)dt.day;
  1067   1111     month = (USHORT)dt.month;
  1068   1112     year = (USHORT)dt.year;
  1069   1113   
................................................................................
  1075   1119       367*(month - 2 - (month - 14)/12*12)/12 -
  1076   1120       3*((year + 4900 + (month - 14)/12)/100)/4;
  1077   1121   
  1078   1122     /* Add the fractional hours, mins and seconds */
  1079   1123     now += (hour + 12.0)/24.0;
  1080   1124     now += minute/1440.0;
  1081   1125     now += second/86400.0;
         1126  +  now += hundredths/8640000.0;
  1082   1127     *prNow = now;
  1083   1128   #ifdef SQLITE_TEST
  1084   1129     if( sqlite3_current_time ){
  1085   1130       *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  1086   1131     }
  1087   1132   #endif
  1088   1133     return 0;
  1089   1134   }
         1135  +
         1136  +/*
         1137  +** Find the current time (in Universal Coordinated Time).  Write into *piNow
         1138  +** the current time and date as a Julian Day number times 86_400_000.  In
         1139  +** other words, write into *piNow the number of milliseconds since the Julian
         1140  +** epoch of noon in Greenwich on November 24, 4714 B.C according to the
         1141  +** proleptic Gregorian calendar.
         1142  +**
         1143  +** On success, return 0.  Return 1 if the time and date cannot be found.
         1144  +*/
         1145  +static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
         1146  +  double now;
         1147  +  os2CurrentTime(pVfs, &now);
         1148  +  *piNow = now * 86400000;
         1149  +  return 0;
         1150  +}
  1090   1151   
  1091   1152   static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
  1092   1153     return 0;
  1093   1154   }
  1094   1155   
  1095   1156   /*
  1096   1157   ** Initialize and deinitialize the operating system interface.
  1097   1158   */
  1098   1159   int sqlite3_os_init(void){
  1099   1160     static sqlite3_vfs os2Vfs = {
  1100         -    1,                 /* iVersion */
         1161  +    3,                 /* iVersion */
  1101   1162       sizeof(os2File),   /* szOsFile */
  1102   1163       CCHMAXPATH,        /* mxPathname */
  1103   1164       0,                 /* pNext */
  1104   1165       "os2",             /* zName */
  1105   1166       0,                 /* pAppData */
  1106   1167   
  1107   1168       os2Open,           /* xOpen */
................................................................................
  1112   1173       os2DlError,        /* xDlError */
  1113   1174       os2DlSym,          /* xDlSym */
  1114   1175       os2DlClose,        /* xDlClose */
  1115   1176       os2Randomness,     /* xRandomness */
  1116   1177       os2Sleep,          /* xSleep */
  1117   1178       os2CurrentTime,    /* xCurrentTime */
  1118   1179       os2GetLastError,   /* xGetLastError */
         1180  +    os2CurrentTimeInt64 /* xCurrentTimeInt64 */
         1181  +    0,                 /* xSetSystemCall */
         1182  +    0,                 /* xGetSystemCall */
         1183  +    0,                 /* xNextSystemCall */
  1119   1184     };
  1120   1185     sqlite3_vfs_register(&os2Vfs, 1);
  1121   1186     initUconvObjects();
  1122   1187     return SQLITE_OK;
  1123   1188   }
  1124   1189   int sqlite3_os_end(void){
  1125   1190     freeUconvObjects();
  1126   1191     return SQLITE_OK;
  1127   1192   }
  1128   1193   
  1129   1194   #endif /* SQLITE_OS_OS2 */

Changes to src/os_unix.c.

   202    202   typedef struct unixFile unixFile;
   203    203   struct unixFile {
   204    204     sqlite3_io_methods const *pMethod;  /* Always the first entry */
   205    205     unixInodeInfo *pInode;              /* Info about locks on this inode */
   206    206     int h;                              /* The file descriptor */
   207    207     int dirfd;                          /* File descriptor for the directory */
   208    208     unsigned char eFileLock;            /* The type of lock held on this fd */
          209  +  unsigned char ctrlFlags;            /* Behavioral bits.  UNIXFILE_* flags */
   209    210     int lastErrno;                      /* The unix errno from last I/O error */
   210    211     void *lockingContext;               /* Locking style specific state */
   211    212     UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
   212         -  int fileFlags;                      /* Miscellanous flags */
   213    213     const char *zPath;                  /* Name of the file */
   214    214     unixShm *pShm;                      /* Shared memory segment information */
   215    215     int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
   216    216   #if SQLITE_ENABLE_LOCKING_STYLE
   217    217     int openFlags;                      /* The flags specified at open() */
   218    218   #endif
   219    219   #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
................................................................................
   240    240     ** it is larger than the struct CrashFile defined in test6.c.
   241    241     */
   242    242     char aPadding[32];
   243    243   #endif
   244    244   };
   245    245   
   246    246   /*
   247         -** The following macros define bits in unixFile.fileFlags
          247  +** Allowed values for the unixFile.ctrlFlags bitmask:
   248    248   */
   249         -#define SQLITE_WHOLE_FILE_LOCKING  0x0001   /* Use whole-file locking */
          249  +#define UNIXFILE_EXCL   0x01     /* Connections from one process only */
          250  +#define UNIXFILE_RDONLY 0x02     /* Connection is read only */
   250    251   
   251    252   /*
   252    253   ** Include code that is common to all os_*.c files
   253    254   */
   254    255   #include "os_common.h"
   255    256   
   256    257   /*
................................................................................
   266    267   #ifndef O_NOFOLLOW
   267    268   # define O_NOFOLLOW 0
   268    269   #endif
   269    270   #ifndef O_BINARY
   270    271   # define O_BINARY 0
   271    272   #endif
   272    273   
   273         -/*
   274         -** The DJGPP compiler environment looks mostly like Unix, but it
   275         -** lacks the fcntl() system call.  So redefine fcntl() to be something
   276         -** that always succeeds.  This means that locking does not occur under
   277         -** DJGPP.  But it is DOS - what did you expect?
   278         -*/
   279         -#ifdef __DJGPP__
   280         -# define fcntl(A,B,C) 0
   281         -#endif
   282         -
   283    274   /*
   284    275   ** The threadid macro resolves to the thread-id or to 0.  Used for
   285    276   ** testing and debugging only.
   286    277   */
   287    278   #if SQLITE_THREADSAFE
   288    279   #define threadid pthread_self()
   289    280   #else
   290    281   #define threadid 0
   291    282   #endif
   292    283   
          284  +/*
          285  +** Many system calls are accessed through pointer-to-functions so that
          286  +** they may be overridden at runtime to facilitate fault injection during
          287  +** testing and sandboxing.  The following array holds the names and pointers
          288  +** to all overrideable system calls.
          289  +*/
          290  +static struct unix_syscall {
          291  +  const char *zName;      /* Name of the sytem call */
          292  +  void *pCurrent;         /* Current value of the system call */
          293  +  void *pDefault;         /* Default value */
          294  +} aSyscall[] = {
          295  +  { "open",         (void*)open,       0  },
          296  +#define osOpen      ((int(*)(const char*,int,int))aSyscall[0].pCurrent)
          297  +
          298  +  { "close",        (void*)close,      0  },
          299  +#define osClose     ((int(*)(int))aSyscall[1].pCurrent)
          300  +
          301  +  { "access",       (void*)access,     0  },
          302  +#define osAccess    ((int(*)(const char*,int))aSyscall[2].pCurrent)
          303  +
          304  +  { "getcwd",       (void*)getcwd,     0  },
          305  +#define osGetcwd    ((char*(*)(char*,size_t))aSyscall[3].pCurrent)
          306  +
          307  +  { "stat",         (void*)stat,       0  },
          308  +#define osStat      ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent)
          309  +
          310  +/*
          311  +** The DJGPP compiler environment looks mostly like Unix, but it
          312  +** lacks the fcntl() system call.  So redefine fcntl() to be something
          313  +** that always succeeds.  This means that locking does not occur under
          314  +** DJGPP.  But it is DOS - what did you expect?
          315  +*/
          316  +#ifdef __DJGPP__
          317  +  { "fstat",        0,                 0  },
          318  +#define osFstat(a,b,c)    0
          319  +#else     
          320  +  { "fstat",        (void*)fstat,      0  },
          321  +#define osFstat     ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
          322  +#endif
          323  +
          324  +  { "ftruncate",    (void*)ftruncate,  0  },
          325  +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent)
          326  +
          327  +  { "fcntl",        (void*)fcntl,      0  },
          328  +#define osFcntl     ((int(*)(int,int,...))aSyscall[7].pCurrent)
          329  +
          330  +  { "read",         (void*)read,       0  },
          331  +#define osRead      ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
          332  +
          333  +#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE)
          334  +  { "pread",        (void*)pread,      0  },
          335  +#else
          336  +  { "pread",        (void*)0,          0  },
          337  +#endif
          338  +#define osPread     ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent)
          339  +
          340  +#if defined(USE_PREAD64)
          341  +  { "pread64",      (void*)pread64,    0  },
          342  +#else
          343  +  { "pread64",      (void*)0,          0  },
          344  +#endif
          345  +#define osPread64   ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
          346  +
          347  +  { "write",        (void*)write,      0  },
          348  +#define osWrite     ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
          349  +
          350  +#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE)
          351  +  { "pwrite",       (void*)pwrite,     0  },
          352  +#else
          353  +  { "pwrite",       (void*)0,          0  },
          354  +#endif
          355  +#define osPwrite    ((ssize_t(*)(int,const void*,size_t,off_t))\
          356  +                    aSyscall[12].pCurrent)
          357  +
          358  +#if defined(USE_PREAD64)
          359  +  { "pwrite64",     (void*)pwrite64,   0  },
          360  +#else
          361  +  { "pwrite64",     (void*)0,          0  },
          362  +#endif
          363  +#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
          364  +                    aSyscall[13].pCurrent)
          365  +
          366  +  { "fchmod",       (void*)fchmod,     0  },
          367  +#define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)
          368  +
          369  +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
          370  +  { "fallocate",    (void*)posix_fallocate,  0 },
          371  +#else
          372  +  { "fallocate",    (void*)0,                0 },
          373  +#endif
          374  +#define osFallocate ((int(*)(int,off_t,off_t)aSyscall[15].pCurrent)
          375  +
          376  +}; /* End of the overrideable system calls */
          377  +
          378  +/*
          379  +** This is the xSetSystemCall() method of sqlite3_vfs for all of the
          380  +** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
          381  +** system call pointer, or SQLITE_NOTFOUND if there is no configurable
          382  +** system call named zName.
          383  +*/
          384  +static int unixSetSystemCall(
          385  +  sqlite3_vfs *pNotUsed,     /* The VFS pointer.  Not used */
          386  +  const char *zName,         /* Name of system call to override */
          387  +  void *pNewFunc             /* Pointer to new system call value */
          388  +){
          389  +  int i;
          390  +  int rc = SQLITE_NOTFOUND;
          391  +  if( zName==0 ){
          392  +    /* If no zName is given, restore all system calls to their default
          393  +    ** settings and return NULL
          394  +    */
          395  +    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
          396  +      if( aSyscall[i].pDefault ){
          397  +        aSyscall[i].pCurrent = aSyscall[i].pDefault;
          398  +        rc = SQLITE_OK;
          399  +      }
          400  +    }
          401  +  }else{
          402  +    /* If zName is specified, operate on only the one system call
          403  +    ** specified.
          404  +    */
          405  +    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
          406  +      if( strcmp(zName, aSyscall[i].zName)==0 ){
          407  +        if( aSyscall[i].pDefault==0 ){
          408  +          aSyscall[i].pDefault = aSyscall[i].pCurrent;
          409  +        }
          410  +        rc = SQLITE_OK;
          411  +        if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
          412  +        aSyscall[i].pCurrent = pNewFunc;
          413  +        break;
          414  +      }
          415  +    }
          416  +  }
          417  +  return rc;
          418  +}
          419  +
          420  +/*
          421  +** Return the value of a system call.  Return NULL if zName is not a
          422  +** recognized system call name.  NULL is also returned if the system call
          423  +** is currently undefined.
          424  +*/
          425  +static void *unixGetSystemCall(sqlite3_vfs *pNotUsed, const char *zName){
          426  +  int i;
          427  +  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
          428  +    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
          429  +  }
          430  +  return 0;
          431  +}
          432  +
          433  +/*
          434  +** Return the name of the first system call after zName.  If zName==NULL
          435  +** then return the name of the first system call.  Return NULL if zName
          436  +** is the last system call or if zName is not the name of a valid
          437  +** system call.
          438  +*/
          439  +static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
          440  +  int i;
          441  +  if( zName==0 ){
          442  +    i = -1;
          443  +  }else{
          444  +    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0])-1; i++){
          445  +      if( strcmp(zName, aSyscall[0].zName)==0 ) break;
          446  +    }
          447  +  }
          448  +  for(i++; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
          449  +    if( aSyscall[0].pCurrent!=0 ) return aSyscall[0].zName;
          450  +  }
          451  +  return 0;
          452  +}
          453  +
          454  +/*
          455  +** Retry open() calls that fail due to EINTR
          456  +*/
          457  +static int robust_open(const char *z, int f, int m){
          458  +  int rc;
          459  +  do{ rc = osOpen(z,f,m); }while( rc<0 && errno==EINTR );
          460  +  return rc;
          461  +}
   293    462   
   294    463   /*
   295    464   ** Helper functions to obtain and relinquish the global mutex. The
   296    465   ** global mutex is used to protect the unixInodeInfo and
   297    466   ** vxworksFileId objects used by this file, all of which may be 
   298    467   ** shared by multiple threads.
   299    468   **
................................................................................
   350    519     int s;
   351    520     int savedErrno;
   352    521     if( op==F_GETLK ){
   353    522       zOpName = "GETLK";
   354    523     }else if( op==F_SETLK ){
   355    524       zOpName = "SETLK";
   356    525     }else{
   357         -    s = fcntl(fd, op, p);
          526  +    s = osFcntl(fd, op, p);
   358    527       sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);
   359    528       return s;
   360    529     }
   361    530     if( p->l_type==F_RDLCK ){
   362    531       zType = "RDLCK";
   363    532     }else if( p->l_type==F_WRLCK ){
   364    533       zType = "WRLCK";
   365    534     }else if( p->l_type==F_UNLCK ){
   366    535       zType = "UNLCK";
   367    536     }else{
   368    537       assert( 0 );
   369    538     }
   370    539     assert( p->l_whence==SEEK_SET );
   371         -  s = fcntl(fd, op, p);
          540  +  s = osFcntl(fd, op, p);
   372    541     savedErrno = errno;
   373    542     sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
   374    543        threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
   375    544        (int)p->l_pid, s);
   376    545     if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
   377    546       struct flock l2;
   378    547       l2 = *p;
   379         -    fcntl(fd, F_GETLK, &l2);
          548  +    osFcntl(fd, F_GETLK, &l2);
   380    549       if( l2.l_type==F_RDLCK ){
   381    550         zType = "RDLCK";
   382    551       }else if( l2.l_type==F_WRLCK ){
   383    552         zType = "WRLCK";
   384    553       }else if( l2.l_type==F_UNLCK ){
   385    554         zType = "UNLCK";
   386    555       }else{
................................................................................
   388    557       }
   389    558       sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",
   390    559          zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);
   391    560     }
   392    561     errno = savedErrno;
   393    562     return s;
   394    563   }
   395         -#define fcntl lockTrace
          564  +#undef osFcntl
          565  +#define osFcntl lockTrace
   396    566   #endif /* SQLITE_LOCK_TRACE */
   397         -
   398    567   
   399    568   /*
   400    569   ** Retry ftruncate() calls that fail due to EINTR
   401    570   */
   402         -#ifdef EINTR
   403    571   static int robust_ftruncate(int h, sqlite3_int64 sz){
   404    572     int rc;
   405         -  do{ rc = ftruncate(h,sz); }while( rc<0 && errno==EINTR );
          573  +  do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR );
   406    574     return rc;
   407    575   }
   408         -#else
   409         -# define robust_ftruncate(a,b) ftruncate(a,b)
   410         -#endif 
   411         -
   412    576   
   413    577   /*
   414    578   ** This routine translates a standard POSIX errno code into something
   415    579   ** useful to the clients of the sqlite3 functions.  Specifically, it is
   416    580   ** intended to translate a variety of "try again" errors into SQLITE_BUSY
   417    581   ** and a variety of "please close the file descriptor NOW" errors into 
   418    582   ** SQLITE_IOERR
................................................................................
   726    890   ** A single inode can have multiple file descriptors, so each unixFile
   727    891   ** structure contains a pointer to an instance of this object and this
   728    892   ** object keeps a count of the number of unixFile pointing to it.
   729    893   */
   730    894   struct unixInodeInfo {
   731    895     struct unixFileId fileId;       /* The lookup key */
   732    896     int nShared;                    /* Number of SHARED locks held */
   733         -  int eFileLock;                  /* One of SHARED_LOCK, RESERVED_LOCK etc. */
          897  +  unsigned char eFileLock;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
          898  +  unsigned char bProcessLock;     /* An exclusive process lock is held */
   734    899     int nRef;                       /* Number of pointers to this structure */
   735    900     unixShmNode *pShmNode;          /* Shared memory associated with this inode */
   736    901     int nLock;                      /* Number of outstanding file locks */
   737    902     UnixUnusedFd *pUnused;          /* Unused file descriptors to close */
   738    903     unixInodeInfo *pNext;           /* List of all unixInodeInfo objects */
   739    904     unixInodeInfo *pPrev;           /*    .... doubly linked */
   740    905   #if defined(SQLITE_ENABLE_LOCKING_STYLE)
................................................................................
   763    928   **
   764    929   ** The first argument passed to the macro should be the error code that
   765    930   ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 
   766    931   ** The two subsequent arguments should be the name of the OS function that
   767    932   ** failed (e.g. "unlink", "open") and the the associated file-system path,
   768    933   ** if any.
   769    934   */
   770         -#define unixLogError(a,b,c)     unixLogError_x(a,b,c,__LINE__)
   771         -static int unixLogError_x(
          935  +#define unixLogError(a,b,c)     unixLogErrorAtLine(a,b,c,__LINE__)
          936  +static int unixLogErrorAtLine(
   772    937     int errcode,                    /* SQLite error code */
   773    938     const char *zFunc,              /* Name of OS function that failed */
   774    939     const char *zPath,              /* File path associated with error */
   775    940     int iLine                       /* Source line number where error occurred */
   776    941   ){
   777    942     char *zErr;                     /* Message from strerror() or equivalent */
          943  +  int iErrno = errno;             /* Saved syscall error number */
   778    944   
   779    945     /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
   780    946     ** the strerror() function to obtain the human-readable error message
   781    947     ** equivalent to errno. Otherwise, use strerror_r().
   782    948     */ 
   783    949   #if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R)
   784    950     char aErr[80];
................................................................................
   796    962     ** available, the error message will often be an empty string. Not a
   797    963     ** huge problem. Incorrectly concluding that the GNU version is available 
   798    964     ** could lead to a segfault though.
   799    965     */
   800    966   #if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
   801    967     zErr = 
   802    968   # endif
   803         -  strerror_r(errno, aErr, sizeof(aErr)-1);
          969  +  strerror_r(iErrno, aErr, sizeof(aErr)-1);
   804    970   
   805    971   #elif SQLITE_THREADSAFE
   806    972     /* This is a threadsafe build, but strerror_r() is not available. */
   807    973     zErr = "";
   808    974   #else
   809    975     /* Non-threadsafe build, use strerror(). */
   810         -  zErr = strerror(errno);
          976  +  zErr = strerror(iErrno);
   811    977   #endif
   812    978   
   813    979     assert( errcode!=SQLITE_OK );
          980  +  if( zPath==0 ) zPath = "";
   814    981     sqlite3_log(errcode,
   815         -      "os_unix.c: %s() at line %d - \"%s\" errno=%d path=%s",
   816         -      zFunc, iLine, zErr, errno, (zPath ? zPath : "n/a")
          982  +      "os_unix.c:%d: (%d) %s(%s) - %s",
          983  +      iLine, iErrno, zFunc, zPath, zErr
   817    984     );
   818    985   
   819    986     return errcode;
   820    987   }
   821    988   
          989  +/*
          990  +** Close a file descriptor.
          991  +**
          992  +** We assume that close() almost always works, since it is only in a
          993  +** very sick application or on a very sick platform that it might fail.
          994  +** If it does fail, simply leak the file descriptor, but do log the
          995  +** error.
          996  +**
          997  +** Note that it is not safe to retry close() after EINTR since the
          998  +** file descriptor might have already been reused by another thread.
          999  +** So we don't even try to recover from an EINTR.  Just log the error
         1000  +** and move on.
         1001  +*/
         1002  +static void robust_close(unixFile *pFile, int h, int lineno){
         1003  +  if( osClose(h) ){
         1004  +    unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close",
         1005  +                       pFile ? pFile->zPath : 0, lineno);
         1006  +  }
         1007  +}
   822   1008   
   823   1009   /*
   824   1010   ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
   825         -** If all such file descriptors are closed without error, the list is
   826         -** cleared and SQLITE_OK returned.
   827         -**
   828         -** Otherwise, if an error occurs, then successfully closed file descriptor
   829         -** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. 
   830         -** not deleted and SQLITE_IOERR_CLOSE returned.
   831   1011   */ 
   832         -static int closePendingFds(unixFile *pFile){
   833         -  int rc = SQLITE_OK;
         1012  +static void closePendingFds(unixFile *pFile){
   834   1013     unixInodeInfo *pInode = pFile->pInode;
   835         -  UnixUnusedFd *pError = 0;
   836   1014     UnixUnusedFd *p;
   837   1015     UnixUnusedFd *pNext;
   838   1016     for(p=pInode->pUnused; p; p=pNext){
   839   1017       pNext = p->pNext;
   840         -    if( close(p->fd) ){
   841         -      pFile->lastErrno = errno;
   842         -      rc = unixLogError(SQLITE_IOERR_CLOSE, "close", pFile->zPath);
   843         -      p->pNext = pError;
   844         -      pError = p;
   845         -    }else{
   846         -      sqlite3_free(p);
   847         -    }
         1018  +    robust_close(pFile, p->fd, __LINE__);
         1019  +    sqlite3_free(p);
   848   1020     }
   849         -  pInode->pUnused = pError;
   850         -  return rc;
         1021  +  pInode->pUnused = 0;
   851   1022   }
   852   1023   
   853   1024   /*
   854   1025   ** Release a unixInodeInfo structure previously allocated by findInodeInfo().
   855   1026   **
   856   1027   ** The mutex entered using the unixEnterMutex() function must be held
   857   1028   ** when this function is called.
................................................................................
   902   1073   
   903   1074     assert( unixMutexHeld() );
   904   1075   
   905   1076     /* Get low-level information about the file that we can used to
   906   1077     ** create a unique name for the file.
   907   1078     */
   908   1079     fd = pFile->h;
   909         -  rc = fstat(fd, &statbuf);
         1080  +  rc = osFstat(fd, &statbuf);
   910   1081     if( rc!=0 ){
   911   1082       pFile->lastErrno = errno;
   912   1083   #ifdef EOVERFLOW
   913   1084       if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
   914   1085   #endif
   915   1086       return SQLITE_IOERR;
   916   1087     }
................................................................................
   923   1094     ** prior to accessing the inode number.  The one byte written is
   924   1095     ** an ASCII 'S' character which also happens to be the first byte
   925   1096     ** in the header of every SQLite database.  In this way, if there
   926   1097     ** is a race condition such that another thread has already populated
   927   1098     ** the first page of the database, no damage is done.
   928   1099     */
   929   1100     if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){
   930         -    do{ rc = write(fd, "S", 1); }while( rc<0 && errno==EINTR );
         1101  +    do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
   931   1102       if( rc!=1 ){
   932   1103         pFile->lastErrno = errno;
   933   1104         return SQLITE_IOERR;
   934   1105       }
   935         -    rc = fstat(fd, &statbuf);
         1106  +    rc = osFstat(fd, &statbuf);
   936   1107       if( rc!=0 ){
   937   1108         pFile->lastErrno = errno;
   938   1109         return SQLITE_IOERR;
   939   1110       }
   940   1111     }
   941   1112   #endif
   942   1113   
................................................................................
   991   1162     if( pFile->pInode->eFileLock>SHARED_LOCK ){
   992   1163       reserved = 1;
   993   1164     }
   994   1165   
   995   1166     /* Otherwise see if some other process holds it.
   996   1167     */
   997   1168   #ifndef __DJGPP__
   998         -  if( !reserved ){
         1169  +  if( !reserved && !pFile->pInode->bProcessLock ){
   999   1170       struct flock lock;
  1000   1171       lock.l_whence = SEEK_SET;
  1001   1172       lock.l_start = RESERVED_BYTE;
  1002   1173       lock.l_len = 1;
  1003   1174       lock.l_type = F_WRLCK;
  1004         -    if (-1 == fcntl(pFile->h, F_GETLK, &lock)) {
         1175  +    if (-1 == osFcntl(pFile->h, F_GETLK, &lock)) {
  1005   1176         int tErrno = errno;
  1006   1177         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
  1007   1178         pFile->lastErrno = tErrno;
  1008   1179       } else if( lock.l_type!=F_UNLCK ){
  1009   1180         reserved = 1;
  1010   1181       }
  1011   1182     }
................................................................................
  1013   1184     
  1014   1185     unixLeaveMutex();
  1015   1186     OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
  1016   1187   
  1017   1188     *pResOut = reserved;
  1018   1189     return rc;
  1019   1190   }
         1191  +
         1192  +/*
         1193  +** Attempt to set a system-lock on the file pFile.  The lock is 
         1194  +** described by pLock.
         1195  +**
         1196  +** If the pFile was opened read/write from unix-excl, then the only lock
         1197  +** ever obtained is an exclusive lock, and it is obtained exactly once
         1198  +** the first time any lock is attempted.  All subsequent system locking
         1199  +** operations become no-ops.  Locking operations still happen internally,
         1200  +** in order to coordinate access between separate database connections
         1201  +** within this process, but all of that is handled in memory and the
         1202  +** operating system does not participate.
         1203  +**
         1204  +** This function is a pass-through to fcntl(F_SETLK) if pFile is using
         1205  +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl"
         1206  +** and is read-only.
         1207  +*/
         1208  +static int unixFileLock(unixFile *pFile, struct flock *pLock){
         1209  +  int rc;
         1210  +  unixInodeInfo *pInode = pFile->pInode;
         1211  +  assert( unixMutexHeld() );
         1212  +  assert( pInode!=0 );
         1213  +  if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
         1214  +   && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
         1215  +  ){
         1216  +    if( pInode->bProcessLock==0 ){
         1217  +      struct flock lock;
         1218  +      assert( pInode->nLock==0 );
         1219  +      lock.l_whence = SEEK_SET;
         1220  +      lock.l_start = SHARED_FIRST;
         1221  +      lock.l_len = SHARED_SIZE;
         1222  +      lock.l_type = F_WRLCK;
         1223  +      rc = osFcntl(pFile->h, F_SETLK, &lock);
         1224  +      if( rc<0 ) return rc;
         1225  +      pInode->bProcessLock = 1;
         1226  +      pInode->nLock++;
         1227  +    }else{
         1228  +      rc = 0;
         1229  +    }
         1230  +  }else{
         1231  +    rc = osFcntl(pFile->h, F_SETLK, pLock);
         1232  +  }
         1233  +  return rc;
         1234  +}
  1020   1235   
  1021   1236   /*
  1022   1237   ** Lock the file with the lock specified by parameter eFileLock - one
  1023   1238   ** of the following:
  1024   1239   **
  1025   1240   **     (1) SHARED_LOCK
  1026   1241   **     (2) RESERVED_LOCK
................................................................................
  1150   1365     lock.l_len = 1L;
  1151   1366     lock.l_whence = SEEK_SET;
  1152   1367     if( eFileLock==SHARED_LOCK 
  1153   1368         || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
  1154   1369     ){
  1155   1370       lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK);
  1156   1371       lock.l_start = PENDING_BYTE;
  1157         -    s = fcntl(pFile->h, F_SETLK, &lock);
         1372  +    s = unixFileLock(pFile, &lock);
  1158   1373       if( s==(-1) ){
  1159   1374         tErrno = errno;
  1160   1375         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
  1161   1376         if( IS_LOCK_ERROR(rc) ){
  1162   1377           pFile->lastErrno = tErrno;
  1163   1378         }
  1164   1379         goto end_lock;
................................................................................
  1172   1387     if( eFileLock==SHARED_LOCK ){
  1173   1388       assert( pInode->nShared==0 );
  1174   1389       assert( pInode->eFileLock==0 );
  1175   1390   
  1176   1391       /* Now get the read-lock */
  1177   1392       lock.l_start = SHARED_FIRST;
  1178   1393       lock.l_len = SHARED_SIZE;
  1179         -    if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){
         1394  +    if( (s = unixFileLock(pFile, &lock))==(-1) ){
  1180   1395         tErrno = errno;
  1181   1396       }
  1182   1397       /* Drop the temporary PENDING lock */
  1183   1398       lock.l_start = PENDING_BYTE;
  1184   1399       lock.l_len = 1L;
  1185   1400       lock.l_type = F_UNLCK;
  1186         -    if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
         1401  +    if( unixFileLock(pFile, &lock)!=0 ){
  1187   1402         if( s != -1 ){
  1188   1403           /* This could happen with a network mount */
  1189   1404           tErrno = errno; 
  1190   1405           rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); 
  1191   1406           if( IS_LOCK_ERROR(rc) ){
  1192   1407             pFile->lastErrno = tErrno;
  1193   1408           }
................................................................................
  1222   1437         case EXCLUSIVE_LOCK:
  1223   1438           lock.l_start = SHARED_FIRST;
  1224   1439           lock.l_len = SHARED_SIZE;
  1225   1440           break;
  1226   1441         default:
  1227   1442           assert(0);
  1228   1443       }
  1229         -    s = fcntl(pFile->h, F_SETLK, &lock);
         1444  +    s = unixFileLock(pFile, &lock);
  1230   1445       if( s==(-1) ){
  1231   1446         tErrno = errno;
  1232   1447         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
  1233   1448         if( IS_LOCK_ERROR(rc) ){
  1234   1449           pFile->lastErrno = tErrno;
  1235   1450         }
  1236   1451       }
................................................................................
  1291   1506   ** 
  1292   1507   ** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED
  1293   1508   ** the byte range is divided into 2 parts and the first part is unlocked then
  1294   1509   ** set to a read lock, then the other part is simply unlocked.  This works 
  1295   1510   ** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to 
  1296   1511   ** remove the write lock on a region when a read lock is set.
  1297   1512   */
  1298         -static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
         1513  +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
  1299   1514     unixFile *pFile = (unixFile*)id;
  1300   1515     unixInodeInfo *pInode;
  1301   1516     struct flock lock;
  1302   1517     int rc = SQLITE_OK;
  1303   1518     int h;
  1304   1519     int tErrno;                      /* Error code from system call errors */
  1305   1520   
................................................................................
  1347   1562       **  2:   [....W]
  1348   1563       **  3:   [RRRRW]
  1349   1564       **  4:   [RRRR.]
  1350   1565       */
  1351   1566       if( eFileLock==SHARED_LOCK ){
  1352   1567   
  1353   1568   #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
         1569  +      (void)handleNFSUnlock;
  1354   1570         assert( handleNFSUnlock==0 );
  1355   1571   #endif
  1356   1572   #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
  1357   1573         if( handleNFSUnlock ){
  1358   1574           off_t divSize = SHARED_SIZE - 1;
  1359   1575           
  1360   1576           lock.l_type = F_UNLCK;
  1361   1577           lock.l_whence = SEEK_SET;
  1362   1578           lock.l_start = SHARED_FIRST;
  1363   1579           lock.l_len = divSize;
  1364         -        if( fcntl(h, F_SETLK, &lock)==(-1) ){
         1580  +        if( unixFileLock(pFile,, &lock)==(-1) ){
  1365   1581             tErrno = errno;
  1366   1582             rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
  1367   1583             if( IS_LOCK_ERROR(rc) ){
  1368   1584               pFile->lastErrno = tErrno;
  1369   1585             }
  1370   1586             goto end_unlock;
  1371   1587           }
  1372   1588           lock.l_type = F_RDLCK;
  1373   1589           lock.l_whence = SEEK_SET;
  1374   1590           lock.l_start = SHARED_FIRST;
  1375   1591           lock.l_len = divSize;
  1376         -        if( fcntl(h, F_SETLK, &lock)==(-1) ){
         1592  +        if( unixFileLock(pFile, &lock)==(-1) ){
  1377   1593             tErrno = errno;
  1378   1594             rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
  1379   1595             if( IS_LOCK_ERROR(rc) ){
  1380   1596               pFile->lastErrno = tErrno;
  1381   1597             }
  1382   1598             goto end_unlock;
  1383   1599           }
  1384   1600           lock.l_type = F_UNLCK;
  1385   1601           lock.l_whence = SEEK_SET;
  1386   1602           lock.l_start = SHARED_FIRST+divSize;
  1387   1603           lock.l_len = SHARED_SIZE-divSize;
  1388         -        if( fcntl(h, F_SETLK, &lock)==(-1) ){
         1604  +        if( unixFileLock(pFile, &lock)==(-1) ){
  1389   1605             tErrno = errno;
  1390   1606             rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
  1391   1607             if( IS_LOCK_ERROR(rc) ){
  1392   1608               pFile->lastErrno = tErrno;
  1393   1609             }
  1394   1610             goto end_unlock;
  1395   1611           }
................................................................................
  1396   1612         }else
  1397   1613   #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
  1398   1614         {
  1399   1615           lock.l_type = F_RDLCK;
  1400   1616           lock.l_whence = SEEK_SET;
  1401   1617           lock.l_start = SHARED_FIRST;
  1402   1618           lock.l_len = SHARED_SIZE;
  1403         -        if( fcntl(h, F_SETLK, &lock)==(-1) ){
         1619  +        if( unixFileLock(pFile, &lock)==(-1) ){
  1404   1620             tErrno = errno;
  1405   1621             rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
  1406   1622             if( IS_LOCK_ERROR(rc) ){
  1407   1623               pFile->lastErrno = tErrno;
  1408   1624             }
  1409   1625             goto end_unlock;
  1410   1626           }
  1411   1627         }
  1412   1628       }
  1413   1629       lock.l_type = F_UNLCK;
  1414   1630       lock.l_whence = SEEK_SET;
  1415   1631       lock.l_start = PENDING_BYTE;
  1416   1632       lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
  1417         -    if( fcntl(h, F_SETLK, &lock)!=(-1) ){
         1633  +    if( unixFileLock(pFile, &lock)!=(-1) ){
  1418   1634         pInode->eFileLock = SHARED_LOCK;
  1419   1635       }else{
  1420   1636         tErrno = errno;
  1421   1637         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
  1422   1638         if( IS_LOCK_ERROR(rc) ){
  1423   1639           pFile->lastErrno = tErrno;
  1424   1640         }
................................................................................
  1434   1650       if( pInode->nShared==0 ){
  1435   1651         lock.l_type = F_UNLCK;
  1436   1652         lock.l_whence = SEEK_SET;
  1437   1653         lock.l_start = lock.l_len = 0L;
  1438   1654         SimulateIOErrorBenign(1);
  1439   1655         SimulateIOError( h=(-1) )
  1440   1656         SimulateIOErrorBenign(0);
  1441         -      if( fcntl(h, F_SETLK, &lock)!=(-1) ){
         1657  +      if( unixFileLock(pFile, &lock)!=(-1) ){
  1442   1658           pInode->eFileLock = NO_LOCK;
  1443   1659         }else{
  1444   1660           tErrno = errno;
  1445   1661           rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
  1446   1662           if( IS_LOCK_ERROR(rc) ){
  1447   1663             pFile->lastErrno = tErrno;
  1448   1664           }
................................................................................
  1454   1670       /* Decrement the count of locks against this same file.  When the
  1455   1671       ** count reaches zero, close any other file descriptors whose close
  1456   1672       ** was deferred because of outstanding locks.
  1457   1673       */
  1458   1674       pInode->nLock--;
  1459   1675       assert( pInode->nLock>=0 );
  1460   1676       if( pInode->nLock==0 ){
  1461         -      int rc2 = closePendingFds(pFile);
  1462         -      if( rc==SQLITE_OK ){
  1463         -        rc = rc2;
  1464         -      }
         1677  +      closePendingFds(pFile);
  1465   1678       }
  1466   1679     }
  1467   1680   	
  1468   1681   end_unlock:
  1469   1682     unixLeaveMutex();
  1470   1683     if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
  1471   1684     return rc;
................................................................................
  1475   1688   ** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
  1476   1689   ** must be either NO_LOCK or SHARED_LOCK.
  1477   1690   **
  1478   1691   ** If the locking level of the file descriptor is already at or below
  1479   1692   ** the requested locking level, this routine is a no-op.
  1480   1693   */
  1481   1694   static int unixUnlock(sqlite3_file *id, int eFileLock){
  1482         -  return _posixUnlock(id, eFileLock, 0);
         1695  +  return posixUnlock(id, eFileLock, 0);
  1483   1696   }
  1484   1697   
  1485   1698   /*
  1486   1699   ** This function performs the parts of the "close file" operation 
  1487   1700   ** common to all locking schemes. It closes the directory and file
  1488   1701   ** handles, if they are valid, and sets all fields of the unixFile
  1489   1702   ** structure to 0.
................................................................................
  1492   1705   ** even on VxWorks.  A mutex will be acquired on VxWorks by the
  1493   1706   ** vxworksReleaseFileId() routine.
  1494   1707   */
  1495   1708   static int closeUnixFile(sqlite3_file *id){
  1496   1709     unixFile *pFile = (unixFile*)id;
  1497   1710     if( pFile ){
  1498   1711       if( pFile->dirfd>=0 ){
  1499         -      int err = close(pFile->dirfd);
  1500         -      if( err ){
  1501         -        pFile->lastErrno = errno;
  1502         -        return unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", pFile->zPath);
  1503         -      }else{
  1504         -        pFile->dirfd=-1;
  1505         -      }
         1712  +      robust_close(pFile, pFile->dirfd, __LINE__);
         1713  +      pFile->dirfd=-1;
  1506   1714       }
  1507   1715       if( pFile->h>=0 ){
  1508         -      int err = close(pFile->h);
  1509         -      if( err ){
  1510         -        pFile->lastErrno = errno;
  1511         -        return unixLogError(SQLITE_IOERR_CLOSE, "close", pFile->zPath);
  1512         -      }
         1716  +      robust_close(pFile, pFile->h, __LINE__);
         1717  +      pFile->h = -1;
  1513   1718       }
  1514   1719   #if OS_VXWORKS
  1515   1720       if( pFile->pId ){
  1516   1721         if( pFile->isDelete ){
  1517   1722           unlink(pFile->pId->zCanonicalName);
  1518   1723         }
  1519   1724         vxworksReleaseFileId(pFile->pId);
................................................................................
  1533   1738   */
  1534   1739   static int unixClose(sqlite3_file *id){
  1535   1740     int rc = SQLITE_OK;
  1536   1741     if( id ){
  1537   1742       unixFile *pFile = (unixFile *)id;
  1538   1743       unixUnlock(id, NO_LOCK);
  1539   1744       unixEnterMutex();
         1745  +    assert( pFile->pInode==0 || pFile->pInode->nLock>0
         1746  +            || pFile->pInode->bProcessLock==0 );
  1540   1747       if( pFile->pInode && pFile->pInode->nLock ){
  1541   1748         /* If there are outstanding locks, do not actually close the file just
  1542   1749         ** yet because that would clear those locks.  Instead, add the file
  1543   1750         ** descriptor to pInode->pUnused list.  It will be automatically closed 
  1544   1751         ** when the last lock is cleared.
  1545   1752         */
  1546   1753         setPendingFd(pFile);
................................................................................
  1647   1854     if( pFile->eFileLock>SHARED_LOCK ){
  1648   1855       /* Either this connection or some other connection in the same process
  1649   1856       ** holds a lock on the file.  No need to check further. */
  1650   1857       reserved = 1;
  1651   1858     }else{
  1652   1859       /* The lock is held if and only if the lockfile exists */
  1653   1860       const char *zLockFile = (const char*)pFile->lockingContext;
  1654         -    reserved = access(zLockFile, 0)==0;
         1861  +    reserved = osAccess(zLockFile, 0)==0;
  1655   1862     }
  1656   1863     OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
  1657   1864     *pResOut = reserved;
  1658   1865     return rc;
  1659   1866   }
  1660   1867   
  1661   1868   /*
................................................................................
  1701   1908       /* Always update the timestamp on the old file */
  1702   1909       utimes(zLockFile, NULL);
  1703   1910   #endif
  1704   1911       return SQLITE_OK;
  1705   1912     }
  1706   1913     
  1707   1914     /* grab an exclusive lock */
  1708         -  fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
         1915  +  fd = robust_open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
  1709   1916     if( fd<0 ){
  1710   1917       /* failed to open/create the file, someone else may have stolen the lock */
  1711   1918       int tErrno = errno;
  1712   1919       if( EEXIST == tErrno ){
  1713   1920         rc = SQLITE_BUSY;
  1714   1921       } else {
  1715   1922         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
  1716   1923         if( IS_LOCK_ERROR(rc) ){
  1717   1924           pFile->lastErrno = tErrno;
  1718   1925         }
  1719   1926       }
  1720   1927       return rc;
  1721   1928     } 
  1722         -  if( close(fd) ){
  1723         -    pFile->lastErrno = errno;
  1724         -    rc = SQLITE_IOERR_CLOSE;
  1725         -  }
         1929  +  robust_close(pFile, fd, __LINE__);
  1726   1930     
  1727   1931     /* got it, set the type and return ok */
  1728   1932     pFile->eFileLock = eFileLock;
  1729   1933     return rc;
  1730   1934   }
  1731   1935   
  1732   1936   /*
................................................................................
  2610   2814           pFile->eFileLock = NO_LOCK;
  2611   2815         }
  2612   2816       }
  2613   2817       if( rc==SQLITE_OK ){
  2614   2818         pInode->nLock--;
  2615   2819         assert( pInode->nLock>=0 );
  2616   2820         if( pInode->nLock==0 ){
  2617         -        rc = closePendingFds(pFile);
         2821  +        closePendingFds(pFile);
  2618   2822         }
  2619   2823       }
  2620   2824     }
  2621   2825     
  2622   2826     unixLeaveMutex();
  2623   2827     if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
  2624   2828     return rc;
................................................................................
  2667   2871    ** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
  2668   2872    ** must be either NO_LOCK or SHARED_LOCK.
  2669   2873    **
  2670   2874    ** If the locking level of the file descriptor is already at or below
  2671   2875    ** the requested locking level, this routine is a no-op.
  2672   2876    */
  2673   2877   static int nfsUnlock(sqlite3_file *id, int eFileLock){
  2674         -  return _posixUnlock(id, eFileLock, 1);
         2878  +  return posixUnlock(id, eFileLock, 1);
  2675   2879   }
  2676   2880   
  2677   2881   #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
  2678   2882   /*
  2679   2883   ** The code above is the NFS lock implementation.  The code is specific
  2680   2884   ** to MacOSX and does not work on other unix platforms.  No alternative
  2681   2885   ** is available.  
................................................................................
  2709   2913   static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
  2710   2914     int got;
  2711   2915   #if (!defined(USE_PREAD) && !defined(USE_PREAD64))
  2712   2916     i64 newOffset;
  2713   2917   #endif
  2714   2918     TIMER_START;
  2715   2919   #if defined(USE_PREAD)
  2716         -  do{ got = pread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
         2920  +  do{ got = osPread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
  2717   2921     SimulateIOError( got = -1 );
  2718   2922   #elif defined(USE_PREAD64)
  2719         -  do{ got = pread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
         2923  +  do{ got = osPread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR);
  2720   2924     SimulateIOError( got = -1 );
  2721   2925   #else
  2722   2926     newOffset = lseek(id->h, offset, SEEK_SET);
  2723   2927     SimulateIOError( newOffset-- );
  2724   2928     if( newOffset!=offset ){
  2725   2929       if( newOffset == -1 ){
  2726   2930         ((unixFile*)id)->lastErrno = errno;
  2727   2931       }else{
  2728   2932         ((unixFile*)id)->lastErrno = 0;			
  2729   2933       }
  2730   2934       return -1;
  2731   2935     }
  2732         -  do{ got = read(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
         2936  +  do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
  2733   2937   #endif
  2734   2938     TIMER_END;
  2735   2939     if( got<0 ){
  2736   2940       ((unixFile*)id)->lastErrno = errno;
  2737   2941     }
  2738   2942     OSTRACE(("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
  2739   2943     return got;
................................................................................
  2787   2991   static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
  2788   2992     int got;
  2789   2993   #if (!defined(USE_PREAD) && !defined(USE_PREAD64))
  2790   2994     i64 newOffset;
  2791   2995   #endif
  2792   2996     TIMER_START;
  2793   2997   #if defined(USE_PREAD)
  2794         -  do{ got = pwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
         2998  +  do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
  2795   2999   #elif defined(USE_PREAD64)
  2796         -  do{ got = pwrite64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
         3000  +  do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
  2797   3001   #else
  2798   3002     newOffset = lseek(id->h, offset, SEEK_SET);
  2799   3003     if( newOffset!=offset ){
  2800   3004       if( newOffset == -1 ){
  2801   3005         ((unixFile*)id)->lastErrno = errno;
  2802   3006       }else{
  2803   3007         ((unixFile*)id)->lastErrno = 0;			
  2804   3008       }
  2805   3009       return -1;
  2806   3010     }
  2807         -  do{ got = write(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
         3011  +  do{ got = osWrite(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
  2808   3012   #endif
  2809   3013     TIMER_END;
  2810   3014     if( got<0 ){
  2811   3015       ((unixFile*)id)->lastErrno = errno;
  2812   3016     }
  2813   3017   
  2814   3018     OSTRACE(("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
................................................................................
  2968   3172     /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
  2969   3173     ** no-op
  2970   3174     */
  2971   3175   #ifdef SQLITE_NO_SYNC
  2972   3176     rc = SQLITE_OK;
  2973   3177   #elif HAVE_FULLFSYNC
  2974   3178     if( fullSync ){
  2975         -    rc = fcntl(fd, F_FULLFSYNC, 0);
         3179  +    rc = osFcntl(fd, F_FULLFSYNC, 0);
  2976   3180     }else{
  2977   3181       rc = 1;
  2978   3182     }
  2979   3183     /* If the FULLFSYNC failed, fall back to attempting an fsync().
  2980   3184     ** It shouldn't be possible for fullfsync to fail on the local 
  2981   3185     ** file system (on OSX), so failure indicates that FULLFSYNC
  2982   3186     ** isn't supported for this file system. So, attempt an fsync 
................................................................................
  3043   3247     rc = full_fsync(pFile->h, isFullsync, isDataOnly);
  3044   3248     SimulateIOError( rc=1 );
  3045   3249     if( rc ){
  3046   3250       pFile->lastErrno = errno;
  3047   3251       return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
  3048   3252     }
  3049   3253     if( pFile->dirfd>=0 ){
  3050         -    int err;
  3051   3254       OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
  3052   3255               HAVE_FULLFSYNC, isFullsync));
  3053   3256   #ifndef SQLITE_DISABLE_DIRSYNC
  3054   3257       /* The directory sync is only attempted if full_fsync is
  3055   3258       ** turned off or unavailable.  If a full_fsync occurred above,
  3056   3259       ** then the directory sync is superfluous.
  3057   3260       */
................................................................................
  3062   3265          ** A failed directory sync is not a big deal.  So it seems
  3063   3266          ** better to ignore the error.  Ticket #1657
  3064   3267          */
  3065   3268          /* pFile->lastErrno = errno; */
  3066   3269          /* return SQLITE_IOERR; */
  3067   3270       }
  3068   3271   #endif
  3069         -    err = close(pFile->dirfd); /* Only need to sync once, so close the */
  3070         -    if( err==0 ){              /* directory when we are done */
  3071         -      pFile->dirfd = -1;
  3072         -    }else{
  3073         -      pFile->lastErrno = errno;
  3074         -      rc = unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", pFile->zPath);
  3075         -    }
         3272  +    /* Only need to sync once, so close the  directory when we are done */
         3273  +    robust_close(pFile, pFile->dirfd, __LINE__);
         3274  +    pFile->dirfd = -1;
  3076   3275     }
  3077   3276     return rc;
  3078   3277   }
  3079   3278   
  3080   3279   /*
  3081   3280   ** Truncate an open file to a specified size
  3082   3281   */
................................................................................
  3120   3319   /*
  3121   3320   ** Determine the current size of a file in bytes
  3122   3321   */
  3123   3322   static int unixFileSize(sqlite3_file *id, i64 *pSize){
  3124   3323     int rc;
  3125   3324     struct stat buf;
  3126   3325     assert( id );
  3127         -  rc = fstat(((unixFile*)id)->h, &buf);
         3326  +  rc = osFstat(((unixFile*)id)->h, &buf);
  3128   3327     SimulateIOError( rc=1 );
  3129   3328     if( rc!=0 ){
  3130   3329       ((unixFile*)id)->lastErrno = errno;
  3131   3330       return SQLITE_IOERR_FSTAT;
  3132   3331     }
  3133   3332     *pSize = buf.st_size;
  3134   3333   
................................................................................
  3161   3360   ** SQLITE_FCNTL_SIZE_HINT operation is a no-op for Unix.
  3162   3361   */
  3163   3362   static int fcntlSizeHint(unixFile *pFile, i64 nByte){
  3164   3363     if( pFile->szChunk ){
  3165   3364       i64 nSize;                    /* Required file size */
  3166   3365       struct stat buf;              /* Used to hold return values of fstat() */
  3167   3366      
  3168         -    if( fstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
         3367  +    if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
  3169   3368   
  3170   3369       nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
  3171   3370       if( nSize>(i64)buf.st_size ){
  3172   3371   #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
  3173   3372         int rc;
  3174   3373         do{
  3175         -        rc = posix_fallocate(pFile-.h, buf.st_size, nSize-buf.st_size;
         3374  +        rc = osFallocate(pFile->.h, buf.st_size, nSize-buf.st_size;
  3176   3375         }while( rc<0 && errno=EINTR );
  3177   3376         if( rc ) return SQLITE_IOERR_WRITE;
  3178   3377   #else
  3179   3378         /* If the OS does not have posix_fallocate(), fake it. First use
  3180   3379         ** ftruncate() to set the file size, then write a single byte to
  3181   3380         ** the last byte in each block within the extended region. This
  3182   3381         ** is the same technique used by glibc to implement posix_fallocate()
................................................................................
  3369   3568   
  3370   3569     /* Shared locks never span more than one byte */
  3371   3570     assert( n==1 || lockType!=F_RDLCK );
  3372   3571   
  3373   3572     /* Locks are within range */
  3374   3573     assert( n>=1 && n<SQLITE_SHM_NLOCK );
  3375   3574   
  3376         -  /* Initialize the locking parameters */
  3377         -  memset(&f, 0, sizeof(f));
  3378         -  f.l_type = lockType;
  3379         -  f.l_whence = SEEK_SET;
  3380         -  f.l_start = ofst;
  3381         -  f.l_len = n;
         3575  +  if( pShmNode->h>=0 ){
         3576  +    /* Initialize the locking parameters */
         3577  +    memset(&f, 0, sizeof(f));
         3578  +    f.l_type = lockType;
         3579  +    f.l_whence = SEEK_SET;
         3580  +    f.l_start = ofst;
         3581  +    f.l_len = n;
  3382   3582   
  3383         -  rc = fcntl(pShmNode->h, F_SETLK, &f);
  3384         -  rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
         3583  +    rc = osFcntl(pShmNode->h, F_SETLK, &f);
         3584  +    rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
         3585  +  }
  3385   3586   
  3386   3587     /* Update the global lock state and do debug tracing */
  3387   3588   #ifdef SQLITE_DEBUG
  3388   3589     { u16 mask;
  3389   3590     OSTRACE(("SHM-LOCK "));
  3390   3591     mask = (1<<(ofst+n)) - (1<<ofst);
  3391   3592     if( rc==SQLITE_OK ){
................................................................................
  3432   3633     unixShmNode *p = pFd->pInode->pShmNode;
  3433   3634     assert( unixMutexHeld() );
  3434   3635     if( p && p->nRef==0 ){
  3435   3636       int i;
  3436   3637       assert( p->pInode==pFd->pInode );
  3437   3638       if( p->mutex ) sqlite3_mutex_free(p->mutex);
  3438   3639       for(i=0; i<p->nRegion; i++){
  3439         -      munmap(p->apRegion[i], p->szRegion);
         3640  +      if( p->h>=0 ){
         3641  +        munmap(p->apRegion[i], p->szRegion);
         3642  +      }else{
         3643  +        sqlite3_free(p->apRegion[i]);
         3644  +      }
  3440   3645       }
  3441   3646       sqlite3_free(p->apRegion);
  3442         -    if( p->h>=0 ) close(p->h);
         3647  +    if( p->h>=0 ){
         3648  +      robust_close(pFd, p->h, __LINE__);
         3649  +      p->h = -1;
         3650  +    }
  3443   3651       p->pInode->pShmNode = 0;
  3444   3652       sqlite3_free(p);
  3445   3653     }
  3446   3654   }
  3447   3655   
  3448   3656   /*
  3449   3657   ** Open a shared-memory area associated with open database file pDbFd.  
................................................................................
  3469   3677   ** same database file at the same time, database corruption will likely
  3470   3678   ** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
  3471   3679   ** "unsupported" and may go away in a future SQLite release.
  3472   3680   **
  3473   3681   ** When opening a new shared-memory file, if no other instances of that
  3474   3682   ** file are currently open, in this process or in other processes, then
  3475   3683   ** the file must be truncated to zero length or have its header cleared.
         3684  +**
         3685  +** If the original database file (pDbFd) is using the "unix-excl" VFS
         3686  +** that means that an exclusive lock is held on the database file and
         3687  +** that no other processes are able to read or write the database.  In
         3688  +** that case, we do not really need shared memory.  No shared memory
         3689  +** file is created.  The shared memory will be simulated with heap memory.
  3476   3690   */
  3477   3691   static int unixOpenSharedMemory(unixFile *pDbFd){
  3478   3692     struct unixShm *p = 0;          /* The connection to be opened */
  3479   3693     struct unixShmNode *pShmNode;   /* The underlying mmapped file */
  3480   3694     int rc;                         /* Result code */
  3481   3695     unixInodeInfo *pInode;          /* The inode of fd */
  3482   3696     char *zShmFilename;             /* Name of the file used for SHM */
................................................................................
  3498   3712       struct stat sStat;                 /* fstat() info for database file */
  3499   3713   
  3500   3714       /* Call fstat() to figure out the permissions on the database file. If
  3501   3715       ** a new *-shm file is created, an attempt will be made to create it
  3502   3716       ** with the same permissions. The actual permissions the file is created
  3503   3717       ** with are subject to the current umask setting.
  3504   3718       */
  3505         -    if( fstat(pDbFd->h, &sStat) ){
         3719  +    if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
  3506   3720         rc = SQLITE_IOERR_FSTAT;
  3507   3721         goto shm_open_err;
  3508   3722       }
  3509   3723   
  3510   3724   #ifdef SQLITE_SHM_DIRECTORY
  3511   3725       nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 30;
  3512   3726   #else
................................................................................
  3531   3745       pShmNode->pInode = pDbFd->pInode;
  3532   3746       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  3533   3747       if( pShmNode->mutex==0 ){
  3534   3748         rc = SQLITE_NOMEM;
  3535   3749         goto shm_open_err;
  3536   3750       }
  3537   3751   
  3538         -    pShmNode->h = open(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777));
  3539         -    if( pShmNode->h<0 ){
  3540         -      rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
  3541         -      goto shm_open_err;
  3542         -    }
  3543         -
  3544         -    /* Check to see if another process is holding the dead-man switch.
  3545         -    ** If not, truncate the file to zero length. 
  3546         -    */
  3547         -    rc = SQLITE_OK;
  3548         -    if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
  3549         -      if( robust_ftruncate(pShmNode->h, 0) ){
  3550         -        rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
  3551         -      }
  3552         -    }
  3553         -    if( rc==SQLITE_OK ){
  3554         -      rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
  3555         -    }
  3556         -    if( rc ) goto shm_open_err;
         3752  +    if( pInode->bProcessLock==0 ){
         3753  +      pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT,
         3754  +                               (sStat.st_mode & 0777));
         3755  +      if( pShmNode->h<0 ){
         3756  +        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
         3757  +        goto shm_open_err;
         3758  +      }
         3759  +  
         3760  +      /* Check to see if another process is holding the dead-man switch.
         3761  +      ** If not, truncate the file to zero length. 
         3762  +      */
         3763  +      rc = SQLITE_OK;
         3764  +      if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
         3765  +        if( robust_ftruncate(pShmNode->h, 0) ){
         3766  +          rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
         3767  +        }
         3768  +      }
         3769  +      if( rc==SQLITE_OK ){
         3770  +        rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
         3771  +      }
         3772  +      if( rc ) goto shm_open_err;
         3773  +    }
  3557   3774     }
  3558   3775   
  3559   3776     /* Make the new connection a child of the unixShmNode */
  3560   3777     p->pShmNode = pShmNode;
  3561   3778   #ifdef SQLITE_DEBUG
  3562   3779     p->id = pShmNode->nextShmId++;
  3563   3780   #endif
................................................................................
  3623   3840       if( rc!=SQLITE_OK ) return rc;
  3624   3841     }
  3625   3842   
  3626   3843     p = pDbFd->pShm;
  3627   3844     pShmNode = p->pShmNode;
  3628   3845     sqlite3_mutex_enter(pShmNode->mutex);
  3629   3846     assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
         3847  +  assert( pShmNode->pInode==pDbFd->pInode );
         3848  +  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
         3849  +  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
  3630   3850   
  3631   3851     if( pShmNode->nRegion<=iRegion ){
  3632   3852       char **apNew;                      /* New apRegion[] array */
  3633   3853       int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
  3634   3854       struct stat sStat;                 /* Used by fstat() */
  3635   3855   
  3636   3856       pShmNode->szRegion = szRegion;
  3637   3857   
  3638         -    /* The requested region is not mapped into this processes address space.
  3639         -    ** Check to see if it has been allocated (i.e. if the wal-index file is
  3640         -    ** large enough to contain the requested region).
  3641         -    */
  3642         -    if( fstat(pShmNode->h, &sStat) ){
  3643         -      rc = SQLITE_IOERR_SHMSIZE;
  3644         -      goto shmpage_out;
  3645         -    }
  3646         -
  3647         -    if( sStat.st_size<nByte ){
  3648         -      /* The requested memory region does not exist. If bExtend is set to
  3649         -      ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
  3650         -      **
  3651         -      ** Alternatively, if bExtend is true, use ftruncate() to allocate
  3652         -      ** the requested memory region.
         3858  +    if( pShmNode->h>=0 ){
         3859  +      /* The requested region is not mapped into this processes address space.
         3860  +      ** Check to see if it has been allocated (i.e. if the wal-index file is
         3861  +      ** large enough to contain the requested region).
  3653   3862         */
  3654         -      if( !bExtend ) goto shmpage_out;
  3655         -      if( robust_ftruncate(pShmNode->h, nByte) ){
  3656         -        rc = unixLogError(SQLITE_IOERR_SHMSIZE,"ftruncate",pShmNode->zFilename);
         3863  +      if( osFstat(pShmNode->h, &sStat) ){
         3864  +        rc = SQLITE_IOERR_SHMSIZE;
  3657   3865           goto shmpage_out;
  3658   3866         }
         3867  +  
         3868  +      if( sStat.st_size<nByte ){
         3869  +        /* The requested memory region does not exist. If bExtend is set to
         3870  +        ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
         3871  +        **
         3872  +        ** Alternatively, if bExtend is true, use ftruncate() to allocate
         3873  +        ** the requested memory region.
         3874  +        */
         3875  +        if( !bExtend ) goto shmpage_out;
         3876  +        if( robust_ftruncate(pShmNode->h, nByte) ){
         3877  +          rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
         3878  +                            pShmNode->zFilename);
         3879  +          goto shmpage_out;
         3880  +        }
         3881  +      }
  3659   3882       }
  3660   3883   
  3661   3884       /* Map the requested memory region into this processes address space. */
  3662   3885       apNew = (char **)sqlite3_realloc(
  3663   3886           pShmNode->apRegion, (iRegion+1)*sizeof(char *)
  3664   3887       );
  3665   3888       if( !apNew ){
  3666   3889         rc = SQLITE_IOERR_NOMEM;
  3667   3890         goto shmpage_out;
  3668   3891       }
  3669   3892       pShmNode->apRegion = apNew;
  3670   3893       while(pShmNode->nRegion<=iRegion){
  3671         -      void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
  3672         -          MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
  3673         -      );
  3674         -      if( pMem==MAP_FAILED ){
  3675         -        rc = SQLITE_IOERR;
  3676         -        goto shmpage_out;
         3894  +      void *pMem;
         3895  +      if( pShmNode->h>=0 ){
         3896  +        pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
         3897  +            MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
         3898  +        );
         3899  +        if( pMem==MAP_FAILED ){
         3900  +          rc = SQLITE_IOERR;
         3901  +          goto shmpage_out;
         3902  +        }
         3903  +      }else{
         3904  +        pMem = sqlite3_malloc(szRegion);
         3905  +        if( pMem==0 ){
         3906  +          rc = SQLITE_NOMEM;
         3907  +          goto shmpage_out;
         3908  +        }
         3909  +        memset(pMem, 0, szRegion);
  3677   3910         }
  3678   3911         pShmNode->apRegion[pShmNode->nRegion] = pMem;
  3679   3912         pShmNode->nRegion++;
  3680   3913       }
  3681   3914     }
  3682   3915   
  3683   3916   shmpage_out:
................................................................................
  3716   3949     assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
  3717   3950     assert( n>=1 );
  3718   3951     assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
  3719   3952          || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
  3720   3953          || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
  3721   3954          || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
  3722   3955     assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
         3956  +  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
         3957  +  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
  3723   3958   
  3724   3959     mask = (1<<(ofst+n)) - (1<<ofst);
  3725   3960     assert( n>1 || mask==(1<<ofst) );
  3726   3961     sqlite3_mutex_enter(pShmNode->mutex);
  3727   3962     if( flags & SQLITE_SHM_UNLOCK ){
  3728   3963       u16 allMask = 0; /* Mask of locks held by siblings */
  3729   3964   
................................................................................
  3853   4088   
  3854   4089     /* If pShmNode->nRef has reached 0, then close the underlying
  3855   4090     ** shared-memory file, too */
  3856   4091     unixEnterMutex();
  3857   4092     assert( pShmNode->nRef>0 );
  3858   4093     pShmNode->nRef--;
  3859   4094     if( pShmNode->nRef==0 ){
  3860         -    if( deleteFlag ) unlink(pShmNode->zFilename);
         4095  +    if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename);
  3861   4096       unixShmPurge(pDbFd);
  3862   4097     }
  3863   4098     unixLeaveMutex();
  3864   4099   
  3865   4100     return SQLITE_OK;
  3866   4101   }
  3867   4102   
................................................................................
  4094   4329     ** Test byte-range lock using fcntl(). If the call succeeds, 
  4095   4330     ** assume that the file-system supports POSIX style locks. 
  4096   4331     */
  4097   4332     lockInfo.l_len = 1;
  4098   4333     lockInfo.l_start = 0;
  4099   4334     lockInfo.l_whence = SEEK_SET;
  4100   4335     lockInfo.l_type = F_RDLCK;
  4101         -  if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
         4336  +  if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
  4102   4337       if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){
  4103   4338         return &nfsIoMethods;
  4104   4339       } else {
  4105   4340         return &posixIoMethods;
  4106   4341       }
  4107   4342     }else{
  4108   4343       return &dotlockIoMethods;
................................................................................
  4136   4371     /* Test if fcntl() is supported and use POSIX style locks.
  4137   4372     ** Otherwise fall back to the named semaphore method.
  4138   4373     */
  4139   4374     lockInfo.l_len = 1;
  4140   4375     lockInfo.l_start = 0;
  4141   4376     lockInfo.l_whence = SEEK_SET;
  4142   4377     lockInfo.l_type = F_RDLCK;
  4143         -  if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
         4378  +  if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
  4144   4379       return &posixIoMethods;
  4145   4380     }else{
  4146   4381       return &semIoMethods;
  4147   4382     }
  4148   4383   }
  4149   4384   static const sqlite3_io_methods 
  4150   4385     *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
................................................................................
  4170   4405   static int fillInUnixFile(
  4171   4406     sqlite3_vfs *pVfs,      /* Pointer to vfs object */
  4172   4407     int h,                  /* Open file descriptor of file being opened */
  4173   4408     int dirfd,              /* Directory file descriptor */
  4174   4409     sqlite3_file *pId,      /* Write to the unixFile structure here */
  4175   4410     const char *zFilename,  /* Name of the file being opened */
  4176   4411     int noLock,             /* Omit locking if true */
  4177         -  int isDelete            /* Delete on close if true */
         4412  +  int isDelete,           /* Delete on close if true */
         4413  +  int isReadOnly          /* True if the file is opened read-only */
  4178   4414   ){
  4179   4415     const sqlite3_io_methods *pLockingStyle;
  4180   4416     unixFile *pNew = (unixFile *)pId;
  4181   4417     int rc = SQLITE_OK;
  4182   4418   
  4183   4419     assert( pNew->pInode==NULL );
  4184   4420   
................................................................................
  4197   4433   #else
  4198   4434     assert( zFilename==0 || zFilename[0]=='/' );
  4199   4435   #endif
  4200   4436   
  4201   4437     OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  4202   4438     pNew->h = h;
  4203   4439     pNew->dirfd = dirfd;
  4204         -  pNew->fileFlags = 0;
  4205   4440     pNew->zPath = zFilename;
         4441  +  if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
         4442  +    pNew->ctrlFlags = UNIXFILE_EXCL;
         4443  +  }else{
         4444  +    pNew->ctrlFlags = 0;
         4445  +  }
         4446  +  if( isReadOnly ){
         4447  +    pNew->ctrlFlags |= UNIXFILE_RDONLY;
         4448  +  }
  4206   4449   
  4207   4450   #if OS_VXWORKS
  4208   4451     pNew->pId = vxworksFindFileId(zFilename);
  4209   4452     if( pNew->pId==0 ){
  4210   4453       noLock = 1;
  4211   4454       rc = SQLITE_NOMEM;
  4212   4455     }
................................................................................
  4246   4489         ** handle h - as it is guaranteed that no posix locks will be released
  4247   4490         ** by doing so.
  4248   4491         **
  4249   4492         ** If scenario (a) caused the error then things are not so safe. The
  4250   4493         ** implicit assumption here is that if fstat() fails, things are in
  4251   4494         ** such bad shape that dropping a lock or two doesn't matter much.
  4252   4495         */
  4253         -      close(h);
         4496  +      robust_close(pNew, h, __LINE__);
  4254   4497         h = -1;
  4255   4498       }
  4256   4499       unixLeaveMutex();
  4257   4500     }
  4258   4501   
  4259   4502   #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
  4260   4503     else if( pLockingStyle == &afpIoMethods ){
................................................................................
  4272   4515         pCtx->dbPath = zFilename;
  4273   4516         pCtx->reserved = 0;
  4274   4517         srandomdev();
  4275   4518         unixEnterMutex();
  4276   4519         rc = findInodeInfo(pNew, &pNew->pInode);
  4277   4520         if( rc!=SQLITE_OK ){
  4278   4521           sqlite3_free(pNew->lockingContext);
  4279         -        close(h);
         4522  +        robust_close(pNew, h, __LINE__);
  4280   4523           h = -1;
  4281   4524         }
  4282   4525         unixLeaveMutex();        
  4283   4526       }
  4284   4527     }
  4285   4528   #endif
  4286   4529   
................................................................................
  4323   4566       unixLeaveMutex();
  4324   4567     }
  4325   4568   #endif
  4326   4569     
  4327   4570     pNew->lastErrno = 0;
  4328   4571   #if OS_VXWORKS
  4329   4572     if( rc!=SQLITE_OK ){
  4330         -    if( h>=0 ) close(h);
         4573  +    if( h>=0 ) robust_close(pNew, h, __LINE__);
  4331   4574       h = -1;
  4332   4575       unlink(zFilename);
  4333   4576       isDelete = 0;
  4334   4577     }
  4335   4578     pNew->isDelete = isDelete;
  4336   4579   #endif
  4337   4580     if( rc!=SQLITE_OK ){
  4338         -    if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
  4339         -    if( h>=0 ) close(h);
         4581  +    if( dirfd>=0 ) robust_close(pNew, dirfd, __LINE__);
         4582  +    if( h>=0 ) robust_close(pNew, h, __LINE__);
  4340   4583     }else{
  4341   4584       pNew->pMethod = pLockingStyle;
  4342   4585       OpenCounter(+1);
  4343   4586     }
  4344   4587     return rc;
  4345   4588   }
  4346   4589   
................................................................................
  4359   4602     int fd = -1;
  4360   4603     char zDirname[MAX_PATHNAME+1];
  4361   4604   
  4362   4605     sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
  4363   4606     for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
  4364   4607     if( ii>0 ){
  4365   4608       zDirname[ii] = '\0';
  4366         -    fd = open(zDirname, O_RDONLY|O_BINARY, 0);
         4609  +    fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
  4367   4610       if( fd>=0 ){
  4368   4611   #ifdef FD_CLOEXEC
  4369         -      fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
         4612  +      osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
  4370   4613   #endif
  4371   4614         OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
  4372   4615       }
  4373   4616     }
  4374   4617     *pFd = fd;
  4375   4618     return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
  4376   4619   }
................................................................................
  4392   4635     struct stat buf;
  4393   4636     const char *zDir = 0;
  4394   4637   
  4395   4638     azDirs[0] = sqlite3_temp_directory;
  4396   4639     if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
  4397   4640     for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
  4398   4641       if( zDir==0 ) continue;
  4399         -    if( stat(zDir, &buf) ) continue;
         4642  +    if( osStat(zDir, &buf) ) continue;
  4400   4643       if( !S_ISDIR(buf.st_mode) ) continue;
  4401         -    if( access(zDir, 07) ) continue;
         4644  +    if( osAccess(zDir, 07) ) continue;
  4402   4645       break;
  4403   4646     }
  4404   4647     return zDir;
  4405   4648   }
  4406   4649   
  4407   4650   /*
  4408   4651   ** Create a temporary file name in zBuf.  zBuf must be allocated
................................................................................
  4437   4680       sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
  4438   4681       j = (int)strlen(zBuf);
  4439   4682       sqlite3_randomness(15, &zBuf[j]);
  4440   4683       for(i=0; i<15; i++, j++){
  4441   4684         zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
  4442   4685       }
  4443   4686       zBuf[j] = 0;
  4444         -  }while( access(zBuf,0)==0 );
         4687  +  }while( osAccess(zBuf,0)==0 );
  4445   4688     return SQLITE_OK;
  4446   4689   }
  4447   4690   
  4448   4691   #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
  4449   4692   /*
  4450   4693   ** Routine to transform a unixFile into a proxy-locking unixFile.
  4451   4694   ** Implementation in the proxy-lock division, but used by unixOpen()
................................................................................
  4698   4941       mode_t openMode;              /* Permissions to create file with */
  4699   4942       rc = findCreateFileMode(zName, flags, &openMode);
  4700   4943       if( rc!=SQLITE_OK ){
  4701   4944         assert( !p->pUnused );
  4702   4945         assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
  4703   4946         return rc;
  4704   4947       }
  4705         -    fd = open(zName, openFlags, openMode);
         4948  +    fd = robust_open(zName, openFlags, openMode);
  4706   4949       OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
  4707   4950       if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
  4708   4951         /* Failed to open the file for read/write access. Try read-only. */
  4709   4952         flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
  4710   4953         openFlags &= ~(O_RDWR|O_CREAT);
  4711   4954         flags |= SQLITE_OPEN_READONLY;
  4712   4955         openFlags |= O_RDONLY;
  4713         -      fd = open(zName, openFlags, openMode);
         4956  +      isReadonly = 1;
         4957  +      fd = robust_open(zName, openFlags, openMode);
  4714   4958       }
  4715   4959       if( fd<0 ){
  4716   4960         rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
  4717   4961         goto open_finished;
  4718   4962       }
  4719   4963     }
  4720   4964     assert( fd>=0 );
................................................................................
  4744   4988       rc = openDirectory(zPath, &dirfd);
  4745   4989       if( rc!=SQLITE_OK ){
  4746   4990         /* It is safe to close fd at this point, because it is guaranteed not
  4747   4991         ** to be open on a database file. If it were open on a database file,
  4748   4992         ** it would not be safe to close as this would release any locks held
  4749   4993         ** on the file by this process.  */
  4750   4994         assert( eType!=SQLITE_OPEN_MAIN_DB );
  4751         -      close(fd);             /* silently leak if fail, already in error */
         4995  +      robust_close(p, fd, __LINE__);
  4752   4996         goto open_finished;
  4753   4997       }
  4754   4998     }
  4755   4999   
  4756   5000   #ifdef FD_CLOEXEC
  4757         -  fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
         5001  +  osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
  4758   5002   #endif
  4759   5003   
  4760   5004     noLock = eType!=SQLITE_OPEN_MAIN_DB;
  4761   5005   
  4762   5006     
  4763   5007   #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
  4764   5008     struct statfs fsInfo;
  4765   5009     if( fstatfs(fd, &fsInfo) == -1 ){
  4766   5010       ((unixFile*)pFile)->lastErrno = errno;
  4767         -    if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */
  4768         -    close(fd); /* silently leak if fail, in error */
         5011  +    if( dirfd>=0 ) robust_close(p, dirfd, __LINE__);
         5012  +    robust_close(p, fd, __LINE__);
  4769   5013       return SQLITE_IOERR_ACCESS;
  4770   5014     }
  4771   5015     if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
  4772   5016       ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
  4773   5017     }
  4774   5018   #endif
  4775   5019     
................................................................................
  4793   5037           ** on that file that are currently holding advisory locks on it,
  4794   5038           ** then the call to close() will cancel those locks. In practice,
  4795   5039           ** we're assuming that statfs() doesn't fail very often. At least
  4796   5040           ** not while other file descriptors opened by the same process on
  4797   5041           ** the same file are working.  */
  4798   5042           p->lastErrno = errno;
  4799   5043           if( dirfd>=0 ){
  4800         -          close(dirfd); /* silently leak if fail, in error */
         5044  +          robust_close(p, dirfd, __LINE__);
  4801   5045           }
  4802         -        close(fd); /* silently leak if fail, in error */
         5046  +        robust_close(p, fd, __LINE__);
  4803   5047           rc = SQLITE_IOERR_ACCESS;
  4804   5048           goto open_finished;
  4805   5049         }
  4806   5050         useProxy = !(fsInfo.f_flags&MNT_LOCAL);
  4807   5051       }
  4808   5052       if( useProxy ){
  4809         -      rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
         5053  +      rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
         5054  +                          isDelete, isReadonly);
  4810   5055         if( rc==SQLITE_OK ){
  4811   5056           rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
  4812   5057           if( rc!=SQLITE_OK ){
  4813   5058             /* Use unixClose to clean up the resources added in fillInUnixFile 
  4814   5059             ** and clear all the structure's references.  Specifically, 
  4815   5060             ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op 
  4816   5061             */
................................................................................
  4819   5064           }
  4820   5065         }
  4821   5066         goto open_finished;
  4822   5067       }
  4823   5068     }
  4824   5069   #endif
  4825   5070     
  4826         -  rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
         5071  +  rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
         5072  +                      isDelete, isReadonly);
  4827   5073   open_finished:
  4828   5074     if( rc!=SQLITE_OK ){
  4829   5075       sqlite3_free(p->pUnused);
  4830   5076     }
  4831   5077     return rc;
  4832   5078   }
  4833   5079   
................................................................................
  4856   5102         if( fsync(fd)==-1 )
  4857   5103   #else
  4858   5104         if( fsync(fd) )
  4859   5105   #endif
  4860   5106         {
  4861   5107           rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
  4862   5108         }
  4863         -      if( close(fd)&&!rc ){
  4864         -        rc = unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", zPath);
  4865         -      }
         5109  +      robust_close(0, fd, __LINE__);
  4866   5110       }
  4867   5111     }
  4868   5112   #endif
  4869   5113     return rc;
  4870   5114   }
  4871   5115   
  4872   5116   /*
................................................................................
  4898   5142       case SQLITE_ACCESS_READ:
  4899   5143         amode = R_OK;
  4900   5144         break;
  4901   5145   
  4902   5146       default:
  4903   5147         assert(!"Invalid flags argument");
  4904   5148     }
  4905         -  *pResOut = (access(zPath, amode)==0);
         5149  +  *pResOut = (osAccess(zPath, amode)==0);
  4906   5150     if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
  4907   5151       struct stat buf;
  4908   5152       if( 0==stat(zPath, &buf) && buf.st_size==0 ){
  4909   5153         *pResOut = 0;
  4910   5154       }
  4911   5155     }
  4912   5156     return SQLITE_OK;
................................................................................
  4940   5184     UNUSED_PARAMETER(pVfs);
  4941   5185   
  4942   5186     zOut[nOut-1] = '\0';
  4943   5187     if( zPath[0]=='/' ){
  4944   5188       sqlite3_snprintf(nOut, zOut, "%s", zPath);
  4945   5189     }else{
  4946   5190       int nCwd;
  4947         -    if( getcwd(zOut, nOut-1)==0 ){
         5191  +    if( osGetcwd(zOut, nOut-1)==0 ){
  4948   5192         return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
  4949   5193       }
  4950   5194       nCwd = (int)strlen(zOut);
  4951   5195       sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
  4952   5196     }
  4953   5197     return SQLITE_OK;
  4954   5198   }
................................................................................
  5035   5279     ** that we always use the same random number sequence.  This makes the
  5036   5280     ** tests repeatable.
  5037   5281     */
  5038   5282     memset(zBuf, 0, nBuf);
  5039   5283   #if !defined(SQLITE_TEST)
  5040   5284     {
  5041   5285       int pid, fd;
  5042         -    fd = open("/dev/urandom", O_RDONLY);
         5286  +    fd = robust_open("/dev/urandom", O_RDONLY, 0);
  5043   5287       if( fd<0 ){
  5044   5288         time_t t;
  5045   5289         time(&t);
  5046   5290         memcpy(zBuf, &t, sizeof(t));
  5047   5291         pid = getpid();
  5048   5292         memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
  5049   5293         assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
  5050   5294         nBuf = sizeof(t) + sizeof(pid);
  5051   5295       }else{
  5052         -      do{ nBuf = read(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR );
  5053         -      close(fd);
         5296  +      do{ nBuf = osRead(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR );
         5297  +      robust_close(0, fd, __LINE__);
  5054   5298       }
  5055   5299     }
  5056   5300   #endif
  5057   5301     return nBuf;
  5058   5302   }
  5059   5303   
  5060   5304   
................................................................................
  5444   5688     }else{
  5445   5689       pUnused = sqlite3_malloc(sizeof(*pUnused));
  5446   5690       if( !pUnused ){
  5447   5691         return SQLITE_NOMEM;
  5448   5692       }
  5449   5693     }
  5450   5694     if( fd<0 ){
  5451         -    fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
         5695  +    fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
  5452   5696       terrno = errno;
  5453   5697       if( fd<0 && errno==ENOENT && islockfile ){
  5454   5698         if( proxyCreateLockPath(path) == SQLITE_OK ){
  5455         -        fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
         5699  +        fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
  5456   5700         }
  5457   5701       }
  5458   5702     }
  5459   5703     if( fd<0 ){
  5460   5704       openFlags = O_RDONLY;
  5461         -    fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
         5705  +    fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
  5462   5706       terrno = errno;
  5463   5707     }
  5464   5708     if( fd<0 ){
  5465   5709       if( islockfile ){
  5466   5710         return SQLITE_BUSY;
  5467   5711       }
  5468   5712       switch (terrno) {
................................................................................
  5483   5727     memset(pNew, 0, sizeof(unixFile));
  5484   5728     pNew->openFlags = openFlags;
  5485   5729     dummyVfs.pAppData = (void*)&autolockIoFinder;
  5486   5730     pUnused->fd = fd;
  5487   5731     pUnused->flags = openFlags;
  5488   5732     pNew->pUnused = pUnused;
  5489   5733     
  5490         -  rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0);
         5734  +  rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0);
  5491   5735     if( rc==SQLITE_OK ){
  5492   5736       *ppFile = pNew;
  5493   5737       return SQLITE_OK;
  5494   5738     }
  5495   5739   end_create_proxy:    
  5496         -  close(fd); /* silently leak fd if error, we're already in error */
         5740  +  robust_close(pNew, fd, __LINE__);
  5497   5741     sqlite3_free(pNew);
  5498   5742     sqlite3_free(pUnused);
  5499   5743     return rc;
  5500   5744   }
  5501   5745   
  5502   5746   #ifdef SQLITE_TEST
  5503   5747   /* simulate multiple hosts by creating unique hostid file paths */
................................................................................
  5568   5812     pathLen = strlcpy(tPath, cPath, MAXPATHLEN);
  5569   5813     if( pathLen>MAXPATHLEN || pathLen<6 || 
  5570   5814        (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){
  5571   5815       sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen);
  5572   5816       goto end_breaklock;
  5573   5817     }
  5574   5818     /* read the conch content */
  5575         -  readLen = pread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0);
         5819  +  readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0);
  5576   5820     if( readLen<PROXY_PATHINDEX ){
  5577   5821       sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen);
  5578   5822       goto end_breaklock;
  5579   5823     }
  5580   5824     /* write it out to the temporary break file */
  5581         -  fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS);
         5825  +  fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL),
         5826  +                   SQLITE_DEFAULT_FILE_PERMISSIONS);
  5582   5827     if( fd<0 ){
  5583   5828       sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
  5584   5829       goto end_breaklock;
  5585   5830     }
  5586         -  if( pwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
         5831  +  if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
  5587   5832       sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno);
  5588   5833       goto end_breaklock;
  5589   5834     }
  5590   5835     if( rename(tPath, cPath) ){
  5591   5836       sqlite3_snprintf(sizeof(errmsg), errmsg, "rename failed (%d)", errno);
  5592   5837       goto end_breaklock;
  5593   5838     }
  5594   5839     rc = 0;
  5595   5840     fprintf(stderr, "broke stale lock on %s\n", cPath);
  5596         -  close(conchFile->h);
         5841  +  robust_close(pFile, conchFile->h, __LINE__);
  5597   5842     conchFile->h = fd;
  5598   5843     conchFile->openFlags = O_RDWR | O_CREAT;
  5599   5844   
  5600   5845   end_breaklock:
  5601   5846     if( rc ){
  5602   5847       if( fd>=0 ){
  5603   5848         unlink(tPath);
  5604         -      close(fd);
         5849  +      robust_close(pFile, fd, __LINE__);
  5605   5850       }
  5606   5851       fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
  5607   5852     }
  5608   5853     return rc;
  5609   5854   }
  5610   5855   
  5611   5856   /* Take the requested lock on the conch file and break a stale lock if the 
................................................................................
  5625   5870         /* If the lock failed (busy):
  5626   5871          * 1st try: get the mod time of the conch, wait 0.5s and try again. 
  5627   5872          * 2nd try: fail if the mod time changed or host id is different, wait 
  5628   5873          *           10 sec and try again
  5629   5874          * 3rd try: break the lock unless the mod time has changed.
  5630   5875          */
  5631   5876         struct stat buf;
  5632         -      if( fstat(conchFile->h, &buf) ){
         5877  +      if( osFstat(conchFile->h, &buf) ){
  5633   5878           pFile->lastErrno = errno;
  5634   5879           return SQLITE_IOERR_LOCK;
  5635   5880         }
  5636   5881         
  5637   5882         if( nTries==1 ){
  5638   5883           conchModTime = buf.st_mtimespec;
  5639   5884           usleep(500000); /* wait 0.5 sec and try the lock again*/
................................................................................
  5644   5889         if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || 
  5645   5890            conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){
  5646   5891           return SQLITE_BUSY;
  5647   5892         }
  5648   5893         
  5649   5894         if( nTries==2 ){  
  5650   5895           char tBuf[PROXY_MAXCONCHLEN];
  5651         -        int len = pread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
         5896  +        int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
  5652   5897           if( len<0 ){
  5653   5898             pFile->lastErrno = errno;
  5654   5899             return SQLITE_IOERR_LOCK;
  5655   5900           }
  5656   5901           if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
  5657   5902             /* don't break the lock if the host id doesn't match */
  5658   5903             if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){
................................................................................
  5814   6059           rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0);
  5815   6060           fsync(conchFile->h);
  5816   6061           /* If we created a new conch file (not just updated the contents of a 
  5817   6062            ** valid conch file), try to match the permissions of the database 
  5818   6063            */
  5819   6064           if( rc==SQLITE_OK && createConch ){
  5820   6065             struct stat buf;
  5821         -          int rc;
  5822         -          int err = fstat(pFile->h, &buf);
         6066  +          int err = osFstat(pFile->h, &buf);
  5823   6067             if( err==0 ){
  5824   6068               mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP |
  5825   6069                                           S_IROTH|S_IWOTH);
  5826   6070               /* try to match the database file R/W permissions, ignore failure */
  5827   6071   #ifndef SQLITE_PROXY_DEBUG
  5828         -            fchmod(conchFile->h, cmode);
         6072  +            osFchmod(conchFile->h, cmode);
  5829   6073   #else
  5830   6074               do{
  5831         -              rc = fchmod(conchFile->h, cmode);
         6075  +              rc = osFchmod(conchFile->h, cmode);
  5832   6076               }while( rc==(-1) && errno==EINTR );
  5833   6077               if( rc!=0 ){
  5834   6078                 int code = errno;
  5835   6079                 fprintf(stderr, "fchmod %o FAILED with %d %s\n",
  5836   6080                         cmode, code, strerror(code));
  5837   6081               } else {
  5838   6082                 fprintf(stderr, "fchmod %o SUCCEDED\n",cmode);
................................................................................
  5847   6091         }
  5848   6092         conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
  5849   6093         
  5850   6094       end_takeconch:
  5851   6095         OSTRACE(("TRANSPROXY: CLOSE  %d\n", pFile->h));
  5852   6096         if( rc==SQLITE_OK && pFile->openFlags ){
  5853   6097           if( pFile->h>=0 ){
  5854         -#ifdef STRICT_CLOSE_ERROR
  5855         -          if( close(pFile->h) ){
  5856         -            pFile->lastErrno = errno;
  5857         -            return SQLITE_IOERR_CLOSE;
  5858         -          }
  5859         -#else
  5860         -          close(pFile->h); /* silently leak fd if fail */
  5861         -#endif
         6098  +          robust_close(pFile, pFile->h, __LINE__);
  5862   6099           }
  5863   6100           pFile->h = -1;
  5864         -        int fd = open(pCtx->dbPath, pFile->openFlags,
         6101  +        int fd = robust_open(pCtx->dbPath, pFile->openFlags,
  5865   6102                         SQLITE_DEFAULT_FILE_PERMISSIONS);
  5866   6103           OSTRACE(("TRANSPROXY: OPEN  %d\n", fd));
  5867   6104           if( fd>=0 ){
  5868   6105             pFile->h = fd;
  5869   6106           }else{
  5870   6107             rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
  5871   6108              during locking */
................................................................................
  6083   6320         ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts
  6084   6321         ** that openFlags will have only one of O_RDONLY or O_RDWR.
  6085   6322         */
  6086   6323         struct statfs fsInfo;
  6087   6324         struct stat conchInfo;
  6088   6325         int goLockless = 0;
  6089   6326   
  6090         -      if( stat(pCtx->conchFilePath, &conchInfo) == -1 ) {
         6327  +      if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) {
  6091   6328           int err = errno;
  6092   6329           if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){
  6093   6330             goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY;
  6094   6331           }
  6095   6332         }
  6096   6333         if( goLockless ){
  6097   6334           pCtx->conchHeld = -1; /* read only FS/ lockless */
................................................................................
  6368   6605     ** Most finders simply return a pointer to a fixed sqlite3_io_methods
  6369   6606     ** object.  But the "autolockIoFinder" available on MacOSX does a little
  6370   6607     ** more than that; it looks at the filesystem type that hosts the 
  6371   6608     ** database file and tries to choose an locking method appropriate for
  6372   6609     ** that filesystem time.
  6373   6610     */
  6374   6611     #define UNIXVFS(VFSNAME, FINDER) {                        \
  6375         -    2,                    /* iVersion */                    \
         6612  +    3,                    /* iVersion */                    \
  6376   6613       sizeof(unixFile),     /* szOsFile */                    \
  6377   6614       MAX_PATHNAME,         /* mxPathname */                  \
  6378   6615       0,                    /* pNext */                       \
  6379   6616       VFSNAME,              /* zName */                       \
  6380   6617       (void*)&FINDER,       /* pAppData */                    \
  6381   6618       unixOpen,             /* xOpen */                       \
  6382   6619       unixDelete,           /* xDelete */                     \
................................................................................
  6387   6624       unixDlSym,            /* xDlSym */                      \
  6388   6625       unixDlClose,          /* xDlClose */                    \
  6389   6626       unixRandomness,       /* xRandomness */                 \
  6390   6627       unixSleep,            /* xSleep */                      \
  6391   6628       unixCurrentTime,      /* xCurrentTime */                \
  6392   6629       unixGetLastError,     /* xGetLastError */               \
  6393   6630       unixCurrentTimeInt64, /* xCurrentTimeInt64 */           \
         6631  +    unixSetSystemCall,    /* xSetSystemCall */              \
         6632  +    unixGetSystemCall,    /* xGetSystemCall */              \
         6633  +    unixNextSystemCall,   /* xNextSystemCall */             \
  6394   6634     }
  6395   6635   
  6396   6636     /*
  6397   6637     ** All default VFSes for unix are contained in the following array.
  6398   6638     **
  6399   6639     ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
  6400   6640     ** by the SQLite core when the VFS is registered.  So the following
................................................................................
  6404   6644   #if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
  6405   6645       UNIXVFS("unix",          autolockIoFinder ),
  6406   6646   #else
  6407   6647       UNIXVFS("unix",          posixIoFinder ),
  6408   6648   #endif
  6409   6649       UNIXVFS("unix-none",     nolockIoFinder ),
  6410   6650       UNIXVFS("unix-dotfile",  dotlockIoFinder ),
         6651  +    UNIXVFS("unix-excl",     posixIoFinder ),
  6411   6652   #if OS_VXWORKS
  6412   6653       UNIXVFS("unix-namedsem", semIoFinder ),
  6413   6654   #endif
  6414   6655   #if SQLITE_ENABLE_LOCKING_STYLE
  6415   6656       UNIXVFS("unix-posix",    posixIoFinder ),
  6416   6657   #if !OS_VXWORKS
  6417   6658       UNIXVFS("unix-flock",    flockIoFinder ),

Changes to src/os_win.c.

  2742   2742   
  2743   2743   
  2744   2744   /*
  2745   2745   ** Initialize and deinitialize the operating system interface.
  2746   2746   */
  2747   2747   int sqlite3_os_init(void){
  2748   2748     static sqlite3_vfs winVfs = {
  2749         -    2,                   /* iVersion */
         2749  +    3,                   /* iVersion */
  2750   2750       sizeof(winFile),     /* szOsFile */
  2751   2751       MAX_PATH,            /* mxPathname */
  2752   2752       0,                   /* pNext */
  2753   2753       "win32",             /* zName */
  2754   2754       0,                   /* pAppData */
  2755   2755       winOpen,             /* xOpen */
  2756   2756       winDelete,           /* xDelete */
................................................................................
  2761   2761       winDlSym,            /* xDlSym */
  2762   2762       winDlClose,          /* xDlClose */
  2763   2763       winRandomness,       /* xRandomness */
  2764   2764       winSleep,            /* xSleep */
  2765   2765       winCurrentTime,      /* xCurrentTime */
  2766   2766       winGetLastError,     /* xGetLastError */
  2767   2767       winCurrentTimeInt64, /* xCurrentTimeInt64 */
         2768  +    0,                   /* xSetSystemCall */
         2769  +    0,                   /* xGetSystemCall */
         2770  +    0,                   /* xNextSystemCall */
  2768   2771     };
  2769   2772   
  2770   2773   #ifndef SQLITE_OMIT_WAL
  2771   2774     /* get memory map allocation granularity */
  2772   2775     memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
  2773   2776     GetSystemInfo(&winSysInfo);
  2774   2777     assert(winSysInfo.dwAllocationGranularity > 0);

Changes to src/pragma.c.

   380    380         sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
   381    381         pParse->nMem += 2;
   382    382         addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
   383    383         sqlite3VdbeChangeP1(v, addr, iDb);
   384    384         sqlite3VdbeChangeP1(v, addr+1, iDb);
   385    385         sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
   386    386       }else{
   387         -      int size = sqlite3Atoi(zRight);
   388         -      if( size<0 ) size = -size;
          387  +      int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
   389    388         sqlite3BeginWriteOperation(pParse, 0, iDb);
   390    389         sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
   391    390         sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
   392    391         pDb->pSchema->cache_size = size;
   393    392         sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
   394    393       }
   395    394     }else
................................................................................
   690    689     ** N should be a positive integer.
   691    690     */
   692    691     if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
   693    692       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
   694    693       if( !zRight ){
   695    694         returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
   696    695       }else{
   697         -      int size = sqlite3Atoi(zRight);
   698         -      if( size<0 ) size = -size;
          696  +      int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
   699    697         pDb->pSchema->cache_size = size;
   700    698         sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
   701    699       }
   702    700     }else
   703    701   
   704    702     /*
   705    703     **   PRAGMA temp_store

Changes to src/prepare.c.

   137    137     int size;
   138    138     Table *pTab;
   139    139     Db *pDb;
   140    140     char const *azArg[4];
   141    141     int meta[5];
   142    142     InitData initData;
   143    143     char const *zMasterSchema;
   144         -  char const *zMasterName = SCHEMA_TABLE(iDb);
          144  +  char const *zMasterName;
   145    145     int openedTransaction = 0;
   146    146   
   147    147     /*
   148    148     ** The master database table has a structure like this
   149    149     */
   150    150     static const char master_schema[] = 
   151    151        "CREATE TABLE sqlite_master(\n"
................................................................................
   274    274       }
   275    275     }else{
   276    276       DbSetProperty(db, iDb, DB_Empty);
   277    277     }
   278    278     pDb->pSchema->enc = ENC(db);
   279    279   
   280    280     if( pDb->pSchema->cache_size==0 ){
   281         -    size = meta[BTREE_DEFAULT_CACHE_SIZE-1];
          281  +    size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]);
   282    282       if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
   283         -    if( size<0 ) size = -size;
   284    283       pDb->pSchema->cache_size = size;
   285    284       sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
   286    285     }
   287    286   
   288    287     /*
   289    288     ** file_format==1    Version 3.0.0.
   290    289     ** file_format==2    Version 3.1.3.  // ALTER TABLE ADD COLUMN

Changes to src/printf.c.

   396    396               v = va_arg(ap,i64);
   397    397             }else if( flag_long ){
   398    398               v = va_arg(ap,long int);
   399    399             }else{
   400    400               v = va_arg(ap,int);
   401    401             }
   402    402             if( v<0 ){
   403         -            longvalue = -v;
          403  +            if( v==SMALLEST_INT64 ){
          404  +              longvalue = ((u64)1)<<63;
          405  +            }else{
          406  +              longvalue = -v;
          407  +            }
   404    408               prefix = '-';
   405    409             }else{
   406    410               longvalue = v;
   407    411               if( flag_plussign )        prefix = '+';
   408    412               else if( flag_blanksign )  prefix = ' ';
   409    413               else                       prefix = 0;
   410    414             }

Changes to src/shell.c.

   415    415     char nullvalue[20];    /* The text to print when a NULL comes back from
   416    416                            ** the database */
   417    417     struct previous_mode_data explainPrev;
   418    418                            /* Holds the mode information just before
   419    419                            ** .explain ON */
   420    420     char outfile[FILENAME_MAX]; /* Filename for *out */
   421    421     const char *zDbFilename;    /* name of the database file */
          422  +  const char *zVfs;           /* Name of VFS to use */
   422    423     sqlite3_stmt *pStmt;   /* Current statement if any. */
   423    424     FILE *pLog;            /* Write log output here */
   424    425   };
   425    426   
   426    427   /*
   427    428   ** These are the allowed modes.
   428    429   */
................................................................................
  2168   2169           printf("\n");
  2169   2170         }
  2170   2171       }
  2171   2172       sqlite3_free_table(azResult);
  2172   2173     }else
  2173   2174   
  2174   2175     if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
         2176  +    static const struct {
         2177  +       const char *zCtrlName;   /* Name of a test-control option */
         2178  +       int ctrlCode;            /* Integer code for that option */
         2179  +    } aCtrl[] = {
         2180  +      { "prng_save",             SQLITE_TESTCTRL_PRNG_SAVE              },
         2181  +      { "prng_restore",          SQLITE_TESTCTRL_PRNG_RESTORE           },
         2182  +      { "prng_reset",            SQLITE_TESTCTRL_PRNG_RESET             },
         2183  +      { "bitvec_test",           SQLITE_TESTCTRL_BITVEC_TEST            },
         2184  +      { "fault_install",         SQLITE_TESTCTRL_FAULT_INSTALL          },
         2185  +      { "benign_malloc_hooks",   SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS    },
         2186  +      { "pending_byte",          SQLITE_TESTCTRL_PENDING_BYTE           },
         2187  +      { "assert",                SQLITE_TESTCTRL_ASSERT                 },
         2188  +      { "always",                SQLITE_TESTCTRL_ALWAYS                 },
         2189  +      { "reserve",               SQLITE_TESTCTRL_RESERVE                },
         2190  +      { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
         2191  +      { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
         2192  +      { "pghdrsz",               SQLITE_TESTCTRL_PGHDRSZ                },
         2193  +      { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },
         2194  +    };
  2175   2195       int testctrl = -1;
  2176   2196       int rc = 0;
         2197  +    int i, n;
  2177   2198       open_db(p);
  2178   2199   
  2179         -    /* convert testctrl text option to value. allow only the first 
  2180         -    ** three characters of the option to be used or the numerical 
  2181         -    ** value. */
  2182         -         if( strncmp( azArg[1], "prng_save", 6 )==0 )            testctrl = SQLITE_TESTCTRL_PRNG_SAVE;                        
  2183         -    else if( strncmp( azArg[1], "prng_restore", 10 )==0 )        testctrl = SQLITE_TESTCTRL_PRNG_RESTORE;        
  2184         -    else if( strncmp( azArg[1], "prng_reset", 10 )==0 )          testctrl = SQLITE_TESTCTRL_PRNG_RESET;          
  2185         -    else if( strncmp( azArg[1], "bitvec_test", 6 )==3 )          testctrl = SQLITE_TESTCTRL_BITVEC_TEST;         
  2186         -    else if( strncmp( azArg[1], "fault_install", 6 )==3 )        testctrl = SQLITE_TESTCTRL_FAULT_INSTALL;       
  2187         -    else if( strncmp( azArg[1], "benign_malloc_hooks", 3 )==0 )  testctrl = SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS; 
  2188         -    else if( strncmp( azArg[1], "pending_byte", 3 )==0 )         testctrl = SQLITE_TESTCTRL_PENDING_BYTE;        
  2189         -    else if( strncmp( azArg[1], "assert", 3 )==0 )               testctrl = SQLITE_TESTCTRL_ASSERT;              
  2190         -    else if( strncmp( azArg[1], "always", 3 )==0 )               testctrl = SQLITE_TESTCTRL_ALWAYS;              
  2191         -    else if( strncmp( azArg[1], "reserve", 3 )==0 )              testctrl = SQLITE_TESTCTRL_RESERVE;             
  2192         -    else if( strncmp( azArg[1], "optimizations", 3 )==0 )        testctrl = SQLITE_TESTCTRL_OPTIMIZATIONS;       
  2193         -    else if( strncmp( azArg[1], "iskeyword", 3 )==0 )            testctrl = SQLITE_TESTCTRL_ISKEYWORD;           
  2194         -    else if( strncmp( azArg[1], "pghdrsz", 3 )==0 )              testctrl = SQLITE_TESTCTRL_PGHDRSZ;             
  2195         -    else if( strncmp( azArg[1], "scratchmalloc", 3 )==0 )        testctrl = SQLITE_TESTCTRL_SCRATCHMALLOC;       
  2196         -    else                                                         testctrl = atoi(azArg[1]);
  2197         -
         2200  +    /* convert testctrl text option to value. allow any unique prefix
         2201  +    ** of the option name, or a numerical value. */
         2202  +    n = strlen(azArg[1]);
         2203  +    for(i=0; i<sizeof(aCtrl)/sizeof(aCtrl[0]); i++){
         2204  +      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
         2205  +        if( testctrl<0 ){
         2206  +          testctrl = aCtrl[i].ctrlCode;
         2207  +        }else{
         2208  +          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
         2209  +          testctrl = -1;
         2210  +          break;
         2211  +        }
         2212  +      }
         2213  +    }
         2214  +    if( testctrl<0 ) testctrl = atoi(azArg[1]);
  2198   2215       if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
  2199   2216         fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
  2200   2217       }else{
  2201   2218         switch(testctrl){
  2202   2219   
  2203   2220           /* sqlite3_test_control(int, db, int) */
  2204   2221           case SQLITE_TESTCTRL_OPTIMIZATIONS:
  2205   2222           case SQLITE_TESTCTRL_RESERVE:             
  2206   2223             if( nArg==3 ){
  2207   2224               int opt = (int)strtol(azArg[2], 0, 0);        
  2208   2225               rc = sqlite3_test_control(testctrl, p->db, opt);
  2209   2226               printf("%d (0x%08x)\n", rc, rc);
  2210   2227             } else {
  2211         -            fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]);
         2228  +            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
         2229  +                    azArg[1]);
  2212   2230             }
  2213   2231             break;
  2214   2232   
  2215   2233           /* sqlite3_test_control(int) */
  2216   2234           case SQLITE_TESTCTRL_PRNG_SAVE:           
  2217   2235           case SQLITE_TESTCTRL_PRNG_RESTORE:        
  2218   2236           case SQLITE_TESTCTRL_PRNG_RESET:
................................................................................
  2228   2246           /* sqlite3_test_control(int, uint) */
  2229   2247           case SQLITE_TESTCTRL_PENDING_BYTE:        
  2230   2248             if( nArg==3 ){
  2231   2249               unsigned int opt = (unsigned int)atoi(azArg[2]);        
  2232   2250               rc = sqlite3_test_control(testctrl, opt);
  2233   2251               printf("%d (0x%08x)\n", rc, rc);
  2234   2252             } else {
  2235         -            fprintf(stderr,"Error: testctrl %s takes a single unsigned int option\n", azArg[1]);
         2253  +            fprintf(stderr,"Error: testctrl %s takes a single unsigned"
         2254  +                           " int option\n", azArg[1]);
  2236   2255             }
  2237   2256             break;
  2238   2257             
  2239   2258           /* sqlite3_test_control(int, int) */
  2240   2259           case SQLITE_TESTCTRL_ASSERT:              
  2241   2260           case SQLITE_TESTCTRL_ALWAYS:              
  2242   2261             if( nArg==3 ){
  2243   2262               int opt = atoi(azArg[2]);        
  2244   2263               rc = sqlite3_test_control(testctrl, opt);
  2245   2264               printf("%d (0x%08x)\n", rc, rc);
  2246   2265             } else {
  2247         -            fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]);
         2266  +            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
         2267  +                            azArg[1]);
  2248   2268             }
  2249   2269             break;
  2250   2270   
  2251   2271           /* sqlite3_test_control(int, char *) */
  2252   2272   #ifdef SQLITE_N_KEYWORD
  2253   2273           case SQLITE_TESTCTRL_ISKEYWORD:           
  2254   2274             if( nArg==3 ){
  2255   2275               const char *opt = azArg[2];        
  2256   2276               rc = sqlite3_test_control(testctrl, opt);
  2257   2277               printf("%d (0x%08x)\n", rc, rc);
  2258   2278             } else {
  2259         -            fprintf(stderr,"Error: testctrl %s takes a single char * option\n", azArg[1]);
         2279  +            fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
         2280  +                            azArg[1]);
  2260   2281             }
  2261   2282             break;
  2262   2283   #endif
  2263   2284   
  2264   2285           case SQLITE_TESTCTRL_BITVEC_TEST:         
  2265   2286           case SQLITE_TESTCTRL_FAULT_INSTALL:       
  2266   2287           case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: 
  2267   2288           case SQLITE_TESTCTRL_SCRATCHMALLOC:       
  2268   2289           default:
  2269         -          fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", azArg[1]);
         2290  +          fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
         2291  +                  azArg[1]);
  2270   2292             break;
  2271   2293         }
  2272   2294       }
  2273   2295     }else
  2274   2296   
  2275   2297     if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
  2276   2298       open_db(p);
  2277   2299       sqlite3_busy_timeout(p->db, atoi(azArg[1]));
  2278   2300     }else
  2279   2301       
  2280         -  if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
         2302  +  if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
         2303  +   && nArg==2
         2304  +  ){
  2281   2305       enableTimer = booleanValue(azArg[1]);
  2282   2306     }else
  2283   2307     
  2284   2308     if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
  2285   2309       int j;
  2286   2310       assert( nArg<=ArraySize(azArg) );
  2287   2311       for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
................................................................................
  2460   2484         }
  2461   2485         free(zSql);
  2462   2486         zSql = 0;
  2463   2487         nSql = 0;
  2464   2488       }
  2465   2489     }
  2466   2490     if( zSql ){
  2467         -    if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
         2491  +    if( !_all_whitespace(zSql) ){
         2492  +      fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
         2493  +    }
  2468   2494       free(zSql);
  2469   2495     }
  2470   2496     free(zLine);
  2471   2497     return errCnt;
  2472   2498   }
  2473   2499   
  2474   2500   /*
................................................................................
  2596   2622     "   -html                set output mode to HTML\n"
  2597   2623     "   -line                set output mode to 'line'\n"
  2598   2624     "   -list                set output mode to 'list'\n"
  2599   2625     "   -separator 'x'       set output field separator (|)\n"
  2600   2626     "   -stats               print memory stats before each finalize\n"
  2601   2627     "   -nullvalue 'text'    set text string for NULL values\n"
  2602   2628     "   -version             show SQLite version\n"
         2629  +  "   -vfs NAME            use NAME as the default VFS\n"
         2630  +#ifdef SQLITE_ENABLE_VFSTRACE
         2631  +  "   -vfstrace            enable tracing of all VFS calls\n"
         2632  +#endif
  2603   2633   ;
  2604   2634   static void usage(int showDetail){
  2605   2635     fprintf(stderr,
  2606   2636         "Usage: %s [OPTIONS] FILENAME [SQL]\n"  
  2607   2637         "FILENAME is the name of an SQLite database. A new database is created\n"
  2608   2638         "if the file does not previously exist.\n", Argv0);
  2609   2639     if( showDetail ){
................................................................................
  2680   2710           if( c=='K' ){ szHeap *= 1000; break; }
  2681   2711           if( c=='G' ){ szHeap *= 1000000000; break; }
  2682   2712         }
  2683   2713         if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
  2684   2714   #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  2685   2715         sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
  2686   2716   #endif
         2717  +#ifdef SQLITE_ENABLE_VFSTRACE
         2718  +    }else if( strcmp(argv[i],"-vfstrace")==0 ){
         2719  +      extern int vfstrace_register(
         2720  +         const char *zTraceName,
         2721  +         const char *zOldVfsName,
         2722  +         int (*xOut)(const char*,void*),
         2723  +         void *pOutArg,
         2724  +         int makeDefault
         2725  +      );
         2726  +      vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
         2727  +#endif
         2728  +    }else if( strcmp(argv[i],"-vfs")==0 ){
         2729  +      sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
         2730  +      if( pVfs ){
         2731  +        sqlite3_vfs_register(pVfs, 1);
         2732  +      }else{
         2733  +        fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
         2734  +        exit(1);
         2735  +      }
  2687   2736       }
  2688   2737     }
  2689   2738     if( i<argc ){
  2690   2739   #if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
  2691   2740       data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
  2692   2741   #else
  2693   2742       data.zDbFilename = argv[i++];
................................................................................
  2788   2837         return 0;
  2789   2838       }else if( strcmp(z,"-interactive")==0 ){
  2790   2839         stdin_is_interactive = 1;
  2791   2840       }else if( strcmp(z,"-batch")==0 ){
  2792   2841         stdin_is_interactive = 0;
  2793   2842       }else if( strcmp(z,"-heap")==0 ){
  2794   2843         i++;
         2844  +    }else if( strcmp(z,"-vfs")==0 ){
         2845  +      i++;
         2846  +    }else if( strcmp(z,"-vfstrace")==0 ){
         2847  +      i++;
  2795   2848       }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
  2796   2849         usage(1);
  2797   2850       }else{
  2798   2851         fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
  2799   2852         fprintf(stderr,"Use -help for a list of options.\n");
  2800   2853         return 1;
  2801   2854       }

Changes to src/sqlite.h.in.

   889    889   ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
   890    890   ** Day Number multipled by 86400000 (the number of milliseconds in 
   891    891   ** a 24-hour day).  
   892    892   ** ^SQLite will use the xCurrentTimeInt64() method to get the current
   893    893   ** date and time if that method is available (if iVersion is 2 or 
   894    894   ** greater and the function pointer is not NULL) and will fall back
   895    895   ** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
          896  +**
          897  +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
          898  +** are not used by the SQLite core.  These optional interfaces are provided
          899  +** by some VFSes to facilitate testing of the VFS code. By overriding 
          900  +** system calls with functions under its control, a test program can
          901  +** simulate faults and error conditions that would otherwise be difficult
          902  +** or impossible to induce.  The set of system calls that can be overridden
          903  +** varies from one VFS to another, and from one version of the same VFS to the
          904  +** next.  Applications that use these interfaces must be prepared for any
          905  +** or all of these interfaces to be NULL or for their behavior to change
          906  +** from one release to the next.  Applications must not attempt to access
          907  +** any of these methods if the iVersion of the VFS is less than 3.
   896    908   */
   897    909   typedef struct sqlite3_vfs sqlite3_vfs;
   898    910   struct sqlite3_vfs {
   899         -  int iVersion;            /* Structure version number (currently 2) */
          911  +  int iVersion;            /* Structure version number (currently 3) */
   900    912     int szOsFile;            /* Size of subclassed sqlite3_file */
   901    913     int mxPathname;          /* Maximum file pathname length */
   902    914     sqlite3_vfs *pNext;      /* Next registered VFS */
   903    915     const char *zName;       /* Name of this virtual file system */
   904    916     void *pAppData;          /* Pointer to application-specific data */
   905    917     int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
   906    918                  int flags, int *pOutFlags);
................................................................................
   918    930     /*
   919    931     ** The methods above are in version 1 of the sqlite_vfs object
   920    932     ** definition.  Those that follow are added in version 2 or later
   921    933     */
   922    934     int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
   923    935     /*
   924    936     ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
          937  +  ** Those below are for version 3 and greater.
          938  +  */
          939  +  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, void *pFunc);
          940  +  void *(*xGetSystemCall)(sqlite3_vfs*, const char *zName);
          941  +  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
          942  +  /*
          943  +  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
   925    944     ** New fields may be appended in figure versions.  The iVersion
   926    945     ** value will increment whenever this happens. 
   927    946     */
   928    947   };
   929    948   
   930    949   /*
   931    950   ** CAPI3REF: Flags for the xAccess VFS method
................................................................................
  1337   1356   ** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
  1338   1357   ** to using its default memory allocator (the system malloc() implementation),
  1339   1358   ** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
  1340   1359   ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
  1341   1360   ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
  1342   1361   ** allocator is engaged to handle all of SQLites memory allocation needs.
  1343   1362   ** The first pointer (the memory pointer) must be aligned to an 8-byte
  1344         -** boundary or subsequent behavior of SQLite will be undefined.</dd>
         1363  +** boundary or subsequent behavior of SQLite will be undefined.
         1364  +** The minimum allocation size is capped at 2^12. Reasonable values
         1365  +** for the minimum allocation size are 2^5 through 2^8.</dd>
  1345   1366   **
  1346   1367   ** <dt>SQLITE_CONFIG_MUTEX</dt>
  1347   1368   ** <dd> ^(This option takes a single argument which is a pointer to an
  1348   1369   ** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
  1349   1370   ** alternative low-level mutex routines to be used in place
  1350   1371   ** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
  1351   1372   ** content of the [sqlite3_mutex_methods] structure before the call to

Changes to src/sqliteInt.h.

  1625   1625   */
  1626   1626   struct Expr {
  1627   1627     u8 op;                 /* Operation performed by this node */
  1628   1628     char affinity;         /* The affinity of the column or 0 if not a column */
  1629   1629     u16 flags;             /* Various flags.  EP_* See below */
  1630   1630     union {
  1631   1631       char *zToken;          /* Token value. Zero terminated and dequoted */
  1632         -    int iValue;            /* Integer value if EP_IntValue */
         1632  +    int iValue;            /* Non-negative integer value if EP_IntValue */
  1633   1633     } u;
  1634   1634   
  1635   1635     /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
  1636   1636     ** space is allocated for the fields below this point. An attempt to
  1637   1637     ** access them will result in a segfault or malfunction. 
  1638   1638     *********************************************************************/
  1639   1639   
................................................................................
  2907   2907   CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
  2908   2908   CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
  2909   2909   Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
  2910   2910   Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
  2911   2911   int sqlite3CheckCollSeq(Parse *, CollSeq *);
  2912   2912   int sqlite3CheckObjectName(Parse *, const char *);
  2913   2913   void sqlite3VdbeSetChanges(sqlite3 *, int);
         2914  +int sqlite3AddInt64(i64*,i64);
         2915  +int sqlite3SubInt64(i64*,i64);
         2916  +int sqlite3MulInt64(i64*,i64);
         2917  +int sqlite3AbsInt32(int);
  2914   2918   
  2915   2919   const void *sqlite3ValueText(sqlite3_value*, u8);
  2916   2920   int sqlite3ValueBytes(sqlite3_value*, u8);
  2917   2921   void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
  2918   2922                           void(*)(void*));
  2919   2923   void sqlite3ValueFree(sqlite3_value*);
  2920   2924   sqlite3_value *sqlite3ValueNew(sqlite3 *);

Changes to src/test_config.c.

   470    470   #endif
   471    471   
   472    472   #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
   473    473     Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "0", TCL_GLOBAL_ONLY);
   474    474   #else
   475    475     Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY);
   476    476   #endif
          477  +
          478  +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
          479  +  Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "0", TCL_GLOBAL_ONLY);
          480  +#else
          481  +  Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "1", TCL_GLOBAL_ONLY);
          482  +#endif
   477    483   
   478    484   #ifdef SQLITE_OMIT_UTF16
   479    485     Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY);
   480    486   #else
   481    487     Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY);
   482    488   #endif
   483    489   

Added src/test_vfstrace.c.

            1  +/*
            2  +** 2011 March 16
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file contains code implements a VFS shim that writes diagnostic
           14  +** output for each VFS call, similar to "strace".
           15  +*/
           16  +#include <stdlib.h>
           17  +#include <string.h>
           18  +#include "sqlite3.h"
           19  +
           20  +/*
           21  +** An instance of this structure is attached to the each trace VFS to
           22  +** provide auxiliary information.
           23  +*/
           24  +typedef struct vfstrace_info vfstrace_info;
           25  +struct vfstrace_info {
           26  +  sqlite3_vfs *pRootVfs;              /* The underlying real VFS */
           27  +  int (*xOut)(const char*, void*);    /* Send output here */
           28  +  void *pOutArg;                      /* First argument to xOut */
           29  +  const char *zVfsName;               /* Name of this trace-VFS */
           30  +  sqlite3_vfs *pTraceVfs;             /* Pointer back to the trace VFS */
           31  +};
           32  +
           33  +/*
           34  +** The sqlite3_file object for the trace VFS
           35  +*/
           36  +typedef struct vfstrace_file vfstrace_file;
           37  +struct vfstrace_file {
           38  +  sqlite3_file base;        /* Base class.  Must be first */
           39  +  vfstrace_info *pInfo;     /* The trace-VFS to which this file belongs */
           40  +  const char *zFName;       /* Base name of the file */
           41  +  sqlite3_file *pReal;      /* The real underlying file */
           42  +};
           43  +
           44  +/*
           45  +** Method declarations for vfstrace_file.
           46  +*/
           47  +static int vfstraceClose(sqlite3_file*);
           48  +static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
           49  +static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64);
           50  +static int vfstraceTruncate(sqlite3_file*, sqlite3_int64 size);
           51  +static int vfstraceSync(sqlite3_file*, int flags);
           52  +static int vfstraceFileSize(sqlite3_file*, sqlite3_int64 *pSize);
           53  +static int vfstraceLock(sqlite3_file*, int);
           54  +static int vfstraceUnlock(sqlite3_file*, int);
           55  +static int vfstraceCheckReservedLock(sqlite3_file*, int *);
           56  +static int vfstraceFileControl(sqlite3_file*, int op, void *pArg);
           57  +static int vfstraceSectorSize(sqlite3_file*);
           58  +static int vfstraceDeviceCharacteristics(sqlite3_file*);
           59  +static int vfstraceShmLock(sqlite3_file*,int,int,int);
           60  +static int vfstraceShmMap(sqlite3_file*,int,int,int, void volatile **);
           61  +static void vfstraceShmBarrier(sqlite3_file*);
           62  +static int vfstraceShmUnmap(sqlite3_file*,int);
           63  +
           64  +/*
           65  +** Method declarations for vfstrace_vfs.
           66  +*/
           67  +static int vfstraceOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
           68  +static int vfstraceDelete(sqlite3_vfs*, const char *zName, int syncDir);
           69  +static int vfstraceAccess(sqlite3_vfs*, const char *zName, int flags, int *);
           70  +static int vfstraceFullPathname(sqlite3_vfs*, const char *zName, int, char *);
           71  +static void *vfstraceDlOpen(sqlite3_vfs*, const char *zFilename);
           72  +static void vfstraceDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
           73  +static void (*vfstraceDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
           74  +static void vfstraceDlClose(sqlite3_vfs*, void*);
           75  +static int vfstraceRandomness(sqlite3_vfs*, int nByte, char *zOut);
           76  +static int vfstraceSleep(sqlite3_vfs*, int microseconds);
           77  +static int vfstraceCurrentTime(sqlite3_vfs*, double*);
           78  +static int vfstraceGetLastError(sqlite3_vfs*, int, char*);
           79  +static int vfstraceCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
           80  +static int vfstraceSetSystemCall(sqlite3_vfs*, const char *zName, void *pFunc);
           81  +static void *vfstraceGetSystemCall(sqlite3_vfs*, const char *zName);
           82  +static const char *vfstraceNextSystemCall(sqlite3_vfs*, const char *zName);
           83  +
           84  +/*
           85  +** Return a pointer to the tail of the pathname.  Examples:
           86  +**
           87  +**     /home/drh/xyzzy.txt -> xyzzy.txt
           88  +**     xyzzy.txt           -> xyzzy.txt
           89  +*/
           90  +static const char *fileTail(const char *z){
           91  +  int i;
           92  +  if( z==0 ) return 0;
           93  +  i = strlen(z)-1;
           94  +  while( i>0 && z[i-1]!='/' ){ i--; }
           95  +  return &z[i];
           96  +}
           97  +
           98  +/*
           99  +** Send trace output defined by zFormat and subsequent arguments.
          100  +*/
          101  +static void vfstrace_printf(
          102  +  vfstrace_info *pInfo,
          103  +  const char *zFormat,
          104  +  ...
          105  +){
          106  +  va_list ap;
          107  +  char *zMsg;
          108  +  va_start(ap, zFormat);
          109  +  zMsg = sqlite3_vmprintf(zFormat, ap);
          110  +  va_end(ap);
          111  +  pInfo->xOut(zMsg, pInfo->pOutArg);
          112  +  sqlite3_free(zMsg);
          113  +}
          114  +
          115  +/*
          116  +** Convert value rc into a string and print it using zFormat.  zFormat
          117  +** should have exactly one %s
          118  +*/
          119  +static void vfstrace_print_errcode(
          120  +  vfstrace_info *pInfo,
          121  +  const char *zFormat,
          122  +  int rc
          123  +){
          124  +  char zBuf[50];
          125  +  char *zVal;
          126  +  switch( rc ){
          127  +    case SQLITE_OK:         zVal = "SQLITE_OK";          break;
          128  +    case SQLITE_ERROR:      zVal = "SQLITE_ERROR";       break;
          129  +    case SQLITE_PERM:       zVal = "SQLITE_PERM";        break;
          130  +    case SQLITE_ABORT:      zVal = "SQLITE_ABORT";       break;
          131  +    case SQLITE_BUSY:       zVal = "SQLITE_BUSY";        break;
          132  +    case SQLITE_NOMEM:      zVal = "SQLITE_NOMEM";       break;
          133  +    case SQLITE_READONLY:   zVal = "SQLITE_READONLY";    break;
          134  +    case SQLITE_INTERRUPT:  zVal = "SQLITE_INTERRUPT";   break;
          135  +    case SQLITE_IOERR:      zVal = "SQLITE_IOERR";       break;
          136  +    case SQLITE_CORRUPT:    zVal = "SQLITE_CORRUPT";     break;
          137  +    case SQLITE_FULL:       zVal = "SQLITE_FULL";        break;
          138  +    case SQLITE_CANTOPEN:   zVal = "SQLITE_CANTOPEN";    break;
          139  +    case SQLITE_PROTOCOL:   zVal = "SQLITE_PROTOCOL";    break;
          140  +    case SQLITE_EMPTY:      zVal = "SQLITE_EMPTY";       break;
          141  +    case SQLITE_SCHEMA:     zVal = "SQLITE_SCHEMA";      break;
          142  +    case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT";  break;
          143  +    case SQLITE_MISMATCH:   zVal = "SQLITE_MISMATCH";    break;
          144  +    case SQLITE_MISUSE:     zVal = "SQLITE_MISUSE";      break;
          145  +    case SQLITE_NOLFS:      zVal = "SQLITE_NOLFS";       break;
          146  +    case SQLITE_IOERR_READ:         zVal = "SQLITE_IOERR_READ";         break;
          147  +    case SQLITE_IOERR_SHORT_READ:   zVal = "SQLITE_IOERR_SHORT_READ";   break;
          148  +    case SQLITE_IOERR_WRITE:        zVal = "SQLITE_IOERR_WRITE";        break;
          149  +    case SQLITE_IOERR_FSYNC:        zVal = "SQLITE_IOERR_FSYNC";        break;
          150  +    case SQLITE_IOERR_DIR_FSYNC:    zVal = "SQLITE_IOERR_DIR_FSYNC";    break;
          151  +    case SQLITE_IOERR_TRUNCATE:     zVal = "SQLITE_IOERR_TRUNCATE";     break;
          152  +    case SQLITE_IOERR_FSTAT:        zVal = "SQLITE_IOERR_FSTAT";        break;
          153  +    case SQLITE_IOERR_UNLOCK:       zVal = "SQLITE_IOERR_UNLOCK";       break;
          154  +    case SQLITE_IOERR_RDLOCK:       zVal = "SQLITE_IOERR_RDLOCK";       break;
          155  +    case SQLITE_IOERR_DELETE:       zVal = "SQLITE_IOERR_DELETE";       break;
          156  +    case SQLITE_IOERR_BLOCKED:      zVal = "SQLITE_IOERR_BLOCKED";      break;
          157  +    case SQLITE_IOERR_NOMEM:        zVal = "SQLITE_IOERR_NOMEM";        break;
          158  +    case SQLITE_IOERR_ACCESS:       zVal = "SQLITE_IOERR_ACCESS";       break;
          159  +    case SQLITE_IOERR_CHECKRESERVEDLOCK:
          160  +                               zVal = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
          161  +    case SQLITE_IOERR_LOCK:         zVal = "SQLITE_IOERR_LOCK";         break;
          162  +    case SQLITE_IOERR_CLOSE:        zVal = "SQLITE_IOERR_CLOSE";        break;
          163  +    case SQLITE_IOERR_DIR_CLOSE:    zVal = "SQLITE_IOERR_DIR_CLOSE";    break;
          164  +    case SQLITE_IOERR_SHMOPEN:      zVal = "SQLITE_IOERR_SHMOPEN";      break;
          165  +    case SQLITE_IOERR_SHMSIZE:      zVal = "SQLITE_IOERR_SHMSIZE";      break;
          166  +    case SQLITE_IOERR_SHMLOCK:      zVal = "SQLITE_IOERR_SHMLOCK";      break;
          167  +    case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break;
          168  +    case SQLITE_BUSY_RECOVERY:      zVal = "SQLITE_BUSY_RECOVERY";      break;
          169  +    case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break;
          170  +    default: {
          171  +       sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
          172  +       zVal = zBuf;
          173  +       break;
          174  +    }
          175  +  }
          176  +  vfstrace_printf(pInfo, zFormat, zVal);
          177  +}
          178  +
          179  +/*
          180  +** Append to a buffer.
          181  +*/
          182  +static void strappend(char *z, int *pI, const char *zAppend){
          183  +  int i = *pI;
          184  +  while( zAppend[0] ){ z[i++] = *(zAppend++); }
          185  +  z[i] = 0;
          186  +  *pI = i;
          187  +}
          188  +
          189  +/*
          190  +** Close an vfstrace-file.
          191  +*/
          192  +static int vfstraceClose(sqlite3_file *pFile){
          193  +  vfstrace_file *p = (vfstrace_file *)pFile;
          194  +  vfstrace_info *pInfo = p->pInfo;
          195  +  int rc;
          196  +  vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName);
          197  +  rc = p->pReal->pMethods->xClose(p->pReal);
          198  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          199  +  if( rc==SQLITE_OK ){
          200  +    sqlite3_free((void*)p->base.pMethods);
          201  +    p->base.pMethods = 0;
          202  +  }
          203  +  return rc;
          204  +}
          205  +
          206  +/*
          207  +** Read data from an vfstrace-file.
          208  +*/
          209  +static int vfstraceRead(
          210  +  sqlite3_file *pFile, 
          211  +  void *zBuf, 
          212  +  int iAmt, 
          213  +  sqlite_int64 iOfst
          214  +){
          215  +  vfstrace_file *p = (vfstrace_file *)pFile;
          216  +  vfstrace_info *pInfo = p->pInfo;
          217  +  int rc;
          218  +  vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)",
          219  +                  pInfo->zVfsName, p->zFName, iAmt, iOfst);
          220  +  rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
          221  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          222  +  return rc;
          223  +}
          224  +
          225  +/*
          226  +** Write data to an vfstrace-file.
          227  +*/
          228  +static int vfstraceWrite(
          229  +  sqlite3_file *pFile, 
          230  +  const void *zBuf, 
          231  +  int iAmt, 
          232  +  sqlite_int64 iOfst
          233  +){
          234  +  vfstrace_file *p = (vfstrace_file *)pFile;
          235  +  vfstrace_info *pInfo = p->pInfo;
          236  +  int rc;
          237  +  vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)",
          238  +                  pInfo->zVfsName, p->zFName, iAmt, iOfst);
          239  +  rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
          240  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          241  +  return rc;
          242  +}
          243  +
          244  +/*
          245  +** Truncate an vfstrace-file.
          246  +*/
          247  +static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){
          248  +  vfstrace_file *p = (vfstrace_file *)pFile;
          249  +  vfstrace_info *pInfo = p->pInfo;
          250  +  int rc;
          251  +  vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName,
          252  +                  size);
          253  +  rc = p->pReal->pMethods->xTruncate(p->pReal, size);
          254  +  vfstrace_printf(pInfo, " -> %d\n", rc);
          255  +  return rc;
          256  +}
          257  +
          258  +/*
          259  +** Sync an vfstrace-file.
          260  +*/
          261  +static int vfstraceSync(sqlite3_file *pFile, int flags){
          262  +  vfstrace_file *p = (vfstrace_file *)pFile;
          263  +  vfstrace_info *pInfo = p->pInfo;
          264  +  int rc;
          265  +  int i;
          266  +  char zBuf[100];
          267  +  memcpy(zBuf, "|0", 3);
          268  +  i = 0;
          269  +  if( flags & SQLITE_SYNC_FULL )        strappend(zBuf, &i, "|FULL");
          270  +  else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL");
          271  +  if( flags & SQLITE_SYNC_DATAONLY )    strappend(zBuf, &i, "|DATAONLY");
          272  +  if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
          273  +    sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
          274  +  }
          275  +  vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
          276  +                  &zBuf[1]);
          277  +  rc = p->pReal->pMethods->xSync(p->pReal, flags);
          278  +  vfstrace_printf(pInfo, " -> %d\n", rc);
          279  +  return rc;
          280  +}
          281  +
          282  +/*
          283  +** Return the current file-size of an vfstrace-file.
          284  +*/
          285  +static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
          286  +  vfstrace_file *p = (vfstrace_file *)pFile;
          287  +  vfstrace_info *pInfo = p->pInfo;
          288  +  int rc;
          289  +  vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName);
          290  +  rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
          291  +  vfstrace_print_errcode(pInfo, " -> %s,", rc);
          292  +  vfstrace_printf(pInfo, " size=%lld\n", *pSize);
          293  +  return rc;
          294  +}
          295  +
          296  +/*
          297  +** Return the name of a lock.
          298  +*/
          299  +static const char *lockName(int eLock){
          300  +  const char *azLockNames[] = {
          301  +     "NONE", "SHARED", "RESERVED", "PENDING", "EXCLUSIVE"
          302  +  };
          303  +  if( eLock<0 || eLock>=sizeof(azLockNames)/sizeof(azLockNames[0]) ){
          304  +    return "???";
          305  +  }else{
          306  +    return azLockNames[eLock];
          307  +  }
          308  +}
          309  +
          310  +/*
          311  +** Lock an vfstrace-file.
          312  +*/
          313  +static int vfstraceLock(sqlite3_file *pFile, int eLock){
          314  +  vfstrace_file *p = (vfstrace_file *)pFile;
          315  +  vfstrace_info *pInfo = p->pInfo;
          316  +  int rc;
          317  +  vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName,
          318  +                  lockName(eLock));
          319  +  rc = p->pReal->pMethods->xLock(p->pReal, eLock);
          320  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          321  +  return rc;
          322  +}
          323  +
          324  +/*
          325  +** Unlock an vfstrace-file.
          326  +*/
          327  +static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
          328  +  vfstrace_file *p = (vfstrace_file *)pFile;
          329  +  vfstrace_info *pInfo = p->pInfo;
          330  +  int rc;
          331  +  vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
          332  +                  lockName(eLock));
          333  +  rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
          334  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          335  +  return rc;
          336  +}
          337  +
          338  +/*
          339  +** Check if another file-handle holds a RESERVED lock on an vfstrace-file.
          340  +*/
          341  +static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){
          342  +  vfstrace_file *p = (vfstrace_file *)pFile;
          343  +  vfstrace_info *pInfo = p->pInfo;
          344  +  int rc;
          345  +  vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)", 
          346  +                  pInfo->zVfsName, p->zFName);
          347  +  rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
          348  +  vfstrace_print_errcode(pInfo, " -> %s", rc);
          349  +  vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
          350  +  return rc;
          351  +}
          352  +
          353  +/*
          354  +** File control method. For custom operations on an vfstrace-file.
          355  +*/
          356  +static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
          357  +  vfstrace_file *p = (vfstrace_file *)pFile;
          358  +  vfstrace_info *pInfo = p->pInfo;
          359  +  int rc;
          360  +  char zBuf[100];
          361  +  char *zOp;
          362  +  switch( op ){
          363  +    case SQLITE_FCNTL_LOCKSTATE:    zOp = "LOCKSTATE";          break;
          364  +    case SQLITE_GET_LOCKPROXYFILE:  zOp = "GET_LOCKPROXYFILE";  break;
          365  +    case SQLITE_SET_LOCKPROXYFILE:  zOp = "SET_LOCKPROXYFILE";  break;
          366  +    case SQLITE_LAST_ERRNO:         zOp = "LAST_ERRNO";         break;
          367  +    case SQLITE_FCNTL_SIZE_HINT: {
          368  +      sqlite3_snprintf(sizeof(zBuf), zBuf, "SIZE_HINT,%lld",
          369  +                       *(sqlite3_int64*)pArg);
          370  +      zOp = zBuf;
          371  +      break;
          372  +    }
          373  +    case SQLITE_FCNTL_CHUNK_SIZE: {
          374  +      sqlite3_snprintf(sizeof(zBuf), zBuf, "CHUNK_SIZE,%d", *(int*)pArg);
          375  +      zOp = zBuf;
          376  +      break;
          377  +    }
          378  +    case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER";       break;
          379  +    case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED";       break;
          380  +    case 0xca093fa0:                zOp = "DB_UNCHANGED";       break;
          381  +    default: {
          382  +      sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op);
          383  +      zOp = zBuf;
          384  +      break;
          385  +    }
          386  +  }
          387  +  vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)",
          388  +                  pInfo->zVfsName, p->zFName, zOp);
          389  +  rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
          390  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          391  +  return rc;
          392  +}
          393  +
          394  +/*
          395  +** Return the sector-size in bytes for an vfstrace-file.
          396  +*/
          397  +static int vfstraceSectorSize(sqlite3_file *pFile){
          398  +  vfstrace_file *p = (vfstrace_file *)pFile;
          399  +  vfstrace_info *pInfo = p->pInfo;
          400  +  int rc;
          401  +  vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName);
          402  +  rc = p->pReal->pMethods->xSectorSize(p->pReal);
          403  +  vfstrace_printf(pInfo, " -> %d\n", rc);
          404  +  return rc;
          405  +}
          406  +
          407  +/*
          408  +** Return the device characteristic flags supported by an vfstrace-file.
          409  +*/
          410  +static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
          411  +  vfstrace_file *p = (vfstrace_file *)pFile;
          412  +  vfstrace_info *pInfo = p->pInfo;
          413  +  int rc;
          414  +  vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)",
          415  +                  pInfo->zVfsName, p->zFName);
          416  +  rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
          417  +  vfstrace_printf(pInfo, " -> 0x%08x\n", rc);
          418  +  return rc;
          419  +}
          420  +
          421  +/*
          422  +** Shared-memory operations.
          423  +*/
          424  +static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
          425  +  vfstrace_file *p = (vfstrace_file *)pFile;
          426  +  vfstrace_info *pInfo = p->pInfo;
          427  +  int rc;
          428  +  char zLck[100];
          429  +  int i = 0;
          430  +  memcpy(zLck, "|0", 3);
          431  +  if( flags & SQLITE_SHM_UNLOCK )    strappend(zLck, &i, "|UNLOCK");
          432  +  if( flags & SQLITE_SHM_LOCK )      strappend(zLck, &i, "|LOCK");
          433  +  if( flags & SQLITE_SHM_SHARED )    strappend(zLck, &i, "|SHARED");
          434  +  if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE");
          435  +  if( flags & ~(0xf) ){
          436  +     sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
          437  +  }
          438  +  vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
          439  +                  pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
          440  +  rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
          441  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          442  +  return rc;
          443  +}
          444  +static int vfstraceShmMap(
          445  +  sqlite3_file *pFile, 
          446  +  int iRegion, 
          447  +  int szRegion, 
          448  +  int isWrite, 
          449  +  void volatile **pp
          450  +){
          451  +  vfstrace_file *p = (vfstrace_file *)pFile;
          452  +  vfstrace_info *pInfo = p->pInfo;
          453  +  int rc;
          454  +  vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)",
          455  +                  pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite);
          456  +  rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
          457  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          458  +  return rc;
          459  +}
          460  +static void vfstraceShmBarrier(sqlite3_file *pFile){
          461  +  vfstrace_file *p = (vfstrace_file *)pFile;
          462  +  vfstrace_info *pInfo = p->pInfo;
          463  +  vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName);
          464  +  p->pReal->pMethods->xShmBarrier(p->pReal);
          465  +}
          466  +static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){
          467  +  vfstrace_file *p = (vfstrace_file *)pFile;
          468  +  vfstrace_info *pInfo = p->pInfo;
          469  +  int rc;
          470  +  vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
          471  +                  pInfo->zVfsName, p->zFName, delFlag);
          472  +  rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
          473  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          474  +  return rc;
          475  +}
          476  +
          477  +
          478  +
          479  +/*
          480  +** Open an vfstrace file handle.
          481  +*/
          482  +static int vfstraceOpen(
          483  +  sqlite3_vfs *pVfs,
          484  +  const char *zName,
          485  +  sqlite3_file *pFile,
          486  +  int flags,
          487  +  int *pOutFlags
          488  +){
          489  +  int rc;
          490  +  vfstrace_file *p = (vfstrace_file *)pFile;
          491  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          492  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          493  +  p->pInfo = pInfo;
          494  +  p->zFName = zName ? fileTail(zName) : "<temp>";
          495  +  p->pReal = (sqlite3_file *)&p[1];
          496  +  rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags);
          497  +  vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
          498  +                  pInfo->zVfsName, p->zFName, flags);
          499  +  if( p->pReal->pMethods ){
          500  +    sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) );
          501  +    const sqlite3_io_methods *pSub = p->pReal->pMethods;
          502  +    memset(pNew, 0, sizeof(*pNew));
          503  +    pNew->iVersion = pSub->iVersion;
          504  +    pNew->xClose = vfstraceClose;
          505  +    pNew->xRead = vfstraceRead;
          506  +    pNew->xWrite = vfstraceWrite;
          507  +    pNew->xTruncate = vfstraceTruncate;
          508  +    pNew->xSync = vfstraceSync;
          509  +    pNew->xFileSize = vfstraceFileSize;
          510  +    pNew->xLock = vfstraceLock;
          511  +    pNew->xUnlock = vfstraceUnlock;
          512  +    pNew->xCheckReservedLock = vfstraceCheckReservedLock;
          513  +    pNew->xFileControl = vfstraceFileControl;
          514  +    pNew->xSectorSize = vfstraceSectorSize;
          515  +    pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics;
          516  +    if( pNew->iVersion>=2 ){
          517  +      pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0;
          518  +      pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0;
          519  +      pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0;
          520  +      pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0;
          521  +    }
          522  +    pFile->pMethods = pNew;
          523  +  }
          524  +  vfstrace_print_errcode(pInfo, " -> %s", rc);
          525  +  if( pOutFlags ){
          526  +    vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags);
          527  +  }else{
          528  +    vfstrace_printf(pInfo, "\n");
          529  +  }
          530  +  return rc;
          531  +}
          532  +
          533  +/*
          534  +** Delete the file located at zPath. If the dirSync argument is true,
          535  +** ensure the file-system modifications are synced to disk before
          536  +** returning.
          537  +*/
          538  +static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
          539  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          540  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          541  +  int rc;
          542  +  vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
          543  +                  pInfo->zVfsName, zPath, dirSync);
          544  +  rc = pRoot->xDelete(pRoot, zPath, dirSync);
          545  +  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          546  +  return rc;
          547  +}
          548  +
          549  +/*
          550  +** Test for access permissions. Return true if the requested permission
          551  +** is available, or false otherwise.
          552  +*/
          553  +static int vfstraceAccess(
          554  +  sqlite3_vfs *pVfs, 
          555  +  const char *zPath, 
          556  +  int flags, 
          557  +  int *pResOut
          558  +){
          559  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          560  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          561  +  int rc;
          562  +  vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
          563  +                  pInfo->zVfsName, zPath, flags);
          564  +  rc = pRoot->xAccess(pRoot, zPath, flags, pResOut);
          565  +  vfstrace_print_errcode(pInfo, " -> %s", rc);
          566  +  vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
          567  +  return rc;
          568  +}
          569  +
          570  +/*
          571  +** Populate buffer zOut with the full canonical pathname corresponding
          572  +** to the pathname in zPath. zOut is guaranteed to point to a buffer
          573  +** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
          574  +*/
          575  +static int vfstraceFullPathname(
          576  +  sqlite3_vfs *pVfs, 
          577  +  const char *zPath, 
          578  +  int nOut, 
          579  +  char *zOut
          580  +){
          581  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          582  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          583  +  int rc;
          584  +  vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")",
          585  +                  pInfo->zVfsName, zPath);
          586  +  rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut);
          587  +  vfstrace_print_errcode(pInfo, " -> %s", rc);
          588  +  vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut);
          589  +  return rc;
          590  +}
          591  +
          592  +/*
          593  +** Open the dynamic library located at zPath and return a handle.
          594  +*/
          595  +static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
          596  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          597  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          598  +  vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath);
          599  +  return pRoot->xDlOpen(pRoot, zPath);
          600  +}
          601  +
          602  +/*
          603  +** Populate the buffer zErrMsg (size nByte bytes) with a human readable
          604  +** utf-8 string describing the most recent error encountered associated 
          605  +** with dynamic libraries.
          606  +*/
          607  +static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
          608  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          609  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          610  +  vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte);
          611  +  pRoot->xDlError(pRoot, nByte, zErrMsg);
          612  +  vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg);
          613  +}
          614  +
          615  +/*
          616  +** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
          617  +*/
          618  +static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){
          619  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          620  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          621  +  vfstrace_printf(pInfo, "%s.xDlSym(\"%s\")\n", pInfo->zVfsName, zSym);
          622  +  return pRoot->xDlSym(pRoot, p, zSym);
          623  +}
          624  +
          625  +/*
          626  +** Close the dynamic library handle pHandle.
          627  +*/
          628  +static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
          629  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          630  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          631  +  vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
          632  +  pRoot->xDlClose(pRoot, pHandle);
          633  +}
          634  +
          635  +/*
          636  +** Populate the buffer pointed to by zBufOut with nByte bytes of 
          637  +** random data.
          638  +*/
          639  +static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
          640  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          641  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          642  +  vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte);
          643  +  return pRoot->xRandomness(pRoot, nByte, zBufOut);
          644  +}
          645  +
          646  +/*
          647  +** Sleep for nMicro microseconds. Return the number of microseconds 
          648  +** actually slept.
          649  +*/
          650  +static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
          651  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          652  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          653  +  return pRoot->xSleep(pRoot, nMicro);
          654  +}
          655  +
          656  +/*
          657  +** Return the current time as a Julian Day number in *pTimeOut.
          658  +*/
          659  +static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
          660  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          661  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          662  +  return pRoot->xCurrentTime(pRoot, pTimeOut);
          663  +}
          664  +static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
          665  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          666  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          667  +  return pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
          668  +}
          669  +
          670  +/*
          671  +** Return th3 emost recent error code and message
          672  +*/
          673  +static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){
          674  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          675  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          676  +  return pRoot->xGetLastError(pRoot, iErr, zErr);
          677  +}
          678  +
          679  +/*
          680  +** Override system calls.
          681  +*/
          682  +static int vfstraceSetSystemCall(
          683  +  sqlite3_vfs *pVfs,
          684  +  const char *zName,
          685  +  void *pFunc
          686  +){
          687  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          688  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          689  +  return pRoot->xSetSystemCall(pRoot, zName, pFunc);
          690  +}
          691  +static void *vfstraceGetSystemCall(sqlite3_vfs *pVfs, const char *zName){
          692  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          693  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          694  +  return pRoot->xGetSystemCall(pRoot, zName);
          695  +}
          696  +static const char *vfstraceNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
          697  +  vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
          698  +  sqlite3_vfs *pRoot = pInfo->pRootVfs;
          699  +  return pRoot->xNextSystemCall(pRoot, zName);
          700  +}
          701  +
          702  +
          703  +/*
          704  +** Clients invoke this routine to construct a new trace-vfs shim.
          705  +**
          706  +** Return SQLITE_OK on success.  
          707  +**
          708  +** SQLITE_NOMEM is returned in the case of a memory allocation error.
          709  +** SQLITE_NOTFOUND is returned if zOldVfsName does not exist.
          710  +*/
          711  +int vfstrace_register(
          712  +   const char *zTraceName,           /* Name of the newly constructed VFS */
          713  +   const char *zOldVfsName,          /* Name of the underlying VFS */
          714  +   int (*xOut)(const char*,void*),   /* Output routine.  ex: fputs */
          715  +   void *pOutArg,                    /* 2nd argument to xOut.  ex: stderr */
          716  +   int makeDefault                   /* True to make the new VFS the default */
          717  +){
          718  +  sqlite3_vfs *pNew;
          719  +  sqlite3_vfs *pRoot;
          720  +  vfstrace_info *pInfo;
          721  +  int nName;
          722  +  int nByte;
          723  +
          724  +  pRoot = sqlite3_vfs_find(zOldVfsName);
          725  +  if( pRoot==0 ) return SQLITE_NOTFOUND;
          726  +  nName = strlen(zTraceName);
          727  +  nByte = sizeof(*pNew) + sizeof(*pInfo) + nName + 1;
          728  +  pNew = sqlite3_malloc( nByte );
          729  +  if( pNew==0 ) return SQLITE_NOMEM;
          730  +  memset(pNew, 0, nByte);
          731  +  pInfo = (vfstrace_info*)&pNew[1];
          732  +  pNew->iVersion = pRoot->iVersion;
          733  +  pNew->szOsFile = pRoot->szOsFile + sizeof(vfstrace_file);
          734  +  pNew->mxPathname = pRoot->mxPathname;
          735  +  pNew->zName = (char*)&pInfo[1];
          736  +  memcpy((char*)&pInfo[1], zTraceName, nName+1);
          737  +  pNew->pAppData = pInfo;
          738  +  pNew->xOpen = vfstraceOpen;
          739  +  pNew->xDelete = vfstraceDelete;
          740  +  pNew->xAccess = vfstraceAccess;
          741  +  pNew->xFullPathname = vfstraceFullPathname;
          742  +  pNew->xDlOpen = pRoot->xDlOpen==0 ? 0 : vfstraceDlOpen;
          743  +  pNew->xDlError = pRoot->xDlError==0 ? 0 : vfstraceDlError;
          744  +  pNew->xDlSym = pRoot->xDlSym==0 ? 0 : vfstraceDlSym;
          745  +  pNew->xDlClose = pRoot->xDlClose==0 ? 0 : vfstraceDlClose;
          746  +  pNew->xRandomness = vfstraceRandomness;
          747  +  pNew->xSleep = vfstraceSleep;
          748  +  pNew->xCurrentTime = vfstraceCurrentTime;
          749  +  pNew->xGetLastError = pRoot->xGetLastError==0 ? 0 : vfstraceGetLastError;
          750  +  if( pNew->iVersion>=2 ){
          751  +    pNew->xCurrentTimeInt64 = pRoot->xCurrentTimeInt64==0 ? 0 :
          752  +                                   vfstraceCurrentTimeInt64;
          753  +    if( pNew->iVersion>=3 ){
          754  +      pNew->xSetSystemCall = pRoot->xSetSystemCall==0 ? 0 : 
          755  +                                   vfstraceSetSystemCall;
          756  +      pNew->xGetSystemCall = pRoot->xGetSystemCall==0 ? 0 : 
          757  +                                   vfstraceGetSystemCall;
          758  +      pNew->xNextSystemCall = pRoot->xNextSystemCall==0 ? 0 : 
          759  +                                   vfstraceNextSystemCall;
          760  +    }
          761  +  }
          762  +  pInfo->pRootVfs = pRoot;
          763  +  pInfo->xOut = xOut;
          764  +  pInfo->pOutArg = pOutArg;
          765  +  pInfo->zVfsName = pNew->zName;
          766  +  pInfo->pTraceVfs = pNew;
          767  +  vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n",
          768  +       pInfo->zVfsName, pRoot->zName);
          769  +  return sqlite3_vfs_register(pNew, makeDefault);
          770  +}

Changes to src/trigger.c.

   258    258     Trigger *pTrig = pParse->pNewTrigger;   /* Trigger being finished */
   259    259     char *zName;                            /* Name of trigger */
   260    260     sqlite3 *db = pParse->db;               /* The database */
   261    261     DbFixer sFix;                           /* Fixer object */
   262    262     int iDb;                                /* Database containing the trigger */
   263    263     Token nameToken;                        /* Trigger name for error reporting */
   264    264   
   265         -  pTrig = pParse->pNewTrigger;
   266    265     pParse->pNewTrigger = 0;
   267    266     if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
   268    267     zName = pTrig->zName;
   269    268     iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
   270    269     pTrig->step_list = pStepList;
   271    270     while( pStepList ){
   272    271       pStepList->pTrig = pTrig;

Changes to src/update.c.

   124    124     /* Register Allocations */
   125    125     int regRowCount = 0;   /* A count of rows changed */
   126    126     int regOldRowid;       /* The old rowid */
   127    127     int regNewRowid;       /* The new rowid */
   128    128     int regNew;
   129    129     int regOld = 0;
   130    130     int regRowSet = 0;     /* Rowset of rows to be updated */
   131         -  int regRec;            /* Register used for new table record to insert */
   132    131   
   133    132     memset(&sContext, 0, sizeof(sContext));
   134    133     db = pParse->db;
   135    134     if( pParse->nErr || db->mallocFailed ){
   136    135       goto update_cleanup;
   137    136     }
   138    137     assert( pTabList->nSrc==1 );
................................................................................
   282    281       pParse->nMem += pTab->nCol;
   283    282     }
   284    283     if( chngRowid || pTrigger || hasFK ){
   285    284       regNewRowid = ++pParse->nMem;
   286    285     }
   287    286     regNew = pParse->nMem + 1;
   288    287     pParse->nMem += pTab->nCol;
   289         -  regRec = ++pParse->nMem;
   290    288   
   291    289     /* Start the view context. */
   292    290     if( isView ){
   293    291       sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
   294    292     }
   295    293   
   296    294     /* If we are trying to update a view, realize that view into
................................................................................
   392    390     ** with the required old.* column data.  */
   393    391     if( hasFK || pTrigger ){
   394    392       u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0);
   395    393       oldmask |= sqlite3TriggerColmask(pParse, 
   396    394           pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
   397    395       );
   398    396       for(i=0; i<pTab->nCol; i++){
   399         -      if( aXRef[i]<0 || oldmask==0xffffffff || (oldmask & (1<<i)) ){
          397  +      if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
   400    398           sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOld+i);
   401    399         }else{
   402    400           sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
   403    401         }
   404    402       }
   405    403       if( chngRowid==0 ){
   406    404         sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);

Changes to src/util.c.

   437    437       testcase( c==(+1) );
   438    438     }
   439    439     return c;
   440    440   }
   441    441   
   442    442   
   443    443   /*
   444         -** Convert zNum to a 64-bit signed integer and write
   445         -** the value of the integer into *pNum.
   446         -** If zNum is exactly 9223372036854665808, return 2.
   447         -** This is a special case as the context will determine
   448         -** if it is too big (used as a negative).
   449         -** If zNum is not an integer or is an integer that 
   450         -** is too large to be expressed with 64 bits,
   451         -** then return 1.  Otherwise return 0.
          444  +** Convert zNum to a 64-bit signed integer.
          445  +**
          446  +** If the zNum value is representable as a 64-bit twos-complement 
          447  +** integer, then write that value into *pNum and return 0.
          448  +**
          449  +** If zNum is exactly 9223372036854665808, return 2.  This special
          450  +** case is broken out because while 9223372036854665808 cannot be a 
          451  +** signed 64-bit integer, its negative -9223372036854665808 can be.
          452  +**
          453  +** If zNum is too big for a 64-bit integer and is not
          454  +** 9223372036854665808 then return 1.
   452    455   **
   453    456   ** length is the number of bytes in the string (bytes, not characters).
   454    457   ** The string is not necessarily zero-terminated.  The encoding is
   455    458   ** given by enc.
   456    459   */
   457    460   int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
   458    461     int incr = (enc==SQLITE_UTF8?1:2);
   459         -  i64 v = 0;
          462  +  u64 u = 0;
   460    463     int neg = 0; /* assume positive */
   461    464     int i;
   462    465     int c = 0;
   463    466     const char *zStart;
   464    467     const char *zEnd = zNum + length;
   465    468     if( enc==SQLITE_UTF16BE ) zNum++;
   466    469     while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
   467         -  if( zNum>=zEnd ) goto do_atoi_calc;
   468         -  if( *zNum=='-' ){
   469         -    neg = 1;
   470         -    zNum+=incr;
   471         -  }else if( *zNum=='+' ){
   472         -    zNum+=incr;
          470  +  if( zNum<zEnd ){
          471  +    if( *zNum=='-' ){
          472  +      neg = 1;
          473  +      zNum+=incr;
          474  +    }else if( *zNum=='+' ){
          475  +      zNum+=incr;
          476  +    }
   473    477     }
   474         -do_atoi_calc:
   475    478     zStart = zNum;
   476    479     while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
   477    480     for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
   478         -    v = v*10 + c - '0';
          481  +    u = u*10 + c - '0';
   479    482     }
   480         -  *pNum = neg ? -v : v;
          483  +  if( u>LARGEST_INT64 ){
          484  +    *pNum = SMALLEST_INT64;
          485  +  }else if( neg ){
          486  +    *pNum = -(i64)u;
          487  +  }else{
          488  +    *pNum = (i64)u;
          489  +  }
   481    490     testcase( i==18 );
   482    491     testcase( i==19 );
   483    492     testcase( i==20 );
   484    493     if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
   485    494       /* zNum is empty or contains non-numeric text or is longer
   486    495       ** than 19 digits (thus guaranteeing that it is too large) */
   487    496       return 1;
   488    497     }else if( i<19*incr ){
   489    498       /* Less than 19 digits, so we know that it fits in 64 bits */
          499  +    assert( u<=LARGEST_INT64 );
   490    500       return 0;
   491    501     }else{
   492         -    /* 19-digit numbers must be no larger than 9223372036854775807 if positive
   493         -    ** or 9223372036854775808 if negative.  Note that 9223372036854665808
   494         -    ** is 2^63. Return 1 if to large */
   495         -    c=compare2pow63(zNum, incr);
   496         -    if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */
   497         -    return c<neg ? 0 : 1;
          502  +    /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
          503  +    c = compare2pow63(zNum, incr);
          504  +    if( c<0 ){
          505  +      /* zNum is less than 9223372036854775808 so it fits */
          506  +      assert( u<=LARGEST_INT64 );
          507  +      return 0;
          508  +    }else if( c>0 ){
          509  +      /* zNum is greater than 9223372036854775808 so it overflows */
          510  +      return 1;
          511  +    }else{
          512  +      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
          513  +      ** special case 2 overflow if positive */
          514  +      assert( u-1==LARGEST_INT64 );
          515  +      assert( (*pNum)==SMALLEST_INT64 );
          516  +      return neg ? 0 : 2;
          517  +    }
   498    518     }
   499    519   }
   500    520   
   501    521   /*
   502    522   ** If zNum represents an integer that will fit in 32-bits, then set
   503    523   ** *pValue to that integer and return true.  Otherwise return false.
   504    524   **
................................................................................
  1056   1076       testcase( sqlite3GlobalConfig.xLog!=0 );
  1057   1077       logBadConnection("invalid");
  1058   1078       return 0;
  1059   1079     }else{
  1060   1080       return 1;
  1061   1081     }
  1062   1082   }
         1083  +
         1084  +/*
         1085  +** Attempt to add, substract, or multiply the 64-bit signed value iB against
         1086  +** the other 64-bit signed integer at *pA and store the result in *pA.
         1087  +** Return 0 on success.  Or if the operation would have resulted in an
         1088  +** overflow, leave *pA unchanged and return 1.
         1089  +*/
         1090  +int sqlite3AddInt64(i64 *pA, i64 iB){
         1091  +  i64 iA = *pA;
         1092  +  testcase( iA==0 ); testcase( iA==1 );
         1093  +  testcase( iB==-1 ); testcase( iB==0 );
         1094  +  if( iB>=0 ){
         1095  +    testcase( iA>0 && LARGEST_INT64 - iA == iB );
         1096  +    testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
         1097  +    if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
         1098  +    *pA += iB;
         1099  +  }else{
         1100  +    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
         1101  +    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
         1102  +    if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
         1103  +    *pA += iB;
         1104  +  }
         1105  +  return 0; 
         1106  +}
         1107  +int sqlite3SubInt64(i64 *pA, i64 iB){
         1108  +  testcase( iB==SMALLEST_INT64+1 );
         1109  +  if( iB==SMALLEST_INT64 ){
         1110  +    testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
         1111  +    if( (*pA)>=0 ) return 1;
         1112  +    *pA -= iB;
         1113  +    return 0;
         1114  +  }else{
         1115  +    return sqlite3AddInt64(pA, -iB);
         1116  +  }
         1117  +}
         1118  +#define TWOPOWER32 (((i64)1)<<32)
         1119  +#define TWOPOWER31 (((i64)1)<<31)
         1120  +int sqlite3MulInt64(i64 *pA, i64 iB){
         1121  +  i64 iA = *pA;
         1122  +  i64 iA1, iA0, iB1, iB0, r;
         1123  +
         1124  +  iA1 = iA/TWOPOWER32;
         1125  +  iA0 = iA % TWOPOWER32;
         1126  +  iB1 = iB/TWOPOWER32;
         1127  +  iB0 = iB % TWOPOWER32;
         1128  +  if( iA1*iB1 != 0 ) return 1;
         1129  +  assert( iA1*iB0==0 || iA0*iB1==0 );
         1130  +  r = iA1*iB0 + iA0*iB1;
         1131  +  testcase( r==(-TWOPOWER31)-1 );
         1132  +  testcase( r==(-TWOPOWER31) );
         1133  +  testcase( r==TWOPOWER31 );
         1134  +  testcase( r==TWOPOWER31-1 );
         1135  +  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
         1136  +  r *= TWOPOWER32;
         1137  +  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
         1138  +  *pA = r;
         1139  +  return 0;
         1140  +}
         1141  +
         1142  +/*
         1143  +** Compute the absolute value of a 32-bit signed integer, of possible.  Or 
         1144  +** if the integer has a value of -2147483648, return +2147483647
         1145  +*/
         1146  +int sqlite3AbsInt32(int x){
         1147  +  if( x>=0 ) return x;
         1148  +  if( x==(int)0x80000000 ) return 0x7fffffff;
         1149  +  return -x;
         1150  +}

Changes to src/vdbe.c.

  1242   1242     pOut = &aMem[pOp->p3];
  1243   1243     flags = pIn1->flags | pIn2->flags;
  1244   1244     if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
  1245   1245     if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
  1246   1246       iA = pIn1->u.i;
  1247   1247       iB = pIn2->u.i;
  1248   1248       switch( pOp->opcode ){
  1249         -      case OP_Add:         iB += iA;       break;
  1250         -      case OP_Subtract:    iB -= iA;       break;
  1251         -      case OP_Multiply:    iB *= iA;       break;
         1249  +      case OP_Add:       if( sqlite3AddInt64(&iB,iA) ) goto fp_math;  break;
         1250  +      case OP_Subtract:  if( sqlite3SubInt64(&iB,iA) ) goto fp_math;  break;
         1251  +      case OP_Multiply:  if( sqlite3MulInt64(&iB,iA) ) goto fp_math;  break;
  1252   1252         case OP_Divide: {
  1253   1253           if( iA==0 ) goto arithmetic_result_is_null;
  1254         -        /* Dividing the largest possible negative 64-bit integer (1<<63) by 
  1255         -        ** -1 returns an integer too large to store in a 64-bit data-type. On
  1256         -        ** some architectures, the value overflows to (1<<63). On others,
  1257         -        ** a SIGFPE is issued. The following statement normalizes this
  1258         -        ** behavior so that all architectures behave as if integer 
  1259         -        ** overflow occurred.
  1260         -        */
  1261         -        if( iA==-1 && iB==SMALLEST_INT64 ) iA = 1;
         1254  +        if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
  1262   1255           iB /= iA;
  1263   1256           break;
  1264   1257         }
  1265   1258         default: {
  1266   1259           if( iA==0 ) goto arithmetic_result_is_null;
  1267   1260           if( iA==-1 ) iA = 1;
  1268   1261           iB %= iA;
  1269   1262           break;
  1270   1263         }
  1271   1264       }
  1272   1265       pOut->u.i = iB;
  1273   1266       MemSetTypeFlag(pOut, MEM_Int);
  1274   1267     }else{
         1268  +fp_math:
  1275   1269       rA = sqlite3VdbeRealValue(pIn1);
  1276   1270       rB = sqlite3VdbeRealValue(pIn2);
  1277   1271       switch( pOp->opcode ){
  1278   1272         case OP_Add:         rB += rA;       break;
  1279   1273         case OP_Subtract:    rB -= rA;       break;
  1280   1274         case OP_Multiply:    rB *= rA;       break;
  1281   1275         case OP_Divide: {
................................................................................
  1462   1456   ** Store the result in register P3.
  1463   1457   ** If either input is NULL, the result is NULL.
  1464   1458   */
  1465   1459   case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */
  1466   1460   case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */
  1467   1461   case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */
  1468   1462   case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
  1469         -  i64 a;
  1470         -  i64 b;
         1463  +  i64 iA;
         1464  +  u64 uA;
         1465  +  i64 iB;
         1466  +  u8 op;
  1471   1467   
  1472   1468     pIn1 = &aMem[pOp->p1];
  1473   1469     pIn2 = &aMem[pOp->p2];
  1474   1470     pOut = &aMem[pOp->p3];
  1475   1471     if( (pIn1->flags | pIn2->flags) & MEM_Null ){
  1476   1472       sqlite3VdbeMemSetNull(pOut);
  1477   1473       break;
  1478   1474     }
  1479         -  a = sqlite3VdbeIntValue(pIn2);
  1480         -  b = sqlite3VdbeIntValue(pIn1);
  1481         -  switch( pOp->opcode ){
  1482         -    case OP_BitAnd:      a &= b;     break;
  1483         -    case OP_BitOr:       a |= b;     break;
  1484         -    case OP_ShiftLeft:   a <<= b;    break;
  1485         -    default:  assert( pOp->opcode==OP_ShiftRight );
  1486         -                         a >>= b;    break;
         1475  +  iA = sqlite3VdbeIntValue(pIn2);
         1476  +  iB = sqlite3VdbeIntValue(pIn1);
         1477  +  op = pOp->opcode;
         1478  +  if( op==OP_BitAnd ){
         1479  +    iA &= iB;
         1480  +  }else if( op==OP_BitOr ){
         1481  +    iA |= iB;
         1482  +  }else if( iB!=0 ){
         1483  +    assert( op==OP_ShiftRight || op==OP_ShiftLeft );
         1484  +
         1485  +    /* If shifting by a negative amount, shift in the other direction */
         1486  +    if( iB<0 ){
         1487  +      assert( OP_ShiftRight==OP_ShiftLeft+1 );
         1488  +      op = 2*OP_ShiftLeft + 1 - op;
         1489  +      iB = iB>(-64) ? -iB : 64;
         1490  +    }
         1491  +
         1492  +    if( iB>=64 ){
         1493  +      iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1;
         1494  +    }else{
         1495  +      memcpy(&uA, &iA, sizeof(uA));
         1496  +      if( op==OP_ShiftLeft ){
         1497  +        uA <<= iB;
         1498  +      }else{
         1499  +        uA >>= iB;
         1500  +        /* Sign-extend on a right shift of a negative number */
         1501  +        if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB);
         1502  +      }
         1503  +      memcpy(&iA, &uA, sizeof(iA));
         1504  +    }
  1487   1505     }
  1488         -  pOut->u.i = a;
         1506  +  pOut->u.i = iA;
  1489   1507     MemSetTypeFlag(pOut, MEM_Int);
  1490   1508     break;
  1491   1509   }
  1492   1510   
  1493   1511   /* Opcode: AddImm  P1 P2 * * *
  1494   1512   ** 
  1495   1513   ** Add the constant P2 to the value in register P1.
................................................................................
  2407   2425     ** Each type field is a varint representing the serial type of the 
  2408   2426     ** corresponding data element (see sqlite3VdbeSerialType()). The
  2409   2427     ** hdr-size field is also a varint which is the offset from the beginning
  2410   2428     ** of the record to data0.
  2411   2429     */
  2412   2430     nData = 0;         /* Number of bytes of data space */
  2413   2431     nHdr = 0;          /* Number of bytes of header space */
  2414         -  nByte = 0;         /* Data space required for this record */
  2415   2432     nZero = 0;         /* Number of zero bytes at the end of the record */
  2416   2433     nField = pOp->p1;
  2417   2434     zAffinity = pOp->p4.z;
  2418   2435     assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
  2419   2436     pData0 = &aMem[nField];
  2420   2437     nField = pOp->p2;
  2421   2438     pLast = &pData0[nField-1];
................................................................................
  3681   3698       **
  3682   3699       ** The second algorithm is to select a rowid at random and see if
  3683   3700       ** it already exists in the table.  If it does not exist, we have
  3684   3701       ** succeeded.  If the random rowid does exist, we select a new one
  3685   3702       ** and try again, up to 100 times.
  3686   3703       */
  3687   3704       assert( pC->isTable );
  3688         -    cnt = 0;
  3689   3705   
  3690   3706   #ifdef SQLITE_32BIT_ROWID
  3691   3707   #   define MAX_ROWID 0x7fffffff
  3692   3708   #else
  3693   3709       /* Some compilers complain about constants of the form 0x7fffffffffffffff.
  3694   3710       ** Others complain about 0x7ffffffffffffffffLL.  The following macro seems
  3695   3711       ** to provide the constant while making all compilers happy.

Changes to src/vdbeapi.c.

   698    698   ** Check to see if column iCol of the given statement is valid.  If
   699    699   ** it is, return a pointer to the Mem for the value of that column.
   700    700   ** If iCol is not valid, return a pointer to a Mem which has a value
   701    701   ** of NULL.
   702    702   */
   703    703   static Mem *columnMem(sqlite3_stmt *pStmt, int i){
   704    704     Vdbe *pVm;
   705         -  int vals;
   706    705     Mem *pOut;
   707    706   
   708    707     pVm = (Vdbe *)pStmt;
   709    708     if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
   710    709       sqlite3_mutex_enter(pVm->db->mutex);
   711         -    vals = sqlite3_data_count(pStmt);
   712    710       pOut = &pVm->pResultSet[i];
   713    711     }else{
   714    712       /* If the value passed as the second argument is out of range, return
   715    713       ** a pointer to a static Mem object that contains the value SQL NULL. 
   716    714       */
   717    715       if( pVm && ALWAYS(pVm->db) ){
   718    716         sqlite3_mutex_enter(pVm->db->mutex);

Changes to src/vdbeaux.c.

    71     71   
    72     72   /*
    73     73   ** Swap all content between two VDBE structures.
    74     74   */
    75     75   void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
    76     76     Vdbe tmp, *pTmp;
    77     77     char *zTmp;
           78  +  assert( pA->db==pB->db );
    78     79     tmp = *pA;
    79     80     *pA = *pB;
    80     81     *pB = tmp;
    81     82     pTmp = pA->pNext;
    82     83     pA->pNext = pB->pNext;
    83     84     pB->pNext = pTmp;
    84     85     pTmp = pA->pPrev;
................................................................................
  1513   1514   ** Also release any dynamic memory held by the VM in the Vdbe.aMem memory 
  1514   1515   ** cell array. This is necessary as the memory cell array may contain
  1515   1516   ** pointers to VdbeFrame objects, which may in turn contain pointers to
  1516   1517   ** open cursors.
  1517   1518   */
  1518   1519   static void closeAllCursors(Vdbe *p){
  1519   1520     if( p->pFrame ){
  1520         -    VdbeFrame *pFrame = p->pFrame;
         1521  +    VdbeFrame *pFrame;
  1521   1522       for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
  1522   1523       sqlite3VdbeFrameRestore(pFrame);
  1523   1524     }
  1524   1525     p->pFrame = 0;
  1525   1526     p->nFrame = 0;
  1526   1527   
  1527   1528     if( p->apCsr ){
................................................................................
  2493   2494       /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
  2494   2495   #   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
  2495   2496       i64 i = pMem->u.i;
  2496   2497       u64 u;
  2497   2498       if( file_format>=4 && (i&1)==i ){
  2498   2499         return 8+(u32)i;
  2499   2500       }
  2500         -    u = i<0 ? -i : i;
         2501  +    if( i<0 ){
         2502  +      if( i<(-MAX_6BYTE) ) return 6;
         2503  +      /* Previous test prevents:  u = -(-9223372036854775808) */
         2504  +      u = -i;
         2505  +    }else{
         2506  +      u = i;
         2507  +    }
  2501   2508       if( u<=127 ) return 1;
  2502   2509       if( u<=32767 ) return 2;
  2503   2510       if( u<=8388607 ) return 3;
  2504   2511       if( u<=2147483647 ) return 4;
  2505   2512       if( u<=MAX_6BYTE ) return 5;
  2506   2513       return 6;
  2507   2514     }

Changes to src/vdbemem.c.

   363    363     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   364    364     flags = pMem->flags;
   365    365     if( flags & MEM_Int ){
   366    366       return pMem->u.i;
   367    367     }else if( flags & MEM_Real ){
   368    368       return doubleToInt64(pMem->r);
   369    369     }else if( flags & (MEM_Str|MEM_Blob) ){
   370         -    i64 value;
          370  +    i64 value = 0;
   371    371       assert( pMem->z || pMem->n==0 );
   372    372       testcase( pMem->z==0 );
   373    373       sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
   374    374       return value;
   375    375     }else{
   376    376       return 0;
   377    377     }
................................................................................
  1073   1073       if( enc!=SQLITE_UTF8 ){
  1074   1074         sqlite3VdbeChangeEncoding(pVal, enc);
  1075   1075       }
  1076   1076     }else if( op==TK_UMINUS ) {
  1077   1077       /* This branch happens for multiple negative signs.  Ex: -(-5) */
  1078   1078       if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
  1079   1079         sqlite3VdbeMemNumerify(pVal);
  1080         -      pVal->u.i = -1 * pVal->u.i;
  1081         -      /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */
  1082         -      pVal->r = (double)-1 * pVal->r;
         1080  +      if( pVal->u.i==SMALLEST_INT64 ){
         1081  +        pVal->flags &= MEM_Int;
         1082  +        pVal->flags |= MEM_Real;
         1083  +        pVal->r = (double)LARGEST_INT64;
         1084  +      }else{
         1085  +        pVal->u.i = -pVal->u.i;
         1086  +      }
         1087  +      pVal->r = -pVal->r;
  1083   1088         sqlite3ValueApplyAffinity(pVal, affinity, enc);
  1084   1089       }
  1085   1090     }else if( op==TK_NULL ){
  1086   1091       pVal = sqlite3ValueNew(db);
  1087   1092       if( pVal==0 ) goto no_mem;
  1088   1093     }
  1089   1094   #ifndef SQLITE_OMIT_BLOB_LITERAL

Changes to src/wal.c.

  1645   1645     /* Allocate the iterator */
  1646   1646     rc = walIteratorInit(pWal, &pIter);
  1647   1647     if( rc!=SQLITE_OK ){
  1648   1648       return rc;
  1649   1649     }
  1650   1650     assert( pIter );
  1651   1651   
  1652         -  mxPage = pWal->hdr.nPage;
  1653   1652     if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
  1654   1653   
  1655   1654     /* Compute in mxSafeFrame the index of the last frame of the WAL that is
  1656   1655     ** safe to write into the database.  Frames beyond mxSafeFrame might
  1657   1656     ** overwrite database pages that are in use by active readers and thus
  1658   1657     ** cannot be backfilled from the WAL.
  1659   1658     */

Changes to src/where.c.

  2516   2516   
  2517   2517   #ifdef SQLITE_ENABLE_STAT2
  2518   2518   /*
  2519   2519   ** Estimate the number of rows that will be returned based on
  2520   2520   ** an equality constraint x=VALUE and where that VALUE occurs in
  2521   2521   ** the histogram data.  This only works when x is the left-most
  2522   2522   ** column of an index and sqlite_stat2 histogram data is available
  2523         -** for that index.
         2523  +** for that index.  When pExpr==NULL that means the constraint is
         2524  +** "x IS NULL" instead of "x=VALUE".
  2524   2525   **
  2525   2526   ** Write the estimated row count into *pnRow and return SQLITE_OK. 
  2526   2527   ** If unable to make an estimate, leave *pnRow unchanged and return
  2527   2528   ** non-zero.
  2528   2529   **
  2529   2530   ** This routine can fail if it is unable to load a collating sequence
  2530   2531   ** required for string comparison, or if unable to allocate memory
................................................................................
  2541   2542     int iLower, iUpper;       /* Range of histogram regions containing pRhs */
  2542   2543     u8 aff;                   /* Column affinity */
  2543   2544     int rc;                   /* Subfunction return code */
  2544   2545     double nRowEst;           /* New estimate of the number of rows */
  2545   2546   
  2546   2547     assert( p->aSample!=0 );
  2547   2548     aff = p->pTable->aCol[p->aiColumn[0]].affinity;
  2548         -  rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
  2549         -  if( rc ) goto whereEqualScanEst_cancel;
         2549  +  if( pExpr ){
         2550  +    rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
         2551  +    if( rc ) goto whereEqualScanEst_cancel;
         2552  +  }else{
         2553  +    pRhs = sqlite3ValueNew(pParse->db);
         2554  +  }
  2550   2555     if( pRhs==0 ) return SQLITE_NOTFOUND;
  2551   2556     rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower);
  2552   2557     if( rc ) goto whereEqualScanEst_cancel;
  2553   2558     rc = whereRangeRegion(pParse, p, pRhs, 1, &iUpper);
  2554   2559     if( rc ) goto whereEqualScanEst_cancel;
  2555   2560     WHERETRACE(("equality scan regions: %d..%d\n", iLower, iUpper));
  2556   2561     if( iLower>=iUpper ){
................................................................................
  2931   2936   #ifdef SQLITE_ENABLE_STAT2
  2932   2937       /* If the constraint is of the form x=VALUE and histogram
  2933   2938       ** data is available for column x, then it might be possible
  2934   2939       ** to get a better estimate on the number of rows based on
  2935   2940       ** VALUE and how common that value is according to the histogram.
  2936   2941       */
  2937   2942       if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 ){
  2938         -      if( pFirstTerm->eOperator==WO_EQ ){
         2943  +      if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
         2944  +        testcase( pFirstTerm->eOperator==WO_EQ );
         2945  +        testcase( pFirstTerm->pOperator==WO_ISNULL );
  2939   2946           whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
  2940   2947         }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){
  2941   2948           whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow);
  2942   2949         }
  2943   2950       }
  2944   2951   #endif /* SQLITE_ENABLE_STAT2 */
  2945   2952   
................................................................................
  3997   4004         sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
  3998   4005         sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg);  /* Deferred seek */
  3999   4006       }
  4000   4007   
  4001   4008       /* Record the instruction used to terminate the loop. Disable 
  4002   4009       ** WHERE clause terms made redundant by the index range scan.
  4003   4010       */
  4004         -    pLevel->op = bRev ? OP_Prev : OP_Next;
         4011  +    if( pLevel->plan.wsFlags & WHERE_UNIQUE ){
         4012  +      pLevel->op = OP_Noop;
         4013  +    }else if( bRev ){
         4014  +      pLevel->op = OP_Prev;
         4015  +    }else{
         4016  +      pLevel->op = OP_Next;
         4017  +    }
  4005   4018       pLevel->p1 = iIdxCur;
  4006   4019     }else
  4007   4020   
  4008   4021   #ifndef SQLITE_OMIT_OR_OPTIMIZATION
  4009   4022     if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
  4010   4023       /* Case 4:  Two or more separately indexed terms connected by OR
  4011   4024       **
................................................................................
  4043   4056       **
  4044   4057       **          Return     2                # Jump back to the Gosub
  4045   4058       **
  4046   4059       **       B: <after the loop>
  4047   4060       **
  4048   4061       */
  4049   4062       WhereClause *pOrWc;    /* The OR-clause broken out into subterms */
  4050         -    WhereTerm *pFinal;     /* Final subterm within the OR-clause. */
  4051   4063       SrcList *pOrTab;       /* Shortened table list or OR-clause generation */
  4052   4064   
  4053   4065       int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
  4054   4066       int regRowset = 0;                        /* Register for RowSet object */
  4055   4067       int regRowid = 0;                         /* Register holding rowid */
  4056   4068       int iLoopBody = sqlite3VdbeMakeLabel(v);  /* Start of loop body */
  4057   4069       int iRetInit;                             /* Address of regReturn init */
................................................................................
  4059   4071       int ii;
  4060   4072      
  4061   4073       pTerm = pLevel->plan.u.pTerm;
  4062   4074       assert( pTerm!=0 );
  4063   4075       assert( pTerm->eOperator==WO_OR );
  4064   4076       assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
  4065   4077       pOrWc = &pTerm->u.pOrInfo->wc;
  4066         -    pFinal = &pOrWc->a[pOrWc->nTerm-1];
  4067   4078       pLevel->op = OP_Return;
  4068   4079       pLevel->p1 = regReturn;
  4069   4080   
  4070   4081       /* Set up a new SrcList ni pOrTab containing the table being scanned
  4071   4082       ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
  4072   4083       ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
  4073   4084       */
................................................................................
  4168   4179     /* Insert code to test every subexpression that can be completely
  4169   4180     ** computed using the current set of tables.
  4170   4181     **
  4171   4182     ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
  4172   4183     ** the use of indices become tests that are evaluated against each row of
  4173   4184     ** the relevant input tables.
  4174   4185     */
  4175         -  k = 0;
  4176   4186     for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
  4177   4187       Expr *pE;
  4178   4188       testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
  4179   4189       testcase( pTerm->wtFlags & TERM_CODED );
  4180   4190       if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
  4181   4191       if( (pTerm->prereqAll & notReady)!=0 ){
  4182   4192         testcase( pWInfo->untestedTerms==0
................................................................................
  4186   4196       }
  4187   4197       pE = pTerm->pExpr;
  4188   4198       assert( pE!=0 );
  4189   4199       if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
  4190   4200         continue;
  4191   4201       }
  4192   4202       sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
  4193         -    k = 1;
  4194   4203       pTerm->wtFlags |= TERM_CODED;
  4195   4204     }
  4196   4205   
  4197   4206     /* For a LEFT OUTER JOIN, generate code that will record the fact that
  4198   4207     ** at least one row of the right table has matched the left table.  
  4199   4208     */
  4200   4209     if( pLevel->iLeftJoin ){
................................................................................
  4494   4503     **   pWInfo->a[].iIdxCur   The VDBE cursor for the index
  4495   4504     **   pWInfo->a[].pTerm     When wsFlags==WO_OR, the OR-clause term
  4496   4505     **
  4497   4506     ** This loop also figures out the nesting order of tables in the FROM
  4498   4507     ** clause.
  4499   4508     */
  4500   4509     notReady = ~(Bitmask)0;
  4501         -  pTabItem = pTabList->a;
  4502         -  pLevel = pWInfo->a;
  4503   4510     andFlags = ~0;
  4504   4511     WHERETRACE(("*** Optimizer Start ***\n"));
  4505   4512     for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
  4506   4513       WhereCost bestPlan;         /* Most efficient plan seen so far */
  4507   4514       Index *pIdx;                /* Index for FROM table at pTabItem */
  4508   4515       int j;                      /* For looping over FROM tables */
  4509   4516       int bestJ = -1;             /* The value of j */
................................................................................
  4606   4613           }
  4607   4614   
  4608   4615           /* Conditions under which this table becomes the best so far:
  4609   4616           **
  4610   4617           **   (1) The table must not depend on other tables that have not
  4611   4618           **       yet run.
  4612   4619           **
  4613         -        **   (2) A full-table-scan plan cannot supercede another plan unless
  4614         -        **       it is an "optimal" plan as defined above.
         4620  +        **   (2) A full-table-scan plan cannot supercede indexed plan unless
         4621  +        **       the full-table-scan is an "optimal" plan as defined above.
  4615   4622           **
  4616   4623           **   (3) All tables have an INDEXED BY clause or this table lacks an
  4617   4624           **       INDEXED BY clause or this table uses the specific
  4618   4625           **       index specified by its INDEXED BY clause.  This rule ensures
  4619   4626           **       that a best-so-far is always selected even if an impossible
  4620   4627           **       combination of INDEXED BY clauses are given.  The error
  4621   4628           **       will be detected and relayed back to the application later.
................................................................................
  4623   4630           **       An indexable full-table-scan from reaching rule (3).
  4624   4631           **
  4625   4632           **   (4) The plan cost must be lower than prior plans or else the
  4626   4633           **       cost must be the same and the number of rows must be lower.
  4627   4634           */
  4628   4635           if( (sCost.used&notReady)==0                       /* (1) */
  4629   4636               && (bestJ<0 || (notIndexed&m)!=0               /* (2) */
         4637  +                || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
  4630   4638                   || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
  4631   4639               && (nUnconstrained==0 || pTabItem->pIndex==0   /* (3) */
  4632   4640                   || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
  4633   4641               && (bestJ<0 || sCost.rCost<bestPlan.rCost      /* (4) */
  4634   4642                   || (sCost.rCost<=bestPlan.rCost 
  4635   4643                    && sCost.plan.nRow<bestPlan.plan.nRow))
  4636   4644           ){

Changes to test/analyze5.test.

   160    160     215  {z IN (-1,3)}         t1z  150
   161    161     216  {z=-1 OR z=3}         t1z  150
   162    162   
   163    163     300  {y=0}                 {}   100
   164    164     301  {y=1}                 t1y   50
   165    165     302  {y=0.1}               t1y   50
   166    166   
          167  +  400  {x IS NULL}           t1x  400
          168  +
          169  +} {
          170  +  # Verify that the expected index is used with the expected row count
          171  +  do_test analyze5-1.${testid}a {
          172  +    set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
          173  +    set idx {}
          174  +    regexp {INDEX (t1.) } $x all idx
          175  +    regexp {~([0-9]+) rows} $x all nrow
          176  +    list $idx $nrow
          177  +  } [list $index $rows]
          178  +
          179  +  # Verify that the same result is achieved regardless of whether or not
          180  +  # the index is used
          181  +  do_test analyze5-1.${testid}b {
          182  +    set w2 [string map {y +y z +z} $where]
          183  +    set a1 [db eval "SELECT rowid FROM t1 NOT INDEXED WHERE $w2\
          184  +                     ORDER BY +rowid"]
          185  +    set a2 [db eval "SELECT rowid FROM t1 WHERE $where ORDER BY +rowid"]
          186  +    if {$a1==$a2} {
          187  +      set res ok
          188  +    } else {
          189  +      set res "a1=\[$a1\] a2=\[$a2\]"
          190  +    }
          191  +    set res
          192  +  } {ok}
          193  +}
          194  +
          195  +# Increase the number of NULLs in column x
          196  +#
          197  +db eval {
          198  +   UPDATE t1 SET x=NULL;
          199  +   UPDATE t1 SET x=rowid
          200  +    WHERE rowid IN (SELECT rowid FROM t1 ORDER BY random() LIMIT 5);
          201  +   ANALYZE;
          202  +}
          203  +
          204  +# Verify that range queries generate the correct row count estimates
          205  +#
          206  +foreach {testid where index rows} {
          207  +  500  {x IS NULL AND u='charlie'}         t1u  20
          208  +  501  {x=1 AND u='charlie'}               t1x   5
          209  +  502  {x IS NULL}                          {} 100
          210  +  503  {x=1}                               t1x  50
          211  +  504  {x IS NOT NULL}                     t1x  25
          212  +
   167    213   } {
   168    214     # Verify that the expected index is used with the expected row count
   169    215     do_test analyze5-1.${testid}a {
   170    216       set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
   171    217       set idx {}
   172    218       regexp {INDEX (t1.) } $x all idx
   173    219       regexp {~([0-9]+) rows} $x all nrow
................................................................................
   185    231         set res ok
   186    232       } else {
   187    233         set res "a1=\[$a1\] a2=\[$a2\]"
   188    234       }
   189    235       set res
   190    236     } {ok}
   191    237   }
   192         -
   193    238   
   194    239   finish_test

Added test/analyze6.test.

            1  +# 2011 March 3
            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  +#
           12  +# This file implements tests for SQLite library.  The focus of the tests
           13  +# in this file a corner-case query planner optimization involving the
           14  +# join order of two tables of different sizes.
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +
           20  +ifcapable !stat2 {
           21  +  finish_test
           22  +  return
           23  +}
           24  +
           25  +set testprefix analyze6
           26  +
           27  +proc eqp {sql {db db}} {
           28  +  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
           29  +}
           30  +
           31  +do_test analyze6-1.0 {
           32  +  db eval {
           33  +    CREATE TABLE cat(x INT);
           34  +    CREATE UNIQUE INDEX catx ON cat(x);
           35  +    /* Give cat 16 unique integers */
           36  +    INSERT INTO cat VALUES(1);
           37  +    INSERT INTO cat VALUES(2);
           38  +    INSERT INTO cat SELECT x+2 FROM cat;
           39  +    INSERT INTO cat SELECT x+4 FROM cat;
           40  +    INSERT INTO cat SELECT x+8 FROM cat;
           41  +
           42  +    CREATE TABLE ev(y INT);
           43  +    CREATE INDEX evy ON ev(y);
           44  +    /* ev will hold 32 copies of 16 integers found in cat */
           45  +    INSERT INTO ev SELECT x FROM cat;
           46  +    INSERT INTO ev SELECT x FROM cat;
           47  +    INSERT INTO ev SELECT y FROM ev;
           48  +    INSERT INTO ev SELECT y FROM ev;
           49  +    INSERT INTO ev SELECT y FROM ev;
           50  +    INSERT INTO ev SELECT y FROM ev;
           51  +    ANALYZE;
           52  +    SELECT count(*) FROM cat;
           53  +    SELECT count(*) FROM ev;
           54  +  }
           55  +} {16 512}
           56  +
           57  +# The lowest cost plan is to scan CAT and for each integer there, do a single
           58  +# lookup of the first corresponding entry in EV then read off the equal values
           59  +# in EV.  (Prior to the 2011-03-04 enhancement to where.c, this query would
           60  +# have used EV for the outer loop instead of CAT - which was about 3x slower.)
           61  +#
           62  +do_test analyze6-1.1 {
           63  +  eqp {SELECT count(*) FROM ev, cat WHERE x=y}
           64  +} {0 0 1 {SCAN TABLE cat (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
           65  +
           66  +# The same plan is chosen regardless of the order of the tables in the
           67  +# FROM clause.
           68  +#
           69  +do_test analyze6-1.2 {
           70  +  eqp {SELECT count(*) FROM cat, ev WHERE x=y}
           71  +} {0 0 0 {SCAN TABLE cat (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
           72  +
           73  +
           74  +finish_test

Changes to test/expr.test.

    78     78   test_expr expr-1.41 {i1=1, i2=2} {-(i2+i1)} {-3}
    79     79   test_expr expr-1.42 {i1=1, i2=2} {i1|i2} {3}
    80     80   test_expr expr-1.42b {i1=1, i2=2} {4|2} {6}
    81     81   test_expr expr-1.43 {i1=1, i2=2} {i1&i2} {0}
    82     82   test_expr expr-1.43b {i1=1, i2=2} {4&5} {4}
    83     83   test_expr expr-1.44 {i1=1} {~i1} {-2}
    84     84   test_expr expr-1.44b {i1=NULL} {~i1} {{}}
    85         -test_expr expr-1.45 {i1=1, i2=3} {i1<<i2} {8}
    86         -test_expr expr-1.46 {i1=32, i2=3} {i1>>i2} {4}
           85  +test_expr expr-1.45a {i1=1, i2=3} {i1<<i2} {8}
           86  +test_expr expr-1.45b {i1=1, i2=-3} {i1>>i2} {8}
           87  +test_expr expr-1.45c {i1=1, i2=0} {i1<<i2} {1}
           88  +test_expr expr-1.45d {i1=1, i2=62} {i1<<i2} {4611686018427387904}
           89  +test_expr expr-1.45e {i1=1, i2=63} {i1<<i2} {-9223372036854775808}
           90  +test_expr expr-1.45f {i1=1, i2=64} {i1<<i2} {0}
           91  +test_expr expr-1.45g {i1=32, i2=-9223372036854775808} {i1>>i2} {0}
           92  +test_expr expr-1.46a {i1=32, i2=3} {i1>>i2} {4}
           93  +test_expr expr-1.46b {i1=32, i2=6} {i1>>i2} {0}
           94  +test_expr expr-1.46c {i1=-32, i2=3} {i1>>i2} {-4}
           95  +test_expr expr-1.46d {i1=-32, i2=100} {i1>>i2} {-1}
           96  +test_expr expr-1.46e {i1=32, i2=-3} {i1>>i2} {256}
    87     97   test_expr expr-1.47 {i1=9999999999, i2=8888888888} {i1<i2} 0
    88     98   test_expr expr-1.48 {i1=9999999999, i2=8888888888} {i1=i2} 0
    89     99   test_expr expr-1.49 {i1=9999999999, i2=8888888888} {i1>i2} 1
    90    100   test_expr expr-1.50 {i1=99999999999, i2=99999999998} {i1<i2} 0
    91    101   test_expr expr-1.51 {i1=99999999999, i2=99999999998} {i1=i2} 0
    92    102   test_expr expr-1.52 {i1=99999999999, i2=99999999998} {i1>i2} 1
    93    103   test_expr expr-1.53 {i1=099999999999, i2=99999999999} {i1<i2} 0
................................................................................
   150    160   ifcapable floatingpoint {
   151    161     test_expr expr-1.103 {i1=0} {(-2147483648.0 % -1)} 0.0
   152    162     test_expr expr-1.104 {i1=0} {(-9223372036854775808.0 % -1)} 0.0
   153    163     test_expr expr-1.105 {i1=0} {(-9223372036854775808.0 / -1)>1} 1
   154    164   }
   155    165   
   156    166   if {[working_64bit_int]} {
   157         -  test_expr expr-1.106 {i1=0} {(1<<63)/-1} -9223372036854775808
          167  +  test_expr expr-1.106 {i1=0} {-9223372036854775808/-1} 9.22337203685478e+18
   158    168   }
   159    169   
   160         -test_expr expr-1.107 {i1=0} {(1<<63)%-1} 0
          170  +test_expr expr-1.107 {i1=0} {-9223372036854775808%-1} 0
   161    171   test_expr expr-1.108 {i1=0} {1%0} {{}}
   162    172   test_expr expr-1.109 {i1=0} {1/0} {{}}
   163    173   
   164    174   if {[working_64bit_int]} {
   165    175     test_expr expr-1.110 {i1=0} {-9223372036854775807/-1} 9223372036854775807
   166    176   }
   167    177   
................................................................................
   185    195     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
   186    196   test_expr expr-1.124 {i1=NULL, i2=NULL} \
   187    197     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
   188    198   test_expr expr-1.125 {i1=6, i2=NULL} \
   189    199     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
   190    200   test_expr expr-1.126 {i1=8, i2=8} \
   191    201     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
          202  +
          203  +ifcapable floatingpoint {if {[working_64bit_int]} {
          204  +  test_expr expr-1.200\
          205  +      {i1=9223372036854775806, i2=1} {i1+i2}      9223372036854775807
          206  +  test_expr expr-1.201\
          207  +      {i1=9223372036854775806, i2=2} {i1+i2}      9.22337203685478e+18
          208  +  test_expr expr-1.202\
          209  +      {i1=9223372036854775806, i2=100000} {i1+i2} 9.22337203685488e+18
          210  +  test_expr expr-1.203\
          211  +      {i1=9223372036854775807, i2=0} {i1+i2}      9223372036854775807
          212  +  test_expr expr-1.204\
          213  +      {i1=9223372036854775807, i2=1} {i1+i2}      9.22337203685478e+18
          214  +  test_expr expr-1.205\
          215  +      {i2=9223372036854775806, i1=1} {i1+i2}      9223372036854775807
          216  +  test_expr expr-1.206\
          217  +      {i2=9223372036854775806, i1=2} {i1+i2}      9.22337203685478e+18
          218  +  test_expr expr-1.207\
          219  +      {i2=9223372036854775806, i1=100000} {i1+i2} 9.22337203685488e+18
          220  +  test_expr expr-1.208\
          221  +      {i2=9223372036854775807, i1=0} {i1+i2}      9223372036854775807
          222  +  test_expr expr-1.209\
          223  +      {i2=9223372036854775807, i1=1} {i1+i2}      9.22337203685478e+18
          224  +  test_expr expr-1.210\
          225  +      {i1=-9223372036854775807, i2=-1} {i1+i2}    -9223372036854775808
          226  +  test_expr expr-1.211\
          227  +      {i1=-9223372036854775807, i2=-2} {i1+i2}    -9.22337203685478e+18
          228  +  test_expr expr-1.212\
          229  +      {i1=-9223372036854775807, i2=-100000} {i1+i2} -9.22337203685488e+18
          230  +  test_expr expr-1.213\
          231  +      {i1=-9223372036854775808, i2=0} {i1+i2}     -9223372036854775808
          232  +  test_expr expr-1.214\
          233  +      {i1=-9223372036854775808, i2=-1} {i1+i2}    -9.22337203685478e+18
          234  +  test_expr expr-1.215\
          235  +      {i2=-9223372036854775807, i1=-1} {i1+i2}    -9223372036854775808
          236  +  test_expr expr-1.216\
          237  +      {i2=-9223372036854775807, i1=-2} {i1+i2}    -9.22337203685478e+18
          238  +  test_expr expr-1.217\
          239  +      {i2=-9223372036854775807, i1=-100000} {i1+i2} -9.22337203685488e+18
          240  +  test_expr expr-1.218\
          241  +      {i2=-9223372036854775808, i1=0} {i1+i2}     -9223372036854775808
          242  +  test_expr expr-1.219\
          243  +      {i2=-9223372036854775808, i1=-1} {i1+i2}    -9.22337203685478e+18
          244  +  test_expr expr-1.220\
          245  +      {i1=9223372036854775806, i2=-1} {i1-i2}     9223372036854775807
          246  +  test_expr expr-1.221\
          247  +      {i1=9223372036854775806, i2=-2} {i1-i2}      9.22337203685478e+18
          248  +  test_expr expr-1.222\
          249  +      {i1=9223372036854775806, i2=-100000} {i1-i2} 9.22337203685488e+18
          250  +  test_expr expr-1.223\
          251  +      {i1=9223372036854775807, i2=0} {i1-i2}      9223372036854775807
          252  +  test_expr expr-1.224\
          253  +      {i1=9223372036854775807, i2=-1} {i1-i2}      9.22337203685478e+18
          254  +  test_expr expr-1.225\
          255  +      {i2=-9223372036854775806, i1=1} {i1-i2}      9223372036854775807
          256  +  test_expr expr-1.226\
          257  +      {i2=-9223372036854775806, i1=2} {i1-i2}      9.22337203685478e+18
          258  +  test_expr expr-1.227\
          259  +      {i2=-9223372036854775806, i1=100000} {i1-i2} 9.22337203685488e+18
          260  +  test_expr expr-1.228\
          261  +      {i2=-9223372036854775807, i1=0} {i1-i2}      9223372036854775807
          262  +  test_expr expr-1.229\
          263  +      {i2=-9223372036854775807, i1=1} {i1-i2}      9.22337203685478e+18
          264  +  test_expr expr-1.230\
          265  +      {i1=-9223372036854775807, i2=1} {i1-i2}    -9223372036854775808
          266  +  test_expr expr-1.231\
          267  +      {i1=-9223372036854775807, i2=2} {i1-i2}    -9.22337203685478e+18
          268  +  test_expr expr-1.232\
          269  +      {i1=-9223372036854775807, i2=100000} {i1-i2} -9.22337203685488e+18
          270  +  test_expr expr-1.233\
          271  +      {i1=-9223372036854775808, i2=0} {i1-i2}     -9223372036854775808
          272  +  test_expr expr-1.234\
          273  +      {i1=-9223372036854775808, i2=1} {i1-i2}    -9.22337203685478e+18
          274  +  test_expr expr-1.235\
          275  +      {i2=9223372036854775807, i1=-1} {i1-i2}    -9223372036854775808
          276  +  test_expr expr-1.236\
          277  +      {i2=9223372036854775807, i1=-2} {i1-i2}    -9.22337203685478e+18
          278  +  test_expr expr-1.237\
          279  +      {i2=9223372036854775807, i1=-100000} {i1-i2} -9.22337203685488e+18
          280  +  test_expr expr-1.238\
          281  +      {i2=9223372036854775807, i1=0} {i1-i2}     -9223372036854775807
          282  +  test_expr expr-1.239\
          283  +      {i2=9223372036854775807, i1=-1} {i1-i2}    -9223372036854775808
          284  +
          285  +  test_expr expr-1.250\
          286  +      {i1=4294967296, i2=2147483648} {i1*i2}      9.22337203685478e+18
          287  +  test_expr expr-1.251\
          288  +      {i1=4294967296, i2=2147483647} {i1*i2}      9223372032559808512
          289  +  test_expr expr-1.252\
          290  +      {i1=-4294967296, i2=2147483648} {i1*i2}     -9223372036854775808
          291  +  test_expr expr-1.253\
          292  +      {i1=-4294967296, i2=2147483647} {i1*i2}     -9223372032559808512
          293  +  test_expr expr-1.254\
          294  +      {i1=4294967296, i2=-2147483648} {i1*i2}     -9223372036854775808
          295  +  test_expr expr-1.255\
          296  +      {i1=4294967296, i2=-2147483647} {i1*i2}     -9223372032559808512
          297  +  test_expr expr-1.256\
          298  +      {i1=-4294967296, i2=-2147483648} {i1*i2}    9.22337203685478e+18
          299  +  test_expr expr-1.257\
          300  +      {i1=-4294967296, i2=-2147483647} {i1*i2}    9223372032559808512
          301  +
          302  +}}
   192    303   
   193    304   ifcapable floatingpoint {
   194    305     test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
   195    306     test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11
   196    307     test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782
   197    308   }
   198    309   set tcl_precision 15

Changes to test/index.test.

   350    350       );
   351    351     }
   352    352     for {set i 1} {$i<=50} {incr i} {
   353    353       execsql "INSERT INTO t3 VALUES('x${i}x',$i,0.$i)"
   354    354     }
   355    355     set sqlite_search_count 0
   356    356     concat [execsql {SELECT c FROM t3 WHERE b==10}] $sqlite_search_count
   357         -} {0.1 3}
          357  +} {0.1 2}
   358    358   integrity_check index-11.2
   359    359   
   360    360   
   361    361   # Numeric strings should compare as if they were numbers.  So even if the
   362    362   # strings are not character-by-character the same, if they represent the
   363    363   # same number they should compare equal to one another.  Verify that this
   364    364   # is true in indices.

Added test/mem5.test.

            1  +# 2011 March 9
            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  +#
           12  +# This file contains tests of the mem5 allocation subsystem.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +
           18  +ifcapable !mem5 {
           19  +  finish_test
           20  +  return
           21  +}
           22  +
           23  +# The tests in this file configure the lookaside allocator after a 
           24  +# connection is opened. This will not work if there is any "presql"
           25  +# configured (SQL run within the [sqlite3] wrapper in tester.tcl).
           26  +if {[info exists ::G(perm:presql)]} {
           27  +  finish_test
           28  +  return
           29  +}
           30  +
           31  +do_test mem5-1.1 {
           32  +  catch {db close}
           33  +  sqlite3_shutdown
           34  +  sqlite3_config_heap 25000000 0
           35  +  sqlite3_config_lookaside 0 0
           36  +  sqlite3_initialize
           37  +} {SQLITE_OK}
           38  +
           39  +# try with min request size = 2^30
           40  +do_test mem5-1.2 {
           41  +  catch {db close}
           42  +  sqlite3_shutdown
           43  +  sqlite3_config_heap 1 1073741824
           44  +  sqlite3_config_lookaside 0 0
           45  +  sqlite3_initialize
           46  +} {SQLITE_NOMEM}
           47  +
           48  +# try with min request size = 2^30+1
           49  +# previously this was causing the memsys5Log() func to infinitely loop.
           50  +do_test mem5-1.3 {
           51  +  catch {db close}
           52  +  sqlite3_shutdown
           53  +  sqlite3_config_heap 1 1073741825
           54  +  sqlite3_config_lookaside 0 0
           55  +  sqlite3_initialize
           56  +} {SQLITE_NOMEM}
           57  +
           58  +do_test mem5-1.4 {
           59  +  catch {db close}
           60  +  sqlite3_shutdown
           61  +  sqlite3_config_heap 0 0
           62  +  sqlite3_config_lookaside 0 0
           63  +  sqlite3_initialize
           64  +} {SQLITE_OK}
           65  +
           66  +finish_test

Added test/omitunique.test.

            1  +# 2011 March 10
            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 file is testing the SQLITE_OMIT_UNIQUE_ENFORCEMENT
           13  +# compiler option.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +
           19  +set uniq_enforced 1
           20  +ifcapable !unique_enforcement {
           21  +  set uniq_enforced 0
           22  +}
           23  +
           24  +# table with UNIQUE keyword on column
           25  +do_test omitunique-1.1 {
           26  +  catchsql { CREATE TABLE t1(a TEXT UNIQUE); }
           27  +} {0 {}}
           28  +
           29  +# table with UNIQUE clause on column
           30  +do_test omitunique-1.2 {
           31  +  catchsql { CREATE TABLE t2(a TEXT, UNIQUE(a)); }
           32  +} {0 {}}
           33  +
           34  +# table with UNIQUE index on column
           35  +do_test omitunique-1.3 {
           36  +  catchsql {
           37  +    CREATE TABLE t3(a TEXT);
           38  +    CREATE UNIQUE INDEX t3a ON t3(a);
           39  +  }
           40  +} {0 {}}
           41  +
           42  +# table with regular index on column
           43  +do_test omitunique-1.4 {
           44  +  catchsql {
           45  +    CREATE TABLE t4(a TEXT);
           46  +    CREATE INDEX t4a ON t4(a);
           47  +  }
           48  +} {0 {}}
           49  +
           50  +# table with no index on column
           51  +do_test omitunique-1.5 {
           52  +  catchsql { CREATE TABLE t5(a TEXT); }
           53  +} {0 {}}
           54  +
           55  +# run our tests using several table/index forms
           56  +foreach {j tbl uniq cnt qp_est stat_enforce stat_omit } {
           57  +1 {t1} 1 1 1      {2 1} {9 9}
           58  +2 {t2} 1 1 1      {2 1} {9 9}
           59  +3 {t3} 1 1 1      {2 1} {9 9}
           60  +4 {t4} 0 9 10     {9 9} {9 9}
           61  +5 {t5} 0 9 100000 9     9
           62  +} {
           63  +
           64  +  do_test omitunique-2.0.$j.1 {
           65  +    catchsql [ subst {INSERT INTO $tbl (a) VALUES('abc'); }]
           66  +  } {0 {}}
           67  +  do_test omitunique-2.0.$j.2 {
           68  +    catchsql [ subst {INSERT INTO $tbl (a) VALUES('123'); }]
           69  +  } {0 {}}
           70  +
           71  +  # check various INSERT commands
           72  +  foreach {i cmd err} {
           73  +    1 {INSERT}             1   
           74  +    2 {INSERT OR IGNORE}   0 
           75  +    3 {INSERT OR REPLACE}  0
           76  +    4 {REPLACE}            0
           77  +    5 {INSERT OR FAIL}     1
           78  +    6 {INSERT OR ABORT}    1
           79  +    7 {INSERT OR ROLLBACK} 1
           80  +  } {
           81  +
           82  +    ifcapable explain {
           83  +      set x [execsql [ subst { EXPLAIN $cmd INTO $tbl (a) VALUES('abc'); }]]
           84  +      ifcapable unique_enforcement {
           85  +          do_test omitunique-2.1.$j.$i.1 {
           86  +            regexp { IsUnique } $x
           87  +          } $uniq
           88  +      }
           89  +      ifcapable !unique_enforcement {
           90  +          do_test omitunique-2.1.$j.$i.1 {
           91  +            regexp { IsUnique } $x
           92  +          } {0}
           93  +      }
           94  +    }
           95  +
           96  +    if { $uniq_enforced==0 || $uniq==0 || $err==0 } { 
           97  +      set msg {0 {}}
           98  +    } {
           99  +      set msg {1 {column a is not unique}}
          100  +    }
          101  +    do_test omitunique-2.1.$j.$i.3 {
          102  +      catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc'); }]
          103  +    } $msg
          104  +
          105  +  }
          106  +  # end foreach cmd
          107  +
          108  +  # check UPDATE command
          109  +  ifcapable explain {
          110  +    set x [execsql [ subst { EXPLAIN UPDATE $tbl SET a='abc'; }]]
          111  +    ifcapable unique_enforcement {
          112  +        do_test omitunique-2.2.$j.1 {
          113  +          regexp { IsUnique } $x
          114  +        } $uniq
          115  +    }
          116  +    ifcapable !unique_enforcement {
          117  +        do_test omitunique-2.2.$j.1 {
          118  +          regexp { IsUnique } $x
          119  +        } {0}
          120  +    }
          121  +  }
          122  +  if { $uniq_enforced==0 || $uniq==0 } { 
          123  +    set msg {0 {}}
          124  +  } {
          125  +    set msg {1 {column a is not unique}}
          126  +  }
          127  +  do_test omitunique-2.2.$j.3 {
          128  +    catchsql [ subst { UPDATE $tbl SET a='abc'; }]
          129  +  } $msg
          130  +
          131  +  # check record counts
          132  +  do_test omitunique-2.3.$j {
          133  +    execsql [ subst { SELECT count(*) FROM $tbl WHERE a='abc'; }]
          134  +  } $cnt
          135  +
          136  +  # make sure the query planner row estimate not affected because of omit enforcement
          137  +  ifcapable explain {
          138  +    do_test omitunique-2.4.$j {
          139  +      set x [ execsql [ subst { EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc'; }]]
          140  +      set y [ subst {~$qp_est row} ]
          141  +      regexp $y $x
          142  +    } {1}
          143  +  }
          144  +
          145  +  # make sure we omit extra OP_Next opcodes when the UNIQUE constraints 
          146  +  # mean there will only be a single pass through the code 
          147  +  ifcapable explain {
          148  +    set x [execsql [ subst { EXPLAIN SELECT * FROM $tbl WHERE a='abc'; }]]
          149  +    do_test omitunique-2.5.$j {
          150  +      if { [ regexp { Next } $x ] } { expr { 0 } } { expr { 1 } }
          151  +    } $uniq
          152  +  }
          153  +
          154  +  # make sure analyze index stats correct
          155  +  ifcapable analyze {
          156  +    if { $uniq_enforced==0 } { 
          157  +      set msg [ list $stat_omit ]
          158  +    } {
          159  +      set msg [ list $stat_enforce ]
          160  +    }
          161  +    do_test omitunique-2.6.$j {
          162  +      execsql [ subst { ANALYZE $tbl; } ]
          163  +      execsql [ subst { SELECT stat FROM sqlite_stat1 WHERE tbl='$tbl'; } ]
          164  +    } $msg
          165  +  }
          166  +
          167  +}
          168  +# end foreach tbl
          169  +
          170  +finish_test

Changes to test/oserror.test.

    52     52       for {set i 0} {$i < 2000} {incr i} { sqlite3 dbh_$i test.db -readonly 1 }
    53     53     } msg] $msg
    54     54   } {1 {unable to open database file}}
    55     55   do_test 1.1.2 {
    56     56     catch { for {set i 0} {$i < 2000} {incr i} { dbh_$i close } }
    57     57   } {1}
    58     58   
    59         -do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c: open.*test.db$}
           59  +do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*test.db\) - }
    60     60   
    61     61   
    62     62   # Test a failure in open() due to the path being a directory.
    63     63   #
    64     64   do_test 1.2.1 {
    65     65     file mkdir dir.db
    66     66     set ::log [list]
    67     67     list [catch { sqlite3 dbh dir.db } msg] $msg
    68     68   } {1 {unable to open database file}}
    69     69   
    70         -do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c: open.*dir.db$}
           70  +do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*dir.db\) - }
    71     71   
    72     72   # Test a failure in open() due to the path not existing.
    73     73   #
    74     74   do_test 1.3.1 {
    75     75     set ::log [list]
    76     76     list [catch { sqlite3 dbh /x/y/z/test.db } msg] $msg
    77     77   } {1 {unable to open database file}}
    78     78   
    79         -do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c: open.*test.db$}
           79  +do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*test.db\) - }
    80     80   
    81     81   # Test a failure in open() due to the path not existing.
    82     82   #
    83     83   do_test 1.4.1 {
    84     84     set ::log [list]
    85     85     list [catch { sqlite3 dbh /root/test.db } msg] $msg
    86     86   } {1 {unable to open database file}}
    87     87   
    88         -do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c: open.*test.db$}
           88  +do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(\d+\) open\(.*test.db\) - }
    89     89   
    90     90   #--------------------------------------------------------------------------
    91     91   # Tests oserror-1.* test failures in the unlink() system call.
    92     92   #
    93     93   do_test 2.1.1 {
    94     94     set ::log [list]
    95     95     file mkdir test.db-wal
    96     96     forcedelete test.db
    97     97     sqlite3 dbh test.db
    98     98     catchsql { SELECT * FROM sqlite_master } dbh
    99     99   } {1 {disk I/O error}}
   100    100   
   101         -do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c: unlink.*test.db-wal$}
          101  +do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) unlink\(.*test.db-wal\) - }
   102    102   do_test 2.1.3 { 
   103    103     dbh close
   104    104     forcedelete test.db-wal
   105    105   } {}
   106    106     
   107    107   
   108    108   sqlite3_shutdown
   109    109   test_sqlite3_log 
   110    110   sqlite3_initialize
   111    111   finish_test
   112         -  

test/progress.test became a regular file.


tool/mkopts.tcl became a regular file.


Changes to tool/omittest.tcl.

   198    198       SQLITE_OMIT_SHARED_CACHE \
   199    199       SQLITE_OMIT_SUBQUERY \
   200    200       SQLITE_OMIT_TCL_VARIABLE \
   201    201       SQLITE_OMIT_TEMPDB \
   202    202       SQLITE_OMIT_TRACE \
   203    203       SQLITE_OMIT_TRIGGER \
   204    204       SQLITE_OMIT_TRUNCATE_OPTIMIZATION \
          205  +    SQLITE_OMIT_UNIQUE_ENFORCEMENT \
   205    206       SQLITE_OMIT_UTF16 \
   206    207       SQLITE_OMIT_VACUUM \
   207    208       SQLITE_OMIT_VIEW \
   208    209       SQLITE_OMIT_VIRTUALTABLE \
   209    210       SQLITE_OMIT_WAL \
   210    211       SQLITE_OMIT_WSD \
   211    212       SQLITE_OMIT_XFER_OPT \