Check-in [aeaee1f385]
Not logged in
Overview

SHA1 Hash:aeaee1f38512181e15be7520ab7d629eb63d2422
Date: 2009-09-10 23:00:22
User: drh
Comment:Add extra quoted to system() calls on windows. Ticket 8d073be8808b. Also update to the latest SQLite.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/diffcmd.c from [38b20f8775] to [5229e8f323].

@@ -171,11 +171,12 @@
     }
     if( zExternalCommand==0 ){
       internalDiff=1;
     }
     blob_zero(&cmd);
-    blob_appendf(&cmd, "%s ", zExternalCommand);
+    shell_escape(&cmd, zExternalCommand);
+    blob_append(&cmd, " ", 1);
   }
   zFile = g.argv[g.argc-1];
   file_tree_name(zFile, &fname, 1);
 
   blob_zero(&vname);
@@ -208,12 +209,30 @@
     blob_write_to_file(&record, blob_str(&vname));
     blob_reset(&record);
     shell_escape(&cmd, blob_str(&vname));
     blob_appendf(&cmd, " ");
     shell_escape(&cmd, zFile);
-    system(blob_str(&cmd));
+    portable_system(blob_str(&cmd));
     unlink(blob_str(&vname));
     blob_reset(&vname);
     blob_reset(&cmd);
   }
   blob_reset(&fname);
+}
+
+/*
+** This function implements a cross-platform "system()" interface.
+*/
+void portable_system(char *zOrigCmd){
+#ifdef __MINGW32__
+  /* On windows, we have to put double-quotes around the entire command.
+  ** Who knows why - this is just the way windows works.
+  */
+  char *zNewCmd = mprintf("\"%s\"", zOrigCmd);
+  system(zNewCmd);
+  free(zNewCmd);
+#else
+  /* On unix, evaluate the command directly.
+  */
+  system(zOrigCmd);
+#endif
 }

Modified src/http_transport.c from [409df8860f] to [bc6bc305c4].

@@ -162,15 +162,11 @@
     char *zCmd;
     fclose(transport.pFile);
     zCmd = mprintf("\"%s\" http \"%s\" \"%s\" \"%s\" 127.0.0.1",
        g.argv[0], g.urlName, transport.zOutFile, transport.zInFile
     );
-#ifdef __MINGW32__
-    /* Quote the entire command to work around goofiness in system() on
-    ** on windows. Ticket [40df1ced7e] */
-    zCmd = mprintf("\"%z\"", zCmd);
-#endif
+    portable_system(zCmd);
     system(zCmd);
     free(zCmd);
     transport.pFile = fopen(transport.zInFile, "rb");
   }
 }

Modified src/sqlite3.c from [6af451108a] to [323d3b7b26].

@@ -15,11 +15,11 @@
 ** of the embedded sqlite3.h header file.) Additional code files may be needed
 ** if you want a wrapper to interface SQLite with your choice of programming
 ** language. The code for the "sqlite3" command-line shell is also in a
 ** separate file. This file contains only code for the core SQLite library.
 **
-** This amalgamation was generated on 2009-09-09 16:11:06 UTC.
+** This amalgamation was generated on 2009-09-10 22:23:14 UTC.
 */
 #define SQLITE_CORE 1
 #define SQLITE_AMALGAMATION 1
 #ifndef SQLITE_PRIVATE
 # define SQLITE_PRIVATE static
@@ -275,11 +275,15 @@
 
 /*
 ** Maximum depth of recursion for triggers.
 */
 #ifndef SQLITE_MAX_TRIGGER_DEPTH
+#if defined(SQLITE_SMALL_STACK)
+# define SQLITE_MAX_TRIGGER_DEPTH 10
+#else
 # define SQLITE_MAX_TRIGGER_DEPTH 1000
+#endif
 #endif
 
 /************** End of sqliteLimit.h *****************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
 
@@ -643,11 +647,11 @@
 **
 ** Requirements: [H10011] [H10014]
 */
 #define SQLITE_VERSION        "3.6.18"
 #define SQLITE_VERSION_NUMBER 3006018
-#define SQLITE_SOURCE_ID      "2009-09-09 16:10:51 f0c72a53c5d57d7487b48a06a40816153f47aaac"
+#define SQLITE_SOURCE_ID      "2009-09-10 20:23:30 f42ec993ac9d42ca31305f26b09924108c36d9f4"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
 ** KEYWORDS: sqlite3_version
 **
@@ -7506,11 +7510,11 @@
 SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int);
 SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
 SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
 #ifdef SQLITE_DEBUG
-SQLITE_PRIVATE   int sqlite3VdbeMayAbort(Vdbe*);
+SQLITE_PRIVATE   int sqlite3VdbeAssertMayAbort(Vdbe *, int);
 SQLITE_PRIVATE   void sqlite3VdbeTrace(Vdbe*,FILE*);
 #endif
 SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*);
 SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
