Avoid creating a TEMP database unless it is absolutely necessary. (CVS 1890)

FossilOrigin-Name: 5914a11caa4c6e778cd7ca010427897c8f971552
diff --git a/src/build.c b/src/build.c
index 764169d..b351ac1 100644
--- a/src/build.c
+++ b/src/build.c
@@ -23,7 +23,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.246 2004/08/08 23:39:19 drh Exp $
+** $Id: build.c,v 1.247 2004/08/18 02:10:15 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -647,31 +647,6 @@
   }
 #endif
 
-  /* Before trying to create a temporary table, make sure the Btree for
-  ** holding temporary tables is open.
-  */
-  if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
-    int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
-    if( rc!=SQLITE_OK ){
-      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
-        "file for storing temporary tables");
-      pParse->nErr++;
-      pParse->rc = rc;
-      sqliteFree(zName);
-      return;
-    }
-    if( db->flags & !db->autoCommit ){
-      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
-      if( rc!=SQLITE_OK ){
-        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
-          "the temporary database file");
-        sqliteFree(zName);
-        pParse->rc = rc;
-        return;
-      }
-    }
-  }
-
   /* Make sure the new table name does not collide with an existing
   ** index or table name in the same database.  Issue an error message if
   ** it does.
@@ -2476,6 +2451,33 @@
 }
 
 /*
+** Make sure the TEMP database is open and available for use.  Return
+** the number of errors.  Leave any error messages in the pParse structure.
+*/
+static int sqlite3OpenTempDatabase(Parse *pParse){
+  sqlite3 *db = pParse->db;
+  if( db->aDb[1].pBt==0 && !pParse->explain ){
+    int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
+    if( rc!=SQLITE_OK ){
+      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
+        "file for storing temporary tables");
+      pParse->rc = rc;
+      return 1;
+    }
+    if( db->flags & !db->autoCommit ){
+      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
+      if( rc!=SQLITE_OK ){
+        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
+          "the temporary database file");
+        pParse->rc = rc;
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+
+/*
 ** Generate VDBE code that will verify the schema cookie and start
 ** a read-transaction for all named database files.
 **
@@ -2516,6 +2518,9 @@
     if( (pParse->cookieMask & mask)==0 ){
       pParse->cookieMask |= mask;
       pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie;
+      if( iDb==1 ){
+        sqlite3OpenTempDatabase(pParse);
+      }
     }
   }
 }
diff --git a/src/main.c b/src/main.c
index ce7f223..0d34349 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.251 2004/08/14 19:20:10 drh Exp $
+** $Id: main.c,v 1.252 2004/08/18 02:10:15 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -184,7 +184,10 @@
 
   /* Create a cursor to hold the database open
   */
-  if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
+  if( db->aDb[iDb].pBt==0 ){
+    if( iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
+    return SQLITE_OK;
+  }
   rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
   if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
     sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
diff --git a/src/pager.c b/src/pager.c
index eed8036..5ba67bc 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.154 2004/08/07 23:54:48 drh Exp $
+** @(#) $Id: pager.c,v 1.155 2004/08/18 02:10:15 drh Exp $
 */
 #include "os.h"         /* Must be first to enable large file support */
 #include "sqliteInt.h"
@@ -1659,9 +1659,7 @@
 */
 int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
   int rc;
-  if( pPager->dbSize<0 ){
-    sqlite3pager_pagecount(pPager);
-  }
+  sqlite3pager_pagecount(pPager);
   if( pPager->errMask!=0 ){
     rc = pager_errcode(pPager);
     return rc;
@@ -2211,7 +2209,7 @@
     if( pPager->nExtra>0 ){
       memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
     }
-    if( pPager->dbSize<0 ) sqlite3pager_pagecount(pPager);
+    sqlite3pager_pagecount(pPager);
     if( pPager->errMask!=0 ){
       sqlite3pager_unref(PGHDR_TO_DATA(pPg));
       rc = pager_errcode(pPager);
@@ -2917,6 +2915,7 @@
   int rc;
   char zTemp[SQLITE_TEMPNAME_SIZE];
   assert( !pPager->stmtInUse );
+  assert( pPager->dbSize>=0 );
   TRACE2("STMT-BEGIN %d\n", pPager->fd.h);
   if( pPager->memDb ){
     pPager->stmtInUse = 1;
diff --git a/src/util.c b/src/util.c
index ac47fd7..8c7985d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.112 2004/08/08 20:22:18 drh Exp $
+** $Id: util.c,v 1.113 2004/08/18 02:10:15 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -789,7 +789,7 @@
 */
 int sqlite3ReadUtf8(const unsigned char *z){
   int c;
-  static const int initVal[] = {
+  static const char initVal[] = {
       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
      15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
      30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,