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

FossilOrigin-Name: 5914a11caa4c6e778cd7ca010427897c8f971552
diff --git a/manifest b/manifest
index d5fe551..8524e4a 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\stypo\sin\sa\scomment.\s(CVS\s1889)
-D 2004-08-17T10:42:55
+C Avoid\screating\sa\sTEMP\sdatabase\sunless\sit\sis\sabsolutely\snecessary.\s(CVS\s1890)
+D 2004-08-18T02:10:15
 F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -29,7 +29,7 @@
 F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217
 F src/btree.c 14c20dfb320473a1fd4e37d43eba5e2afd606757
 F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
-F src/build.c 951a36b246d9f38f2340562bfdd6a96bf7433530
+F src/build.c 2c608a4825160f4a723e1bc68f875853bf289913
 F src/date.c edff4aa851eeca8abbc737dc3933a2f0671156ce
 F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
@@ -39,7 +39,7 @@
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
 F src/insert.c bedcba371401395033a1a1c578d8fdc3fec87bec
 F src/legacy.c 2f3617c61bcdcd1d776154a9cfebf99facda8ad8
-F src/main.c 34a95ab1b2f6b33dfebb64d4367c34627b1f0a24
+F src/main.c a779422c5402df92c390e233ac32ab718fc4436b
 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
 F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
 F src/os_common.h cd7eb025fdab7dc91e0e97bf6310f1648205857f
@@ -51,7 +51,7 @@
 F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
 F src/os_win.c 54181eb73cb4783c4241feca9eaa490768b39008
 F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
-F src/pager.c 37b2159056b4c965eb055b544b301d0e7cd561dd
+F src/pager.c 4e3bbc44aeda16cebf7e502e82e211285e5b6f92
 F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
 F src/parse.y 589b1a39b23092888adfa9ec1f3ded8a35e8e006
 F src/pragma.c 5cf335adfdac453a2d03ab0c82f93847c43bea81
@@ -72,7 +72,7 @@
 F src/trigger.c 360cf8f12edd4eb3a8a2895b136aac238c3cf44e
 F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a
 F src/utf.c 3d8f7bffcbefcced69a436c9e0a1c7eb9e0bb4fa
-F src/util.c c1d903777e6d2e647d1c898db37d15fe3a1cc172
+F src/util.c e2c631849cc9e035f6fd387f507ad8886f77cedd
 F src/vacuum.c 9978a5760c2c430bc5b5e66505a02dad76f25813
 F src/vdbe.c 281af7f601a3220e86be2152eeb2ec6d82a6f71a
 F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52
@@ -83,7 +83,7 @@
 F src/where.c cf8a54641eea01f1af5d09529ad69166db92f658
 F test/all.test 3b692eb43583b52c99c344b2fa8934512d179016
 F test/attach.test 8fd75d2939528e1ae2a5030dfe738cd7fa8520eb
-F test/attach2.test b175333059e86c82dbf593fc922522ecb0f8aff8
+F test/attach2.test 07d509619d6f39a3b76c167d891d3c4f44f1bb15
 F test/attach3.test 6d060986ff004ebb89e1876a331d96c6bb62269e
 F test/auth.test e74b015545f608c06d5b84d17acdf7146eb818af
 F test/bigfile.test 62722ac4b420dfbcdceb137b8634e2cf2865fe27
@@ -242,7 +242,7 @@
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 7619bf4771781005da23a3e9d7b00de405e27a64
-R 3fab28d30448c92b5729efc763860d05
+P 9af1d4d1456d32c2e15f73f79928572f3bfba6ae
+R a62b70c2e591452c368e3b544bb10c66
 U drh
-Z 82fb33cabd0b5cd9f42772051414ee5b
+Z 4e553b9cd37331bb88d3fd47639da9eb
diff --git a/manifest.uuid b/manifest.uuid
index 49ed259..598432c 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-9af1d4d1456d32c2e15f73f79928572f3bfba6ae
\ No newline at end of file
+5914a11caa4c6e778cd7ca010427897c8f971552
\ No newline at end of file
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,
diff --git a/test/attach2.test b/test/attach2.test
index fac840c..e5dc2cd 100644
--- a/test/attach2.test
+++ b/test/attach2.test
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and related functionality.
 #
-# $Id: attach2.test,v 1.22 2004/07/19 17:25:25 drh Exp $
+# $Id: attach2.test,v 1.23 2004/08/18 02:10:15 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -165,8 +165,8 @@
   execsql {ATTACH 'test2.db' as file2} db2
 } {}
 
-lock_status 4.1.1 db {main unlocked temp unlocked file2 unlocked}
-lock_status 4.1.2 db2 {main unlocked temp unlocked file2 unlocked}
+lock_status 4.1.1 db {main unlocked temp closed file2 unlocked}
+lock_status 4.1.2 db2 {main unlocked temp closed file2 unlocked}
 
 do_test attach2-4.2 {
   # Handle 'db' read-locks test.db
@@ -177,16 +177,16 @@
   #    db2 -
 } {}
 
-lock_status 4.2.1 db {main shared temp unlocked file2 unlocked}
-lock_status 4.2.2 db2 {main unlocked temp unlocked file2 unlocked}
+lock_status 4.2.1 db {main shared temp closed file2 unlocked}
+lock_status 4.2.2 db2 {main unlocked temp closed file2 unlocked}
 
 do_test attach2-4.3 {
   # The read lock held by db does not prevent db2 from reading test.db
   execsql {SELECT * FROM t1} db2
 } {}
 
-lock_status 4.3.1 db {main shared temp unlocked file2 unlocked}
-lock_status 4.3.2 db2 {main unlocked temp unlocked file2 unlocked}
+lock_status 4.3.1 db {main shared temp closed file2 unlocked}
+lock_status 4.3.2 db2 {main unlocked temp closed file2 unlocked}
 
 do_test attach2-4.4 {
   # db is holding a read lock on test.db, so we should not be able
@@ -196,7 +196,7 @@
   } db2 
 } {1 {database is locked}}
 
-lock_status 4.4.1 db {main shared temp unlocked file2 unlocked}
+lock_status 4.4.1 db {main shared temp closed file2 unlocked}
 lock_status 4.4.2 db2 {main unlocked temp unlocked file2 unlocked}
 
 do_test attach2-4.5 {
@@ -208,7 +208,7 @@
   #    db2 - reserved(file2)
 } {}
 
-lock_status 4.5.1 db {main shared temp unlocked file2 unlocked}
+lock_status 4.5.1 db {main shared temp closed file2 unlocked}
 lock_status 4.5.2 db2 {main unlocked temp reserved file2 reserved}
 
 do_test attach2-4.6.1 {
@@ -221,7 +221,7 @@
   #    db2 - reserved(file2)
 } {0 {}}
 
-lock_status 4.6.1.1 db {main shared temp unlocked file2 shared}
+lock_status 4.6.1.1 db {main shared temp closed file2 shared}
 lock_status 4.6.1.2 db2 {main unlocked temp reserved file2 reserved}
 
 do_test attach2-4.6.2 {