@@ -11373,11 +11377,11 @@
     x.s = s;
   }
   x.tz = 0;
   x.validJD = 0;
   computeJD(&x);
-  t = x.iJD/1000 - 21086676*(i64)10000;
+  t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
 #ifdef HAVE_LOCALTIME_R
   {
     struct tm sLocal;
     localtime_r(&t, &sLocal);
     y.Y = sLocal.tm_year + 1900;
@@ -14369,10 +14373,20 @@
 
 **
 ** $Id: mutex.c,v 1.31 2009/07/16 18:21:18 drh Exp $
 */
 
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
+/*
+** For debugging purposes, record when the mutex subsystem is initialized
+** and uninitialized so that we can assert() if there is an attempt to
+** allocate a mutex while the system is uninitialized.
+*/
+static SQLITE_WSD int mutexIsInit = 0;
+#endif /* SQLITE_DEBUG */
+
+
 #ifndef SQLITE_MUTEX_OMIT
 /*
 ** Initialize the mutex system.
 */
 SQLITE_PRIVATE int sqlite3MutexInit(void){
@@ -14393,10 +14407,14 @@
       pTo->xMutexAlloc = pFrom->xMutexAlloc;
     }
     rc = sqlite3GlobalConfig.mutex.xMutexInit();
   }
 
+#ifdef SQLITE_DEBUG
+  GLOBAL(int, mutexIsInit) = 1;
+#endif
+
   return rc;
 }
 
 /*
 ** Shutdown the mutex system. This call frees resources allocated by
@@ -14405,10 +14423,15 @@
 SQLITE_PRIVATE int sqlite3MutexEnd(void){
   int rc = SQLITE_OK;
   if( sqlite3GlobalConfig.mutex.xMutexEnd ){
     rc = sqlite3GlobalConfig.mutex.xMutexEnd();
   }
+
+#ifdef SQLITE_DEBUG
+  GLOBAL(int, mutexIsInit) = 0;
+#endif
+
   return rc;
 }
 
 /*
 ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
@@ -14422,10 +14445,11 @@
 
 SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
   if( !sqlite3GlobalConfig.bCoreMutex ){
     return 0;
   }
+  assert( GLOBAL(int, mutexIsInit) );
   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
 }
 
 /*
 ** Free a dynamic mutex.
@@ -22403,11 +22427,21 @@
       }
       if( pOpen->pNext ){
         assert( pOpen->pNext->pPrev==pOpen );
         pOpen->pNext->pPrev = pOpen->pPrev;
       }
-      assert( !pOpen->pUnused );
+#if SQLITE_THREADSAFE && defined(__linux__)
+      assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 );
+#endif
+
+      /* If pOpen->pUnused is not null, then memory and file-descriptors
+      ** are leaked.
+      **
+      ** This will only happen if, under Linuxthreads, the user has opened
+      ** a transaction in one thread, then attempts to close the database
+      ** handle from another thread (without first unlocking the db file).
+      ** This is a misuse.  */
       sqlite3_free(pOpen);
     }
   }
 }
 
@@ -27555,21 +27589,21 @@
 
   if (!pFile->hMutex) return TRUE;
   winceMutexAcquire(pFile->hMutex);
 
   /* Wanting an exclusive lock? */
-  if (dwFileOffsetLow == SHARED_FIRST
-       && nNumberOfBytesToLockLow == SHARED_SIZE){
+  if (dwFileOffsetLow == (DWORD)SHARED_FIRST
+       && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
     if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
        pFile->shared->bExclusive = TRUE;
        pFile->local.bExclusive = TRUE;
        bReturn = TRUE;
     }
   }
 
   /* Want a read-only lock? */
-  else if (dwFileOffsetLow == SHARED_FIRST &&
+  else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
            nNumberOfBytesToLockLow == 1){
     if (pFile->shared->bExclusive == 0){
       pFile->local.nReaders ++;
       if (pFile->local.nReaders == 1){
         pFile->shared->nReaders ++;
@@ -27577,21 +27611,21 @@
       bReturn = TRUE;
     }
   }
 
   /* Want a pending lock? */
-  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
+  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
     /* If no pending lock has been acquired, then acquire it */
     if (pFile->shared->bPending == 0) {
       pFile->shared->bPending = TRUE;
       pFile->local.bPending = TRUE;
       bReturn = TRUE;
     }
   }
 
   /* Want a reserved lock? */
-  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
+  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
     if (pFile->shared->bReserved == 0) {
       pFile->shared->bReserved = TRUE;
       pFile->local.bReserved = TRUE;
       bReturn = TRUE;
     }
@@ -27619,22 +27653,22 @@
 
   if (!pFile->hMutex) return TRUE;
   winceMutexAcquire(pFile->hMutex);
 
   /* Releasing a reader lock or an exclusive lock */
