More work toward getting sqlite3_interrupt() to work from separate
threads.  Ticket #1897. (CVS 3336)

FossilOrigin-Name: e431131d47481f9fc64c498e8934b10a96b0a931
diff --git a/src/prepare.c b/src/prepare.c
index 3d4d641..5d65dc0 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.36 2006/06/26 12:50:09 drh Exp $
+** $Id: prepare.c,v 1.37 2006/07/26 13:43:31 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -28,6 +28,7 @@
     sqlite3SetString(pData->pzErrMsg, "malformed database schema",
        zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
   }
+  pData->rc = SQLITE_CORRUPT;
 }
 
 /*
@@ -49,6 +50,7 @@
   sqlite3 *db = pData->db;
   int iDb;
 
+  pData->rc = SQLITE_OK;
   if( sqlite3MallocFailed() ){
     return SQLITE_NOMEM;
   }
@@ -76,13 +78,14 @@
     db->init.iDb = 0;
     assert( rc!=SQLITE_OK || zErr==0 );
     if( SQLITE_OK!=rc ){
+      pData->rc = rc;
       if( rc==SQLITE_NOMEM ){
         sqlite3FailedMalloc();
-      }else{
+      }else if( rc!=SQLITE_INTERRUPT ){
         corruptSchema(pData, zErr);
       }
       sqlite3_free(zErr);
-      return rc;
+      return 1;
     }
   }else{
     /* If the SQL column is blank it means this is an index that
@@ -179,9 +182,9 @@
   initData.db = db;
   initData.pzErrMsg = pzErrMsg;
   rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
-  if( rc!=SQLITE_OK ){
+  if( rc ){
     sqlite3SafetyOn(db);
-    return rc;
+    return initData.rc;
   }
   pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
   if( pTab ){
@@ -295,6 +298,7 @@
         zDbNum, db->aDb[iDb].zName, zMasterName);
     sqlite3SafetyOff(db);
     rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+    if( rc==SQLITE_ABORT ) rc = initData.rc;
     sqlite3SafetyOn(db);
     sqliteFree(zSql);
 #ifndef SQLITE_OMIT_ANALYZE
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index d5e4376..a8a3ce1 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.522 2006/07/26 01:39:30 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.523 2006/07/26 13:43:31 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1513,6 +1513,7 @@
 typedef struct {
   sqlite3 *db;        /* The database being initialized */
   char **pzErrMsg;    /* Error message stored here */
+  int rc;             /* Result code stored here */
 } InitData;
 
 /*
diff --git a/src/tokenize.c b/src/tokenize.c
index 04da0dc..1ade8b8 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -15,7 +15,7 @@
 ** individual tokens and sends those tokens one-by-one over to the
 ** parser for analysis.
 **
-** $Id: tokenize.c,v 1.122 2006/07/26 01:39:30 drh Exp $
+** $Id: tokenize.c,v 1.123 2006/07/26 13:43:31 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -394,7 +394,9 @@
   extern void sqlite3ParserFree(void*, void(*)(void*));
   extern int sqlite3Parser(void*, int, Token, Parse*);
 
-  db->u1.isInterrupted = 0;
+  if( db->activeVdbeCnt==0 ){
+    db->u1.isInterrupted = 0;
+  }
   pParse->rc = SQLITE_OK;
   i = 0;
   pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX);
diff --git a/src/vdbe.c b/src/vdbe.c
index 2038908..40595e4 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.571 2006/07/26 01:39:30 drh Exp $
+** $Id: vdbe.c,v 1.572 2006/07/26 13:43:31 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -4048,6 +4048,7 @@
   db->init.busy = 1;
   assert( !sqlite3MallocFailed() );
   rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+  if( rc==SQLITE_ABORT ) rc = initData.rc;
   sqliteFree(zSql);
   db->init.busy = 0;
   sqlite3SafetyOn(db);
@@ -4971,7 +4972,6 @@
   */
 abort_due_to_interrupt:
   assert( db->u1.isInterrupted );
-  db->u1.isInterrupted = 0;
   if( db->magic!=SQLITE_MAGIC_BUSY ){
     rc = SQLITE_MISUSE;
   }else{
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 3b0a6ad..a57cff3 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -180,6 +180,14 @@
     return SQLITE_MISUSE;
   }
   if( p->pc<0 ){
+    /* If there are no other statements currently running, then
+    ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
+    ** from interrupting a statement that has not yet started.
+    */
+    if( db->activeVdbeCnt==0 ){
+      db->u1.isInterrupted = 0;
+    }
+
 #ifndef SQLITE_OMIT_TRACE
     /* Invoke the trace callback if there is one
     */
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 08361d1..bd5a001 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -671,7 +671,6 @@
     p->rc = SQLITE_OK;
     rc = SQLITE_DONE;
   }else if( db->u1.isInterrupted ){
-    db->u1.isInterrupted = 0;
     p->rc = SQLITE_INTERRUPT;
     rc = SQLITE_ERROR;
     sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);