Add a generation counter to the Schema object and enhance OP_VerifySchema
to also check the Schema generation.  Fix for
ticket [f7b4edece25c99].

FossilOrigin-Name: 36c04dd1695f0899b53ce58738181b146fc005ed
diff --git a/src/build.c b/src/build.c
index 2cfb1f4..79ac436 100644
--- a/src/build.c
+++ b/src/build.c
@@ -156,7 +156,9 @@
         sqlite3VdbeUsesBtree(v, iDb);
         sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
         if( db->init.busy==0 ){
-          sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
+          sqlite3VdbeAddOp3(v, OP_VerifyCookie,
+                            iDb, pParse->cookieValue[iDb],
+                            db->aDb[iDb].pSchema->iGeneration);
         }
       }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
diff --git a/src/callback.c b/src/callback.c
index eaff6d0..fdee9bc 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -427,7 +427,10 @@
   sqlite3HashClear(&temp1);
   sqlite3HashClear(&pSchema->fkeyHash);
   pSchema->pSeqTab = 0;
-  pSchema->flags &= ~DB_SchemaLoaded;
+  if( pSchema->flags & DB_SchemaLoaded ){
+    pSchema->iGeneration++;
+    pSchema->flags &= ~DB_SchemaLoaded;
+  }
 }
 
 /*
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 0142d1e..c2d4607 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -671,6 +671,7 @@
 */
 struct Schema {
   int schema_cookie;   /* Database schema version number for this file */
+  int iGeneration;     /* Generation counter.  Incremented with each change */
   Hash tblHash;        /* All tables indexed by name */
   Hash idxHash;        /* All (named) indices indexed by name */
   Hash trigHash;       /* All triggers indexed by name */
diff --git a/src/vdbe.c b/src/vdbe.c
index 828baa5..b7dfd33 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2890,10 +2890,12 @@
   break;
 }
 
-/* Opcode: VerifyCookie P1 P2 *
+/* Opcode: VerifyCookie P1 P2 P3 * *
 **
 ** Check the value of global database parameter number 0 (the
-** schema version) and make sure it is equal to P2.  
+** schema version) and make sure it is equal to P2 and that the
+** generation counter on the local schema parse equals P3.
+**
 ** P1 is the database number which is 0 for the main database file
 ** and 1 for the file holding temporary tables and some higher number
 ** for auxiliary databases.
@@ -2908,16 +2910,19 @@
 */
 case OP_VerifyCookie: {
   int iMeta;
+  int iGen;
   Btree *pBt;
+
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (1<<pOp->p1))!=0 );
   pBt = db->aDb[pOp->p1].pBt;
   if( pBt ){
     sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
+    iGen = db->aDb[pOp->p1].pSchema->iGeneration;
   }else{
     iMeta = 0;
   }
-  if( iMeta!=pOp->p2 ){
+  if( iMeta!=pOp->p2 || iGen!=pOp->p3 ){
     sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
     /* If the schema-cookie from the database file matches the cookie 
diff --git a/src/vdbeblob.c b/src/vdbeblob.c
index f26cc87..18fdd46 100644
--- a/src/vdbeblob.c
+++ b/src/vdbeblob.c
@@ -266,6 +266,7 @@
       /* Configure the OP_VerifyCookie */
       sqlite3VdbeChangeP1(v, 1, iDb);
       sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
+      sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration);
 
       /* Make sure a mutex is held on the table to be accessed */
       sqlite3VdbeUsesBtree(v, iDb);