-  if (dwFileOffsetLow == SHARED_FIRST){
+  if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
     /* Did we have an exclusive lock? */
     if (pFile->local.bExclusive){
-      assert(nNumberOfBytesToUnlockLow == SHARED_SIZE);
+      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
       pFile->local.bExclusive = FALSE;
       pFile->shared->bExclusive = FALSE;
       bReturn = TRUE;
     }
 
     /* Did we just have a reader lock? */
     else if (pFile->local.nReaders){
-      assert(nNumberOfBytesToUnlockLow == 1);
+      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
       pFile->local.nReaders --;
       if (pFile->local.nReaders == 0)
       {
         pFile->shared->nReaders --;
       }
@@ -27641,19 +27675,19 @@
       bReturn = TRUE;
     }
   }
 
   /* Releasing a pending lock */
-  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
+  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
     if (pFile->local.bPending){
       pFile->local.bPending = FALSE;
       pFile->shared->bPending = FALSE;
       bReturn = TRUE;
     }
   }
   /* Releasing a reserved lock */
-  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
+  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
     if (pFile->local.bReserved) {
       pFile->local.bReserved = FALSE;
       pFile->shared->bReserved = FALSE;
       bReturn = TRUE;
     }
@@ -27677,13 +27711,13 @@
   UNUSED_PARAMETER(dwReserved);
   UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
 
   /* If the caller wants a shared read lock, forward this call
   ** to winceLockFile */
-  if (lpOverlapped->Offset == SHARED_FIRST &&
+  if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
       dwFlags == 1 &&
-      nNumberOfBytesToLockLow == SHARED_SIZE){
+      nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
     return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
   }
   return FALSE;
 }
 /*
@@ -47373,11 +47407,11 @@
 
   return pRet;
 }
 
 /*
-** Return true if the program stored in the VM passed as an argument may
+** Check if the program stored in the VM associated with pParse may
 ** throw an ABORT exception (causing the statement, but not transaction
 ** to be rolled back). This condition is true if the main program or any
 ** sub-programs contains any of the following:
 **
 **   *  OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
@@ -47384,14 +47418,19 @@
 **   *  OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
 **   *  OP_Destroy
 **   *  OP_VUpdate
 **   *  OP_VRename
 **
-** This function is only used as part of an assert() statement.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMayAbort(Vdbe *v){
-  int mayAbort = 0;
+** Then check that the value of Parse.mayAbort is true if an
+** ABORT may be thrown, or false otherwise. Return true if it does
+** match, or false otherwise. This function is intended to be used as
+** part of an assert statement in the compiler. Similar to:
+**
+**   assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
+*/
+SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
+  int hasAbort = 0;
   Op *pOp;
   VdbeOpIter sIter;
   memset(&sIter, 0, sizeof(sIter));
   sIter.v = v;
 
@@ -47399,17 +47438,22 @@
     int opcode = pOp->opcode;
     if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
      || ((opcode==OP_Halt || opcode==OP_HaltIfNull)
       && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
     ){
-      mayAbort = 1;
-      break;
-    }
-  }
-
+      hasAbort = 1;
+      break;
+    }
+  }
   sqlite3DbFree(v->db, sIter.apSub);
-  return mayAbort;
+
+  /* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
+  ** If malloc failed, then the while() loop above may not have iterated
+  ** through all opcodes and hasAbort may be set incorrectly. Return
+  ** true for this case to prevent the assert() in the callers frame
+  ** from failing.  */
+  return ( v->db->mallocFailed || hasAbort==mayAbort );
 }
 #endif
 
 /*
 ** Loop through the program looking for P2 values that are negative
@@ -48365,11 +48409,11 @@
   int nVar,                      /* Number of '?' see in the SQL statement */
   int nMem,                      /* Number of memory cells to allocate */
   int nCursor,                   /* Number of cursors to allocate */
   int nArg,                      /* Maximum number of args in SubPrograms */
   int isExplain,                 /* True if the EXPLAIN keywords is present */
-  int usesStmtJournal             /* True to set Vdbe.usesStmtJournal */
+  int usesStmtJournal            /* True to set Vdbe.usesStmtJournal */
 ){
   int n;
   sqlite3 *db = p->db;
 
   assert( p!=0 );
@@ -48401,11 +48445,11 @@
   if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){
     u8 *zCsr = (u8 *)&p->aOp[p->nOp];
     u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc];
     int nByte;
     resolveP2Values(p, &nArg);
-    p->usesStmtJournal = usesStmtJournal;
+    p->usesStmtJournal = (u8)usesStmtJournal;
     if( isExplain && nMem<10 ){
       nMem = 10;
     }
     memset(zCsr, 0, zEnd-zCsr);
     zCsr += (zCsr - (u8*)0)&7;
