Modify the behaviour of writable_schema to ignore schema parsing errors. (CVS 3686)

FossilOrigin-Name: a8d6d935fbe32a759a55c1ef90adda7fe534acc1
diff --git a/src/pragma.c b/src/pragma.c
index 26bdba2..2177097 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.127 2007/01/27 02:24:56 drh Exp $
+** $Id: pragma.c,v 1.128 2007/03/14 15:37:04 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -157,7 +157,7 @@
     { "ignore_check_constraints", SQLITE_IgnoreChecks  },
 #endif
     /* The following is VERY experimental */
-    { "writable_schema",          SQLITE_WriteSchema   },
+    { "writable_schema",          SQLITE_WriteSchema|SQLITE_RecoveryMode },
     { "omit_readlock",            SQLITE_NoReadlock    },
 
     /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
diff --git a/src/prepare.c b/src/prepare.c
index 2c68112..36864ba 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.43 2007/01/09 14:01:13 drh Exp $
+** $Id: prepare.c,v 1.44 2007/03/14 15:37:04 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -310,10 +310,17 @@
     rc = SQLITE_NOMEM;
     sqlite3ResetInternalSchema(db, 0);
   }
-  if( rc==SQLITE_OK ){
+  if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
+    /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
+    ** the schema loaded, even if errors occured. In this situation the 
+    ** current sqlite3_prepare() operation will fail, but the following one
+    ** will attempt to compile the supplied statement against whatever subset
+    ** of the schema was loaded before the error occured. The primary
+    ** purpose of this is to allow access to the sqlite_master table
+    ** even when it's contents have been corrupted.
+    */
     DbSetProperty(db, iDb, DB_SchemaLoaded);
-  }else{
-    sqlite3ResetInternalSchema(db, iDb);
+    rc = SQLITE_OK;
   }
   return rc;
 }
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 1d5f21a..075f2fa 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.541 2007/03/02 06:24:19 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.542 2007/03/14 15:37:04 danielk1977 Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -545,6 +545,8 @@
 #define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
 #define SQLITE_LoadExtension  0x00020000  /* Enable load_extension */
 
+#define SQLITE_RecoveryMode   0x00040000  /* Ignore schema errors */
+
 /*
 ** Possible values for the sqlite.magic field.
 ** The numbers are obtained at random and have no special meaning, other