@@ -55382,18 +55426,22 @@
         }
       }
 
 #ifndef SQLITE_OMIT_AUTOINCREMENT
       if( pOp->p3 ){
+        /* Assert that P3 is a valid memory cell. */
+        assert( pOp->p3>0 );
         if( p->pFrame ){
           for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent);
+          /* Assert that P3 is a valid memory cell. */
+          assert( pOp->p3<=u.be.pFrame->nMem );
           u.be.pMem = &u.be.pFrame->aMem[pOp->p3];
         }else{
+          /* Assert that P3 is a valid memory cell. */
+          assert( pOp->p3<=p->nMem );
           u.be.pMem = &p->aMem[pOp->p3];
         }
-        /* Assert that P3 is a valid memory cell. */
-        assert( pOp->p3>0 && pOp->p3<=(p->pFrame ? u.be.pFrame->nMem : p->nMem) );
 
         REGISTER_TRACE(pOp->p3, u.be.pMem);
         sqlite3VdbeMemIntegerify(u.be.pMem);
         assert( (u.be.pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
         if( u.be.pMem->u.i==MAX_ROWID || u.be.pC->useRandomRowid ){
@@ -65441,11 +65489,12 @@
 
   /* Begin by generating some termination code at the end of the
   ** vdbe program
   */
   v = sqlite3GetVdbe(pParse);
-  assert( pParse->isMultiWrite==0 || sqlite3VdbeMayAbort(v)==pParse->mayAbort );
+  assert( !pParse->isMultiWrite
+       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
   if( v ){
     sqlite3VdbeAddOp0(v, OP_Halt);
 
     /* The cookie mask contains one bit for each database file open.
     ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
@@ -77658,11 +77707,11 @@
       Table *pTab = 0;            /* Table structure column is extracted from */
       Select *pS = 0;             /* Select the column is extracted from */
       int iCol = pExpr->iColumn;  /* Index of column in pTab */
       testcase( pExpr->op==TK_AGG_COLUMN );
       testcase( pExpr->op==TK_COLUMN );
-      while( ALWAYS(pNC) && !pTab ){
+      while( pNC && !pTab ){
         SrcList *pTabList = pNC->pSrcList;
         for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
         if( j<pTabList->nSrc ){
           pTab = pTabList->a[j].pTab;
           pS = pTabList->a[j].pSelect;
@@ -77669,22 +77718,32 @@
         }else{
           pNC = pNC->pNext;
         }
       }
 
-      if( NEVER(pTab==0) ){
+      if( pTab==0 ){
         /* At one time, code such as "SELECT new.x" within a trigger would
         ** cause this condition to run.  Since then, we have restructured how
         ** trigger code is generated and so this condition is no longer
-        ** possible.  But it seems prudent to keep the test in place in
-        ** case something else changes.
-        */
-        zType = "TEXT";
-        break;
-      }
-
-      assert( pTab );
+        ** possible. However, it can still be true for statements like
+        ** the following:
+        **
+        **   CREATE TABLE t1(col INTEGER);
+        **   SELECT (SELECT t1.col) FROM FROM t1;
+        **
+        ** when columnType() is called on the expression "t1.col" in the
+        ** sub-select. In this case, set the column type to NULL, even
+        ** though it should really be "INTEGER".
+        **
+        ** This is not a problem, as the column type of "t1.col" is never
+        ** used. When columnType() is called on the expression
+        ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
+        ** branch below.  */
+        break;
+      }
+
+      assert( pTab && pExpr->pTab==pTab );
       if( pS ){
         /* The "table" is actually a sub-select or a view in the FROM clause
         ** of the SELECT statement. Return the declaration type and origin
         ** data for the result-set column of the sub-select.
         */
@@ -77694,11 +77753,11 @@
           ** test case misc2.2.2) - it always evaluates to NULL.
           */
           NameContext sNC;
           Expr *p = pS->pEList->a[iCol].pExpr;
           sNC.pSrcList = pS->pSrc;
-          sNC.pNext = 0;
+          sNC.pNext = pNC;
           sNC.pParse = pNC->pParse;
           zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
         }
       }else if( ALWAYS(pTab->pSchema) ){
         /* A real table */

Modified src/sqlite3.h from [ea0493c46c] to [34a15ec991].

@@ -119,11 +119,11 @@
 **
 ** Requirements: [H10011] [H10014]
 */
 #define SQLITE_VERSION        "3.6.18"
 #define SQLITE_VERSION_NUMBER 3006018
-#define SQLITE_SOURCE_ID      "2009-09-09 16:10:51 f0c72a53c5d57d7487b48a06a40816153f47aaac"
+#define SQLITE_SOURCE_ID      "2009-09-10 19:20:03 e9d064bd9318c2bc9248df948f71fd30f24525eb"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
 ** KEYWORDS: sqlite3_version
 **