r2605 - in packages/libdbd-sqlite3-perl/trunk: . debian lib/DBD t

Krzysztof Krzyzaniak eloy at costa.debian.org
Tue Apr 18 15:20:54 UTC 2006


Author: eloy
Date: 2006-04-18 15:20:48 +0000 (Tue, 18 Apr 2006)
New Revision: 2605

Added:
   packages/libdbd-sqlite3-perl/trunk/._Changes
   packages/libdbd-sqlite3-perl/trunk/._SQLiteXS.h
   packages/libdbd-sqlite3-perl/trunk/complete.c
   packages/libdbd-sqlite3-perl/trunk/earlyexit.pl
   packages/libdbd-sqlite3-perl/trunk/os.c
   packages/libdbd-sqlite3-perl/trunk/t/._04select.t
   packages/libdbd-sqlite3-perl/trunk/t/._05tran.t
   packages/libdbd-sqlite3-perl/trunk/t/._40blobtext.t
   packages/libdbd-sqlite3-perl/trunk/t/07busy.t
   packages/libdbd-sqlite3-perl/trunk/t/11unicode.t
Modified:
   packages/libdbd-sqlite3-perl/trunk/Changes
   packages/libdbd-sqlite3-perl/trunk/MANIFEST
   packages/libdbd-sqlite3-perl/trunk/META.yml
   packages/libdbd-sqlite3-perl/trunk/alter.c
   packages/libdbd-sqlite3-perl/trunk/analyze.c
   packages/libdbd-sqlite3-perl/trunk/attach.c
   packages/libdbd-sqlite3-perl/trunk/auth.c
   packages/libdbd-sqlite3-perl/trunk/btree.c
   packages/libdbd-sqlite3-perl/trunk/btree.h
   packages/libdbd-sqlite3-perl/trunk/build.c
   packages/libdbd-sqlite3-perl/trunk/callback.c
   packages/libdbd-sqlite3-perl/trunk/date.c
   packages/libdbd-sqlite3-perl/trunk/dbdimp.c
   packages/libdbd-sqlite3-perl/trunk/dbdimp.h
   packages/libdbd-sqlite3-perl/trunk/debian/changelog
   packages/libdbd-sqlite3-perl/trunk/delete.c
   packages/libdbd-sqlite3-perl/trunk/experimental.c
   packages/libdbd-sqlite3-perl/trunk/expr.c
   packages/libdbd-sqlite3-perl/trunk/func.c
   packages/libdbd-sqlite3-perl/trunk/getsqlite.pl
   packages/libdbd-sqlite3-perl/trunk/hash.c
   packages/libdbd-sqlite3-perl/trunk/hash.h
   packages/libdbd-sqlite3-perl/trunk/insert.c
   packages/libdbd-sqlite3-perl/trunk/keywordhash.h
   packages/libdbd-sqlite3-perl/trunk/legacy.c
   packages/libdbd-sqlite3-perl/trunk/lib/DBD/SQLite.pm
   packages/libdbd-sqlite3-perl/trunk/main.c
   packages/libdbd-sqlite3-perl/trunk/opcodes.c
   packages/libdbd-sqlite3-perl/trunk/opcodes.h
   packages/libdbd-sqlite3-perl/trunk/os.h
   packages/libdbd-sqlite3-perl/trunk/os_common.h
   packages/libdbd-sqlite3-perl/trunk/os_unix.c
   packages/libdbd-sqlite3-perl/trunk/os_win.c
   packages/libdbd-sqlite3-perl/trunk/pager.c
   packages/libdbd-sqlite3-perl/trunk/pager.h
   packages/libdbd-sqlite3-perl/trunk/parse.c
   packages/libdbd-sqlite3-perl/trunk/parse.h
   packages/libdbd-sqlite3-perl/trunk/pragma.c
   packages/libdbd-sqlite3-perl/trunk/prepare.c
   packages/libdbd-sqlite3-perl/trunk/printf.c
   packages/libdbd-sqlite3-perl/trunk/random.c
   packages/libdbd-sqlite3-perl/trunk/select.c
   packages/libdbd-sqlite3-perl/trunk/sqlite3.h
   packages/libdbd-sqlite3-perl/trunk/sqliteInt.h
   packages/libdbd-sqlite3-perl/trunk/table.c
   packages/libdbd-sqlite3-perl/trunk/tokenize.c
   packages/libdbd-sqlite3-perl/trunk/trigger.c
   packages/libdbd-sqlite3-perl/trunk/update.c
   packages/libdbd-sqlite3-perl/trunk/utf.c
   packages/libdbd-sqlite3-perl/trunk/util.c
   packages/libdbd-sqlite3-perl/trunk/vacuum.c
   packages/libdbd-sqlite3-perl/trunk/vdbe.c
   packages/libdbd-sqlite3-perl/trunk/vdbe.h
   packages/libdbd-sqlite3-perl/trunk/vdbeInt.h
   packages/libdbd-sqlite3-perl/trunk/vdbeapi.c
   packages/libdbd-sqlite3-perl/trunk/vdbeaux.c
   packages/libdbd-sqlite3-perl/trunk/vdbemem.c
   packages/libdbd-sqlite3-perl/trunk/where.c
Log:
eloy: new upstream release


Copied: packages/libdbd-sqlite3-perl/trunk/._Changes (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/._Changes)

Copied: packages/libdbd-sqlite3-perl/trunk/._SQLiteXS.h (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/._SQLiteXS.h)

Modified: packages/libdbd-sqlite3-perl/trunk/Changes
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/Changes	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/Changes	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,5 +1,8 @@
 Revision history for Perl extension DBD::SQLite.
 
+1.12
+	- Brought up to date with SQLite 3.3.5
+
 1.11
     - Make blobs work transparently (without SQLBLOB binding)
 

Modified: packages/libdbd-sqlite3-perl/trunk/MANIFEST
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/MANIFEST	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/MANIFEST	2006-04-18 15:20:48 UTC (rev 2605)
@@ -7,10 +7,12 @@
 build.c
 callback.c
 Changes
+complete.c
 date.c
 dbdimp.c
 dbdimp.h
 delete.c
+earlyexit.pl
 experimental.c
 expr.c
 func.c
@@ -28,6 +30,7 @@
 META.yml			Module meta-data (added by MakeMaker)
 opcodes.c
 opcodes.h
+os.c
 os.h
 os_common.h
 os_test.c
@@ -58,9 +61,11 @@
 t/04select.t
 t/05tran.t
 t/06error.t
+t/07busy.t
 t/08create_function.t
 t/09create_aggregate.t
 t/10dsnlist.t
+t/11unicode.t
 t/20createdrop.t
 t/30insertfetch.t
 t/40bindparam.t

Modified: packages/libdbd-sqlite3-perl/trunk/META.yml
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/META.yml	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/META.yml	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,11 +1,11 @@
 # http://module-build.sourceforge.net/META-spec.html
 #XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
 name:         DBD-SQLite
-version:      1.11
+version:      1.12
 version_from: lib/DBD/SQLite.pm
 installdirs:  site
 requires:
     DBI:                           1.21
 
 distribution_type: module
-generated_by: ExtUtils::MakeMaker version 6.21
+generated_by: ExtUtils::MakeMaker version 6.30

Modified: packages/libdbd-sqlite3-perl/trunk/alter.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/alter.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/alter.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that used to generate VDBE code
 ** that implements the ALTER TABLE command.
 **
-** $Id: alter.c,v 1.8 2005/08/19 19:14:13 drh Exp $
+** $Id: alter.c,v 1.20 2006/02/09 02:56:03 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -47,7 +47,7 @@
 
   int token;
   Token tname;
-  char const *zCsr = zSql;
+  unsigned char const *zCsr = zSql;
   int len = 0;
   char *zRet;
 
@@ -96,7 +96,7 @@
   int token;
   Token tname;
   int dist = 3;
-  char const *zCsr = zSql;
+  unsigned char const *zCsr = zSql;
   int len = 0;
   char *zRet;
 
@@ -162,7 +162,7 @@
   int i;
 
   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
+    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
         SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
   }
 }
@@ -177,9 +177,16 @@
   Trigger *pTrig;
   char *zWhere = 0;
   char *tmp = 0;
-  if( pTab->iDb!=1 ){
+  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
+
+  /* If the table is not located in the temp-db (in which case NULL is 
+  ** returned, loop through the tables list of triggers. For each trigger
+  ** that is not part of the temp-db schema, add a clause to the WHERE 
+  ** expression being built up in zWhere.
+  */
+  if( pTab->pSchema!=pTempSchema ){
     for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
-      if( pTrig->iDb==1 ){
+      if( pTrig->pSchema==pTempSchema ){
         if( !zWhere ){
           zWhere = sqlite3MPrintf("name=%Q", pTrig->name);
         }else{
@@ -204,20 +211,22 @@
 static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
   Vdbe *v;
   char *zWhere;
-  int iDb;
+  int iDb;                   /* Index of database containing pTab */
 #ifndef SQLITE_OMIT_TRIGGER
   Trigger *pTrig;
 #endif
 
   v = sqlite3GetVdbe(pParse);
   if( !v ) return;
-  iDb = pTab->iDb;
+  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+  assert( iDb>=0 );
 
 #ifndef SQLITE_OMIT_TRIGGER
   /* Drop any table triggers from the internal schema. */
   for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
-    assert( pTrig->iDb==iDb || pTrig->iDb==1 );
-    sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0);
+    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
+    assert( iTrigDb==iDb || iTrigDb==1 );
+    sqlite3VdbeOp3(v, OP_DropTrigger, iTrigDb, 0, pTrig->name, 0);
   }
 #endif
 
@@ -233,7 +242,7 @@
   /* Now, if the table is not stored in the temp database, reload any temp 
   ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
   */
-  if( (zWhere=whereTempTriggers(pParse, pTab)) ){
+  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
     sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC);
   }
 #endif
@@ -258,12 +267,12 @@
   char *zWhere = 0;         /* Where clause to locate temp triggers */
 #endif
   
-  if( sqlite3_malloc_failed ) goto exit_rename_table;
+  if( sqlite3MallocFailed() ) goto exit_rename_table;
   assert( pSrc->nSrc==1 );
 
   pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
   if( !pTab ) goto exit_rename_table;
-  iDb = pTab->iDb;
+  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   zDb = db->aDb[iDb].zName;
 
   /* Get a NULL terminated version of the new table name. */
@@ -349,7 +358,7 @@
   ** table. Don't do this if the table being ALTERed is itself located in
   ** the temp database.
   */
-  if( (zWhere=whereTempTriggers(pParse, pTab)) ){
+  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
     sqlite3NestedParse(pParse, 
         "UPDATE sqlite_temp_master SET "
             "sql = sqlite_rename_trigger(sql, %Q), "
@@ -385,13 +394,12 @@
   char *zCol;               /* Null-terminated column definition */
   Column *pCol;             /* The new column */
   Expr *pDflt;              /* Default value for the new column */
-  Vdbe *v;
 
   if( pParse->nErr ) return;
   pNew = pParse->pNewTable;
   assert( pNew );
 
-  iDb = pNew->iDb;
+  iDb = sqlite3SchemaToIndex(pParse->db, pNew->pSchema);
   zDb = pParse->db->aDb[iDb].zName;
   zTab = pNew->zName;
   pCol = &pNew->aCol[pNew->nCol-1];
@@ -399,6 +407,13 @@
   pTab = sqlite3FindTable(pParse->db, zTab, zDb);
   assert( pTab );
 
+#ifndef SQLITE_OMIT_AUTHORIZATION
+  /* Invoke the authorization callback. */
+  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
+    return;
+  }
+#endif
+
   /* If the default value for the new column was specified with a 
   ** literal NULL, then set pDflt to 0. This simplifies checking
   ** for an SQL NULL default below.
@@ -442,7 +457,7 @@
   }
 
   /* Modify the CREATE TABLE statement. */
-  zCol = sqliteStrNDup(pColDef->z, pColDef->n);
+  zCol = sqliteStrNDup((char*)pColDef->z, pColDef->n);
   if( zCol ){
     char *zEnd = &zCol[pColDef->n-1];
     while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
@@ -462,22 +477,12 @@
   ** format to 2. If the default value of the new column is not NULL,
   ** the file format becomes 3.
   */
-  if( (v=sqlite3GetVdbe(pParse)) ){
-    int f = (pDflt?3:2);
+  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
 
-    /* Only set the file format to $f if it is currently less than $f. */
-    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
-    sqlite3VdbeAddOp(v, OP_Integer, f, 0);
-    sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
-    sqlite3VdbeAddOp(v, OP_Integer, f, 0);
-    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
-  }
-
   /* Reload the schema of the modified table. */
   reloadTableSchema(pParse, pTab, pTab->zName);
 }
 
-
 /*
 ** This function is called by the parser after the table-name in
 ** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
@@ -501,10 +506,9 @@
   int i;
   int nAlloc;
 
-
   /* Look up the table being altered. */
   assert( pParse->pNewTable==0 );
-  if( sqlite3_malloc_failed ) goto exit_begin_add_column;
+  if( sqlite3MallocFailed() ) goto exit_begin_add_column;
   pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
   if( !pTab ) goto exit_begin_add_column;
 
@@ -515,7 +519,7 @@
   }
 
   assert( pTab->addColOffset>0 );
-  iDb = pTab->iDb;
+  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
 
   /* Put a copy of the Table struct in Parse.pNewTable for the
   ** sqlite3AddColumn() function and friends to modify.
@@ -537,10 +541,11 @@
   for(i=0; i<pNew->nCol; i++){
     Column *pCol = &pNew->aCol[i];
     pCol->zName = sqliteStrDup(pCol->zName);
+    pCol->zColl = 0;
     pCol->zType = 0;
     pCol->pDflt = 0;
   }
-  pNew->iDb = iDb;
+  pNew->pSchema = pParse->db->aDb[iDb].pSchema;
   pNew->addColOffset = pTab->addColOffset;
   pNew->nRef = 1;
 

Modified: packages/libdbd-sqlite3-perl/trunk/analyze.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/analyze.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/analyze.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code associated with the ANALYZE command.
 **
-** @(#) $Id: analyze.c,v 1.9 2005/09/20 17:42:23 drh Exp $
+** @(#) $Id: analyze.c,v 1.16 2006/01/10 17:58:23 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_ANALYZE
 #include "sqliteInt.h"
@@ -61,8 +61,14 @@
     sqlite3VdbeAddOp(v, OP_Clear, pStat->tnum, iDb);
   }
 
-  /* Open the sqlite_stat1 table for writing.
+  /* Open the sqlite_stat1 table for writing. Unless it was created
+  ** by this vdbe program, lock it for writing at the shared-cache level. 
+  ** If this vdbe did create the sqlite_stat1 table, then it must have 
+  ** already obtained a schema-lock, making the write-lock redundant.
   */
+  if( iRootPage>0 ){
+    sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
+  }
   sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
   sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage);
   sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3);
@@ -86,6 +92,7 @@
   int topOfLoop;   /* The top of the loop */
   int endOfLoop;   /* The end of the loop */
   int addr;        /* The address of an instruction */
+  int iDb;         /* Index of database containing pTab */
 
   v = sqlite3GetVdbe(pParse);
   if( pTab==0 || pTab->pIndex==0 ){
@@ -93,21 +100,29 @@
     return;
   }
 
+  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+  assert( iDb>=0 );
 #ifndef SQLITE_OMIT_AUTHORIZATION
   if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
-      pParse->db->aDb[pTab->iDb].zName ) ){
+      pParse->db->aDb[iDb].zName ) ){
     return;
   }
 #endif
 
+  /* Establish a read-lock on the table at the shared-cache level. */
+  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+
   iIdxCur = pParse->nTab;
   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
+
     /* Open a cursor to the index to be analyzed
     */
-    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+    assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
+    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
     VdbeComment((v, "# %s", pIdx->zName));
     sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum,
-                     (char*)&pIdx->keyInfo, P3_KEYINFO);
+        (char *)pKey, P3_KEYINFO_HANDOFF);
     nCol = pIdx->nColumn;
     if( iMem+nCol*2>=pParse->nMem ){
       pParse->nMem = iMem+nCol*2+1;
@@ -139,7 +154,7 @@
     endOfLoop = sqlite3VdbeMakeLabel(v);
     sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, endOfLoop);
     topOfLoop = sqlite3VdbeCurrentAddr(v);
-    sqlite3VdbeAddOp(v, OP_MemIncr, iMem, 0);
+    sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem);
     for(i=0; i<nCol; i++){
       sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
       sqlite3VdbeAddOp(v, OP_MemLoad, iMem+nCol+i+1, 0);
@@ -147,7 +162,7 @@
     }
     sqlite3VdbeAddOp(v, OP_Goto, 0, endOfLoop);
     for(i=0; i<nCol; i++){
-      addr = sqlite3VdbeAddOp(v, OP_MemIncr, iMem+i+1, 0);
+      addr = sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem+i+1);
       sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
       sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
       sqlite3VdbeAddOp(v, OP_MemStore, iMem+nCol+i+1, 1);
@@ -188,13 +203,14 @@
       sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
       sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
       sqlite3VdbeAddOp(v, OP_Divide, 0, 0);
+      sqlite3VdbeAddOp(v, OP_ToInt, 0, 0);
       if( i==nCol-1 ){
         sqlite3VdbeAddOp(v, OP_Concat, nCol*2-1, 0);
       }else{
         sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
       }
     }
-    sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "ttt", 0);
+    sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0);
     sqlite3VdbeAddOp(v, OP_Insert, iStatCur, 0);
     sqlite3VdbeJumpHere(v, addr);
   }
@@ -214,6 +230,7 @@
 */
 static void analyzeDatabase(Parse *pParse, int iDb){
   sqlite3 *db = pParse->db;
+  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
   HashElem *k;
   int iStatCur;
   int iMem;
@@ -222,7 +239,7 @@
   iStatCur = pParse->nTab++;
   openStatTable(pParse, iDb, iStatCur, 0);
   iMem = pParse->nMem;
-  for(k=sqliteHashFirst(&db->aDb[iDb].tblHash);  k; k=sqliteHashNext(k)){
+  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
     Table *pTab = (Table*)sqliteHashData(k);
     analyzeOneTable(pParse, pTab, iStatCur, iMem);
   }
@@ -238,7 +255,7 @@
   int iStatCur;
 
   assert( pTab!=0 );
-  iDb = pTab->iDb;
+  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   sqlite3BeginWriteOperation(pParse, 0, iDb);
   iStatCur = pParse->nTab++;
   openStatTable(pParse, iDb, iStatCur, pTab->zName);
@@ -360,7 +377,7 @@
   char *zSql;
 
   /* Clear any prior statistics */
-  for(i=sqliteHashFirst(&db->aDb[iDb].idxHash); i; i=sqliteHashNext(i)){
+  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
     Index *pIdx = sqliteHashData(i);
     sqlite3DefaultRowEst(pIdx);
   }

Modified: packages/libdbd-sqlite3-perl/trunk/attach.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/attach.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/attach.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -11,204 +11,350 @@
 *************************************************************************
 ** This file contains code used to implement the ATTACH and DETACH commands.
 **
-** $Id: attach.c,v 1.34 2005/08/20 03:03:04 drh Exp $
+** $Id: attach.c,v 1.50 2006/04/05 11:57:37 drh Exp $
 */
 #include "sqliteInt.h"
 
 /*
-** This routine is called by the parser to process an ATTACH statement:
+** Resolve an expression that was part of an ATTACH or DETACH statement. This
+** is slightly different from resolving a normal SQL expression, because simple
+** identifiers are treated as strings, not possible column names or aliases.
 **
-**     ATTACH DATABASE filename AS dbname
+** i.e. if the parser sees:
 **
-** The pFilename and pDbname arguments are the tokens that define the
-** filename and dbname in the ATTACH statement.
+**     ATTACH DATABASE abc AS def
+**
+** it treats the two expressions as literal strings 'abc' and 'def' instead of
+** looking for columns of the same name.
+**
+** This only applies to the root node of pExpr, so the statement:
+**
+**     ATTACH DATABASE abc||def AS 'db2'
+**
+** will fail because neither abc or def can be resolved.
 */
-void sqlite3Attach(
-  Parse *pParse,       /* The parser context */
-  Token *pFilename,    /* Name of database file */
-  Token *pDbname,      /* Name of the database to use internally */
-  int keyType,         /* 0: no key.  1: TEXT,  2: BLOB */
-  Token *pKey          /* Text of the key for keytype 1 and 2 */
+static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
+{
+  int rc = SQLITE_OK;
+  if( pExpr ){
+    if( pExpr->op!=TK_ID ){
+      rc = sqlite3ExprResolveNames(pName, pExpr);
+    }else{
+      pExpr->op = TK_STRING;
+    }
+  }
+  return rc;
+}
+
+/*
+** An SQL user-function registered to do the work of an ATTACH statement. The
+** three arguments to the function come directly from an attach statement:
+**
+**     ATTACH DATABASE x AS y KEY z
+**
+**     SELECT sqlite_attach(x, y, z)
+**
+** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
+** third argument.
+*/
+static void attachFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
 ){
+  int i;
+  int rc = 0;
+  sqlite3 *db = sqlite3_user_data(context);
+  const char *zName;
+  const char *zFile;
   Db *aNew;
-  int rc, i;
-  char *zFile = 0;
-  char *zName = 0;
-  sqlite3 *db;
-  Vdbe *v;
+  char zErr[128];
+  char *zErrDyn = 0;
 
-  v = sqlite3GetVdbe(pParse);
-  if( !v ) return;
-  sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
-  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
-  if( pParse->explain ) return;
-  db = pParse->db;
+  zFile = (const char *)sqlite3_value_text(argv[0]);
+  zName = (const char *)sqlite3_value_text(argv[1]);
+
+  /* Check for the following errors:
+  **
+  **     * Too many attached databases,
+  **     * Transaction currently open
+  **     * Specified database name already being used.
+  */
   if( db->nDb>=MAX_ATTACHED+2 ){
-    sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
-       MAX_ATTACHED);
-    pParse->rc = SQLITE_ERROR;
-    return;
+    sqlite3_snprintf(
+      127, zErr, "too many attached databases - max %d", MAX_ATTACHED
+    );
+    goto attach_error;
   }
-
   if( !db->autoCommit ){
-    sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction");
-    pParse->rc = SQLITE_ERROR;
-    return;
+    strcpy(zErr, "cannot ATTACH database within transaction");
+    goto attach_error;
   }
-
-  zFile = sqlite3NameFromToken(pFilename);
-  if( zFile==0 ){
-    goto attach_end;
-  }
-#ifndef SQLITE_OMIT_AUTHORIZATION
-  if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
-    goto attach_end;
-  }
-#endif /* SQLITE_OMIT_AUTHORIZATION */
-
-  zName = sqlite3NameFromToken(pDbname);
-  if( zName==0 ){
-    goto attach_end;
-  }
   for(i=0; i<db->nDb; i++){
     char *z = db->aDb[i].zName;
     if( z && sqlite3StrICmp(z, zName)==0 ){
-      sqlite3ErrorMsg(pParse, "database %s is already in use", zName);
-      pParse->rc = SQLITE_ERROR;
-      goto attach_end;
+      sqlite3_snprintf(127, zErr, "database %s is already in use", zName);
+      goto attach_error;
     }
   }
 
+  /* Allocate the new entry in the db->aDb[] array and initialise the schema
+  ** hash tables.
+  */
   if( db->aDb==db->aDbStatic ){
     aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
     if( aNew==0 ){
-      goto attach_end;
+      return;
     }
     memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
   }else{
     aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
     if( aNew==0 ){
-      goto attach_end;
+      return;
     } 
   }
   db->aDb = aNew;
   aNew = &db->aDb[db->nDb++];
   memset(aNew, 0, sizeof(*aNew));
-  sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
-  sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
-  sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
-  sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
-  aNew->zName = zName;
-  zName = 0;
-  aNew->safety_level = 3;
+
+  /* Open the database file. If the btree is successfully opened, use
+  ** it to obtain the database schema. At this point the schema may
+  ** or may not be initialised.
+  */
   rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
-  if( rc ){
-    sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
+  if( rc==SQLITE_OK ){
+    aNew->pSchema = sqlite3SchemaGet(aNew->pBt);
+    if( !aNew->pSchema ){
+      rc = SQLITE_NOMEM;
+    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
+      strcpy(zErr, 
+        "attached databases must use the same text encoding as main database");
+      goto attach_error;
+    }
   }
+  aNew->zName = sqliteStrDup(zName);
+  aNew->safety_level = 3;
+
 #if SQLITE_HAS_CODEC
   {
     extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
+    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+    int nKey;
     char *zKey;
-    int nKey;
-    if( keyType==0 ){
-      /* No key specified.  Use the key from the main database */
-      extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
-      sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
-    }else if( keyType==1 ){
-      /* Key specified as text */
-      zKey = sqlite3NameFromToken(pKey);
-      nKey = strlen(zKey);
-    }else{
-      /* Key specified as a BLOB */
-      char *zTemp;
-      assert( keyType==2 );
-      pKey->z++;
-      pKey->n--;
-      zTemp = sqlite3NameFromToken(pKey);
-      zKey = sqlite3HexToBlob(zTemp);
-      sqliteFree(zTemp);
+    int t = sqlite3_value_type(argv[2]);
+    switch( t ){
+      case SQLITE_INTEGER:
+      case SQLITE_FLOAT:
+        zErrDyn = sqliteStrDup("Invalid key value");
+        rc = SQLITE_ERROR;
+        break;
+        
+      case SQLITE_TEXT:
+      case SQLITE_BLOB:
+        nKey = sqlite3_value_bytes(argv[2]);
+        zKey = (char *)sqlite3_value_blob(argv[2]);
+        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+        break;
+
+      case SQLITE_NULL:
+        /* No key specified.  Use the key from the main database */
+        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+        break;
     }
-    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
-    if( keyType ){
-      sqliteFree(zKey);
-    }
   }
 #endif
-  db->flags &= ~SQLITE_Initialized;
-  if( pParse->nErr==0 && rc==SQLITE_OK ){
-    rc = sqlite3ReadSchema(pParse);
+
+  /* If the file was opened successfully, read the schema for the new database.
+  ** If this fails, or if opening the file failed, then close the file and 
+  ** remove the entry from the db->aDb[] array. i.e. put everything back the way
+  ** we found it.
+  */
+  if( rc==SQLITE_OK ){
+    sqlite3SafetyOn(db);
+    rc = sqlite3Init(db, &zErrDyn);
+    sqlite3SafetyOff(db);
   }
   if( rc ){
-    int i = db->nDb - 1;
-    assert( i>=2 );
-    if( db->aDb[i].pBt ){
-      sqlite3BtreeClose(db->aDb[i].pBt);
-      db->aDb[i].pBt = 0;
+    int iDb = db->nDb - 1;
+    assert( iDb>=2 );
+    if( db->aDb[iDb].pBt ){
+      sqlite3BtreeClose(db->aDb[iDb].pBt);
+      db->aDb[iDb].pBt = 0;
+      db->aDb[iDb].pSchema = 0;
     }
     sqlite3ResetInternalSchema(db, 0);
-    assert( pParse->nErr>0 );  /* Always set by sqlite3ReadSchema() */
-    if( pParse->rc==SQLITE_OK ){
-      pParse->rc = SQLITE_ERROR;
+    db->nDb = iDb;
+    if( rc==SQLITE_NOMEM ){
+      sqlite3MallocFailed();
+      sqlite3_snprintf(127, zErr, "out of memory");
+    }else{
+      sqlite3_snprintf(127, zErr, "unable to open database: %s", zFile);
     }
+    goto attach_error;
   }
+  
+  return;
 
-attach_end:
-  sqliteFree(zFile);
-  sqliteFree(zName);
+attach_error:
+  /* Return an error if we get here */
+  if( zErrDyn ){
+    sqlite3_result_error(context, zErrDyn, -1);
+    sqliteFree(zErrDyn);
+  }else{
+    zErr[sizeof(zErr)-1] = 0;
+    sqlite3_result_error(context, zErr, -1);
+  }
 }
 
 /*
-** This routine is called by the parser to process a DETACH statement:
+** An SQL user-function registered to do the work of an DETACH statement. The
+** three arguments to the function come directly from a detach statement:
 **
-**    DETACH DATABASE dbname
+**     DETACH DATABASE x
 **
-** The pDbname argument is the name of the database in the DETACH statement.
+**     SELECT sqlite_detach(x)
 */
-void sqlite3Detach(Parse *pParse, Token *pDbname){
+static void detachFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  const char *zName = (const char *)sqlite3_value_text(argv[0]);
+  sqlite3 *db = sqlite3_user_data(context);
   int i;
-  sqlite3 *db;
-  Vdbe *v;
   Db *pDb = 0;
-  char *zName;
+  char zErr[128];
 
-  v = sqlite3GetVdbe(pParse);
-  if( !v ) return;
-  sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
-  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
-  if( pParse->explain ) return;
-  db = pParse->db;
-  zName = sqlite3NameFromToken(pDbname);
-  if( zName==0 ) return;
+  assert(zName);
   for(i=0; i<db->nDb; i++){
     pDb = &db->aDb[i];
     if( pDb->pBt==0 ) continue;
     if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
   }
+
   if( i>=db->nDb ){
-    sqlite3ErrorMsg(pParse, "no such database: %z", zName);
-    return;
+    sqlite3_snprintf(sizeof(zErr), zErr, "no such database: %s", zName);
+    goto detach_error;
   }
   if( i<2 ){
-    sqlite3ErrorMsg(pParse, "cannot detach database %z", zName);
-    return;
+    sqlite3_snprintf(sizeof(zErr), zErr, "cannot detach database %s", zName);
+    goto detach_error;
   }
-  sqliteFree(zName);
   if( !db->autoCommit ){
-    sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction");
-    pParse->rc = SQLITE_ERROR;
-    return;
+    strcpy(zErr, "cannot DETACH database within transaction");
+    goto detach_error;
   }
-#ifndef SQLITE_OMIT_AUTHORIZATION
-  if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
-    return;
-  }
-#endif /* SQLITE_OMIT_AUTHORIZATION */
+
   sqlite3BtreeClose(pDb->pBt);
   pDb->pBt = 0;
+  pDb->pSchema = 0;
   sqlite3ResetInternalSchema(db, 0);
+  return;
+
+detach_error:
+  sqlite3_result_error(context, zErr, -1);
 }
 
 /*
+** This procedure generates VDBE code for a single invocation of either the
+** sqlite_detach() or sqlite_attach() SQL user functions.
+*/
+static void codeAttach(
+  Parse *pParse,       /* The parser context */
+  int type,            /* Either SQLITE_ATTACH or SQLITE_DETACH */
+  const char *zFunc,   /* Either "sqlite_attach" or "sqlite_detach */
+  int nFunc,           /* Number of args to pass to zFunc */
+  Expr *pAuthArg,      /* Expression to pass to authorization callback */
+  Expr *pFilename,     /* Name of database file */
+  Expr *pDbname,       /* Name of the database to use internally */
+  Expr *pKey           /* Database key for encryption extension */
+){
+  int rc;
+  NameContext sName;
+  Vdbe *v;
+  FuncDef *pFunc;
+  sqlite3* db = pParse->db;
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+  assert( sqlite3MallocFailed() || pAuthArg );
+  if( pAuthArg ){
+    char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span);
+    if( !zAuthArg ){
+      goto attach_end;
+    }
+    rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
+    sqliteFree(zAuthArg);
+    if(rc!=SQLITE_OK ){
+      goto attach_end;
+    }
+  }
+#endif /* SQLITE_OMIT_AUTHORIZATION */
+
+  memset(&sName, 0, sizeof(NameContext));
+  sName.pParse = pParse;
+
+  if( 
+      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
+      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
+      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
+  ){
+    pParse->nErr++;
+    goto attach_end;
+  }
+
+  v = sqlite3GetVdbe(pParse);
+  sqlite3ExprCode(pParse, pFilename);
+  sqlite3ExprCode(pParse, pDbname);
+  sqlite3ExprCode(pParse, pKey);
+
+  assert( v || sqlite3MallocFailed() );
+  if( v ){
+    sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
+    pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
+    sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);
+
+    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
+    ** statement only). For DETACH, set it to false (expire all existing
+    ** statements).
+    */
+    sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
+  }
+  
+attach_end:
+  sqlite3ExprDelete(pFilename);
+  sqlite3ExprDelete(pDbname);
+  sqlite3ExprDelete(pKey);
+}
+
+/*
+** Called by the parser to compile a DETACH statement.
+**
+**     DETACH pDbname
+*/
+void sqlite3Detach(Parse *pParse, Expr *pDbname){
+  codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname);
+}
+
+/*
+** Called by the parser to compile an ATTACH statement.
+**
+**     ATTACH p AS pDbname KEY pKey
+*/
+void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
+  codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);
+}
+
+/*
+** Register the functions sqlite_attach and sqlite_detach.
+*/
+void sqlite3AttachFunctions(sqlite3 *db){
+  static const int enc = SQLITE_UTF8;
+  sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0);
+  sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0);
+}
+
+/*
 ** Initialize a DbFixer structure.  This routine must be called prior
 ** to passing the structure to one of the sqliteFixAAAA() routines below.
 **

Modified: packages/libdbd-sqlite3-perl/trunk/auth.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/auth.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/auth.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -14,7 +14,7 @@
 ** systems that do not need this facility may omit it by recompiling
 ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
 **
-** $Id: auth.c,v 1.22 2005/07/29 15:36:15 drh Exp $
+** $Id: auth.c,v 1.24 2006/01/13 13:55:45 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -112,10 +112,17 @@
   int iSrc;             /* Index in pTabList->a[] of table being read */
   const char *zDBase;   /* Name of database being accessed */
   TriggerStack *pStack; /* The stack of current triggers */
+  int iDb;              /* The index of the database the expression refers to */
 
   if( db->xAuth==0 ) return;
   if( pExpr->op==TK_AS ) return;
   assert( pExpr->op==TK_COLUMN );
+  iDb = sqlite3SchemaToIndex(pParse->db, pExpr->pSchema);
+  if( iDb<0 ){
+    /* An attempt to read a column out of a subquery or other
+    ** temporary table. */
+    return;
+  }
   for(iSrc=0; pTabList && iSrc<pTabList->nSrc; iSrc++){
     if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
   }
@@ -140,14 +147,14 @@
   }else{
     zCol = "ROWID";
   }
-  assert( pExpr->iDb<db->nDb );
-  zDBase = db->aDb[pExpr->iDb].zName;
+  assert( iDb>=0 && iDb<db->nDb );
+  zDBase = db->aDb[iDb].zName;
   rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, 
                  pParse->zAuthContext);
   if( rc==SQLITE_IGNORE ){
     pExpr->op = TK_NULL;
   }else if( rc==SQLITE_DENY ){
-    if( db->nDb>2 || pExpr->iDb!=0 ){
+    if( db->nDb>2 || iDb!=0 ){
       sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", 
          zDBase, pTab->zName, zCol);
     }else{

Modified: packages/libdbd-sqlite3-perl/trunk/btree.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/btree.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/btree.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.269 2005/09/17 15:20:27 drh Exp $
+** $Id: btree.c,v 1.324 2006/04/04 01:54:55 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -230,6 +230,7 @@
 
 /* Forward declarations */
 typedef struct MemPage MemPage;
+typedef struct BtLock BtLock;
 
 /*
 ** This is a magic string that appears at the beginning of every
@@ -285,10 +286,10 @@
   u16 nFree;           /* Number of free bytes on the page */
   u16 nCell;           /* Number of cells on this page, local and ovfl */
   struct _OvflCell {   /* Cells that will not fit on aData[] */
-    u8 *pCell;           /* Pointers to the body of the overflow cell */
-    u16 idx;             /* Insert this cell before idx-th non-overflow cell */
+    u8 *pCell;          /* Pointers to the body of the overflow cell */
+    u16 idx;            /* Insert this cell before idx-th non-overflow cell */
   } aOvfl[5];
-  struct Btree *pBt;   /* Pointer back to BTree structure */
+  BtShared *pBt;       /* Pointer back to BTree structure */
   u8 *aData;           /* Pointer back to the start of the page */
   Pgno pgno;           /* Page number for this page */
   MemPage *pParent;    /* The parent of this page.  NULL for root */
@@ -301,14 +302,32 @@
 */
 #define EXTRA_SIZE sizeof(MemPage)
 
+/* Btree handle */
+struct Btree {
+  sqlite3 *pSqlite;
+  BtShared *pBt;
+  u8 inTrans;            /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
+};
+
 /*
+** Btree.inTrans may take one of the following values.
+**
+** If the shared-data extension is enabled, there may be multiple users
+** of the Btree structure. At most one of these may open a write transaction,
+** but any number may have active read transactions. Variable Btree.pDb 
+** points to the handle that owns any current write-transaction.
+*/
+#define TRANS_NONE  0
+#define TRANS_READ  1
+#define TRANS_WRITE 2
+
+/*
 ** Everything we need to know about an open database
 */
-struct Btree {
+struct BtShared {
   Pager *pPager;        /* The page cache */
   BtCursor *pCursor;    /* A list of all open cursors */
   MemPage *pPage1;      /* First page of the database */
-  u8 inTrans;           /* True if a transaction is in progress */
   u8 inStmt;            /* True if we are in a statement subtransaction */
   u8 readOnly;          /* True if the underlying file is readonly */
   u8 maxEmbedFrac;      /* Maximum payload as % of total page size */
@@ -325,17 +344,18 @@
   int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
   int minLeaf;          /* Minimum local payload in a LEAFDATA table */
   BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
+  u8 inTransaction;     /* Transaction state */
+  int nRef;             /* Number of references to this structure */
+  int nTransaction;     /* Number of open transactions (read + write) */
+  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
+  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  BtLock *pLock;        /* List of locks held on this shared-btree struct */
+  BtShared *pNext;      /* Next in ThreadData.pBtree linked list */
+#endif
 };
-typedef Btree Bt;
 
 /*
-** Btree.inTrans may take one of the following values.
-*/
-#define TRANS_NONE  0
-#define TRANS_READ  1
-#define TRANS_WRITE 2
-
-/*
 ** An instance of the following structure is used to hold information
 ** about a cell.  The parseCellPtr() function fills in this structure
 ** based on information extract from the raw disk page.
@@ -357,7 +377,7 @@
 ** MemPage.aCell[] of the entry.
 */
 struct BtCursor {
-  Btree *pBt;               /* The Btree to which this cursor belongs */
+  Btree *pBtree;            /* The Btree to which this cursor belongs */
   BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
   int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */
   void *pArg;               /* First arg to xCompare() */
@@ -366,10 +386,39 @@
   int idx;                  /* Index of the entry in pPage->aCell[] */
   CellInfo info;            /* A parse of the cell we are pointing at */
   u8 wrFlag;                /* True if writable */
-  u8 isValid;               /* TRUE if points to a valid entry */
+  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  void *pKey;      /* Saved key that was cursor's last known position */
+  i64 nKey;        /* Size of pKey, or last integer key */
+  int skip;        /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */
+#endif
 };
 
 /*
+** Potential values for BtCursor.eState. The first two values (VALID and 
+** INVALID) may occur in any build. The third (REQUIRESEEK) may only occur 
+** if sqlite was compiled without the OMIT_SHARED_CACHE symbol defined.
+**
+** CURSOR_VALID:
+**   Cursor points to a valid entry. getPayload() etc. may be called.
+**
+** CURSOR_INVALID:
+**   Cursor does not point to a valid entry. This can happen (for example) 
+**   because the table is empty or because BtreeCursorFirst() has not been
+**   called.
+**
+** CURSOR_REQUIRESEEK:
+**   The table that this cursor was opened on still exists, but has been 
+**   modified since the cursor was last used. The cursor position is saved
+**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
+**   this state, restoreOrClearCursorPosition() can be called to attempt to
+**   seek the cursor to the saved position.
+*/
+#define CURSOR_INVALID           0
+#define CURSOR_VALID             1
+#define CURSOR_REQUIRESEEK       2
+
+/*
 ** The TRACE macro will print high-level status information about the
 ** btree operation when the global variable sqlite3_btree_trace is
 ** enabled.
@@ -385,7 +434,7 @@
 /*
 ** Forward declaration
 */
-static int checkReadLocks(Btree*,Pgno,BtCursor*);
+static int checkReadLocks(BtShared*,Pgno,BtCursor*);
 
 /*
 ** Read or write a two- and four-byte big-endian integer values.
@@ -413,15 +462,291 @@
 ** file.
 */
 #define getVarint    sqlite3GetVarint
-#define getVarint32  sqlite3GetVarint32
+/* #define getVarint32  sqlite3GetVarint32 */
+#define getVarint32(A,B)  ((*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B))
 #define putVarint    sqlite3PutVarint
 
 /* The database page the PENDING_BYTE occupies. This page is never used.
 ** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
 ** should possibly be consolidated (presumably in pager.h).
+**
+** If disk I/O is omitted (meaning that the database is stored purely
+** in memory) then there is no pending byte.
 */
-#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)
+#ifdef SQLITE_OMIT_DISKIO
+# define PENDING_BYTE_PAGE(pBt)  0x7fffffff
+#else
+# define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)
+#endif
 
+/*
+** A linked list of the following structures is stored at BtShared.pLock.
+** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
+** is opened on the table with root page BtShared.iTable. Locks are removed
+** from this list when a transaction is committed or rolled back, or when
+** a btree handle is closed.
+*/
+struct BtLock {
+  Btree *pBtree;        /* Btree handle holding this lock */
+  Pgno iTable;          /* Root page of table */
+  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
+  BtLock *pNext;        /* Next in BtShared.pLock list */
+};
+
+/* Candidate values for BtLock.eLock */
+#define READ_LOCK     1
+#define WRITE_LOCK    2
+
+#ifdef SQLITE_OMIT_SHARED_CACHE
+  /*
+  ** The functions queryTableLock(), lockTable() and unlockAllTables()
+  ** manipulate entries in the BtShared.pLock linked list used to store
+  ** shared-cache table level locks. If the library is compiled with the
+  ** shared-cache feature disabled, then there is only ever one user
+  ** of each BtShared structure and so this locking is not necessary. 
+  ** So define the lock related functions as no-ops.
+  */
+  #define queryTableLock(a,b,c) SQLITE_OK
+  #define lockTable(a,b,c) SQLITE_OK
+  #define unlockAllTables(a)
+  #define restoreOrClearCursorPosition(a,b) SQLITE_OK
+  #define saveAllCursors(a,b,c) SQLITE_OK
+
+#else
+
+static void releasePage(MemPage *pPage);
+
+/*
+** Save the current cursor position in the variables BtCursor.nKey 
+** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
+*/
+static int saveCursorPosition(BtCursor *pCur){
+  int rc;
+
+  assert( CURSOR_VALID==pCur->eState );
+  assert( 0==pCur->pKey );
+
+  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
+
+  /* If this is an intKey table, then the above call to BtreeKeySize()
+  ** stores the integer key in pCur->nKey. In this case this value is
+  ** all that is required. Otherwise, if pCur is not open on an intKey
+  ** table, then malloc space for and store the pCur->nKey bytes of key 
+  ** data.
+  */
+  if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
+    void *pKey = sqliteMalloc(pCur->nKey);
+    if( pKey ){
+      rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
+      if( rc==SQLITE_OK ){
+        pCur->pKey = pKey;
+      }else{
+        sqliteFree(pKey);
+      }
+    }else{
+      rc = SQLITE_NOMEM;
+    }
+  }
+  assert( !pCur->pPage->intKey || !pCur->pKey );
+
+  if( rc==SQLITE_OK ){
+    releasePage(pCur->pPage);
+    pCur->pPage = 0;
+    pCur->eState = CURSOR_REQUIRESEEK;
+  }
+
+  return rc;
+}
+
+/*
+** Save the positions of all cursors except pExcept open on the table 
+** with root-page iRoot. Usually, this is called just before cursor
+** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
+*/
+static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
+  BtCursor *p;
+  if( sqlite3ThreadDataReadOnly()->useSharedData ){
+    for(p=pBt->pCursor; p; p=p->pNext){
+      if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && 
+          p->eState==CURSOR_VALID ){
+        int rc = saveCursorPosition(p);
+        if( SQLITE_OK!=rc ){
+          return rc;
+        }
+      }
+    }
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Restore the cursor to the position it was in (or as close to as possible)
+** when saveCursorPosition() was called. Note that this call deletes the 
+** saved position info stored by saveCursorPosition(), so there can be
+** at most one effective restoreOrClearCursorPosition() call after each 
+** saveCursorPosition().
+**
+** If the second argument argument - doSeek - is false, then instead of 
+** returning the cursor to it's saved position, any saved position is deleted
+** and the cursor state set to CURSOR_INVALID.
+*/
+static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
+  int rc = SQLITE_OK;
+  assert( sqlite3ThreadDataReadOnly()->useSharedData );
+  assert( pCur->eState==CURSOR_REQUIRESEEK );
+  pCur->eState = CURSOR_INVALID;
+  if( doSeek ){
+    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
+  }
+  if( rc==SQLITE_OK ){
+    sqliteFree(pCur->pKey);
+    pCur->pKey = 0;
+    assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
+  }
+  return rc;
+}
+
+#define restoreOrClearCursorPosition(p,x) \
+  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
+
+/*
+** Query to see if btree handle p may obtain a lock of type eLock 
+** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
+** SQLITE_OK if the lock may be obtained (by calling lockTable()), or
+** SQLITE_LOCKED if not.
+*/
+static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
+  BtShared *pBt = p->pBt;
+  BtLock *pIter;
+
+  /* This is a no-op if the shared-cache is not enabled */
+  if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){
+    return SQLITE_OK;
+  }
+
+  /* This (along with lockTable()) is where the ReadUncommitted flag is
+  ** dealt with. If the caller is querying for a read-lock and the flag is
+  ** set, it is unconditionally granted - even if there are write-locks
+  ** on the table. If a write-lock is requested, the ReadUncommitted flag
+  ** is not considered.
+  **
+  ** In function lockTable(), if a read-lock is demanded and the 
+  ** ReadUncommitted flag is set, no entry is added to the locks list 
+  ** (BtShared.pLock).
+  **
+  ** To summarize: If the ReadUncommitted flag is set, then read cursors do
+  ** not create or respect table locks. The locking procedure for a 
+  ** write-cursor does not change.
+  */
+  if( 
+    !p->pSqlite || 
+    0==(p->pSqlite->flags&SQLITE_ReadUncommitted) || 
+    eLock==WRITE_LOCK ||
+    iTab==MASTER_ROOT
+  ){
+    for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
+      if( pIter->pBtree!=p && pIter->iTable==iTab && 
+          (pIter->eLock!=eLock || eLock!=READ_LOCK) ){
+        return SQLITE_LOCKED;
+      }
+    }
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Add a lock on the table with root-page iTable to the shared-btree used
+** by Btree handle p. Parameter eLock must be either READ_LOCK or 
+** WRITE_LOCK.
+**
+** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and
+** SQLITE_NOMEM may also be returned.
+*/
+static int lockTable(Btree *p, Pgno iTable, u8 eLock){
+  BtShared *pBt = p->pBt;
+  BtLock *pLock = 0;
+  BtLock *pIter;
+
+  /* This is a no-op if the shared-cache is not enabled */
+  if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){
+    return SQLITE_OK;
+  }
+
+  assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );
+
+  /* If the read-uncommitted flag is set and a read-lock is requested,
+  ** return early without adding an entry to the BtShared.pLock list. See
+  ** comment in function queryTableLock() for more info on handling 
+  ** the ReadUncommitted flag.
+  */
+  if( 
+    (p->pSqlite) && 
+    (p->pSqlite->flags&SQLITE_ReadUncommitted) && 
+    (eLock==READ_LOCK) &&
+    iTable!=MASTER_ROOT
+  ){
+    return SQLITE_OK;
+  }
+
+  /* First search the list for an existing lock on this table. */
+  for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
+    if( pIter->iTable==iTable && pIter->pBtree==p ){
+      pLock = pIter;
+      break;
+    }
+  }
+
+  /* If the above search did not find a BtLock struct associating Btree p
+  ** with table iTable, allocate one and link it into the list.
+  */
+  if( !pLock ){
+    pLock = (BtLock *)sqliteMalloc(sizeof(BtLock));
+    if( !pLock ){
+      return SQLITE_NOMEM;
+    }
+    pLock->iTable = iTable;
+    pLock->pBtree = p;
+    pLock->pNext = pBt->pLock;
+    pBt->pLock = pLock;
+  }
+
+  /* Set the BtLock.eLock variable to the maximum of the current lock
+  ** and the requested lock. This means if a write-lock was already held
+  ** and a read-lock requested, we don't incorrectly downgrade the lock.
+  */
+  assert( WRITE_LOCK>READ_LOCK );
+  if( eLock>pLock->eLock ){
+    pLock->eLock = eLock;
+  }
+
+  return SQLITE_OK;
+}
+
+/*
+** Release all the table locks (locks obtained via calls to the lockTable()
+** procedure) held by Btree handle p.
+*/
+static void unlockAllTables(Btree *p){
+  BtLock **ppIter = &p->pBt->pLock;
+
+  /* If the shared-cache extension is not enabled, there should be no
+  ** locks in the BtShared.pLock list, making this procedure a no-op. Assert
+  ** that this is the case.
+  */
+  assert( sqlite3ThreadDataReadOnly()->useSharedData || 0==*ppIter );
+
+  while( *ppIter ){
+    BtLock *pLock = *ppIter;
+    if( pLock->pBtree==p ){
+      *ppIter = pLock->pNext;
+      sqliteFree(pLock);
+    }else{
+      ppIter = &pLock->pNext;
+    }
+  }
+}
+#endif /* SQLITE_OMIT_SHARED_CACHE */
+
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
 ** These macros define the location of the pointer-map entry for a 
@@ -438,10 +763,20 @@
 ** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
 ** this test.
 */
-#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2)
-#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5)
-#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno)
+#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
+#define PTRMAP_PTROFFSET(pBt, pgno) (5*(pgno-ptrmapPageno(pBt, pgno)-1))
+#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
 
+static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
+  int nPagesPerMapPage = (pBt->usableSize/5)+1;
+  int iPtrMap = (pgno-2)/nPagesPerMapPage;
+  int ret = (iPtrMap*nPagesPerMapPage) + 2; 
+  if( ret==PENDING_BYTE_PAGE(pBt) ){
+    ret++;
+  }
+  return ret;
+}
+
 /*
 ** The pointer map is a lookup table that identifies the parent page for
 ** each child page in the database file.  The parent page is the page that
@@ -486,22 +821,25 @@
 ** so that it maps to type 'eType' and parent page number 'pgno'.
 ** An error code is returned if something goes wrong, otherwise SQLITE_OK.
 */
-static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){
+static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
   u8 *pPtrmap;    /* The pointer map page */
   Pgno iPtrmap;   /* The pointer map page number */
   int offset;     /* Offset in pointer map page */
   int rc;
 
+  /* The master-journal page number must never be used as a pointer map page */
+  assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );
+
   assert( pBt->autoVacuum );
   if( key==0 ){
     return SQLITE_CORRUPT_BKPT;
   }
-  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+  iPtrmap = PTRMAP_PAGENO(pBt, key);
   rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
   if( rc!=SQLITE_OK ){
     return rc;
   }
-  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
+  offset = PTRMAP_PTROFFSET(pBt, key);
 
   if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
     TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
@@ -523,20 +861,21 @@
 ** the type and parent page number to *pEType and *pPgno respectively.
 ** An error code is returned if something goes wrong, otherwise SQLITE_OK.
 */
-static int ptrmapGet(Btree *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
+static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
   int iPtrmap;       /* Pointer map page index */
   u8 *pPtrmap;       /* Pointer map page data */
   int offset;        /* Offset of entry in pointer map */
   int rc;
 
-  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+  iPtrmap = PTRMAP_PAGENO(pBt, key);
   rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
   if( rc!=0 ){
     return rc;
   }
 
-  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
-  if( pEType ) *pEType = pPtrmap[offset];
+  offset = PTRMAP_PTROFFSET(pBt, key);
+  assert( pEType!=0 );
+  *pEType = pPtrmap[offset];
   if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
 
   sqlite3pager_unref(pPtrmap);
@@ -604,12 +943,16 @@
   }else{
     nPayload = 0;
   }
-  n += getVarint(&pCell[n], (u64 *)&pInfo->nKey);
-  pInfo->nHeader = n;
   pInfo->nData = nPayload;
-  if( !pPage->intKey ){
-    nPayload += pInfo->nKey;
+  if( pPage->intKey ){
+    n += getVarint(&pCell[n], (u64 *)&pInfo->nKey);
+  }else{
+    u32 x;
+    n += getVarint32(&pCell[n], &x);
+    pInfo->nKey = x;
+    nPayload += x;
   }
+  pInfo->nHeader = n;
   if( nPayload<=pPage->maxLocal ){
     /* This is the (easy) common case where the entire payload fits
     ** on the local page.  No overflow is required.
@@ -790,10 +1133,20 @@
 # define pageIntegrity(X)
 #endif
 
+/* A bunch of assert() statements to check the transaction state variables
+** of handle p (type Btree*) are internally consistent.
+*/
+#define btreeIntegrity(p) \
+  assert( p->inTrans!=TRANS_NONE || p->pBt->nTransaction<p->pBt->nRef ); \
+  assert( p->pBt->nTransaction<=p->pBt->nRef ); \
+  assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
+  assert( p->pBt->inTransaction>=p->inTrans ); 
+
 /*
 ** Defragment the page given.  All Cells are moved to the
-** beginning of the page and all free space is collected 
-** into one big FreeBlk at the end of the page.
+** end of the page and all free space is collected into one
+** big FreeBlk that occurs in between the header and cell
+** pointer array and the cell content area.
 */
 static int defragmentPage(MemPage *pPage){
   int i;                     /* Loop counter */
@@ -928,6 +1281,12 @@
   assert( (start + size)<=pPage->pBt->usableSize );
   if( size<4 ) size = 4;
 
+#ifdef SQLITE_SECURE_DELETE
+  /* Overwrite deleted information with zeros when the SECURE_DELETE 
+  ** option is enabled at compile-time */
+  memset(&data[start], 0, size);
+#endif
+
   /* Add the space back into the linked list of freeblocks */
   hdr = pPage->hdrOffset;
   addr = hdr + 1;
@@ -977,7 +1336,7 @@
 ** and initialize fields of the MemPage structure accordingly.
 */
 static void decodeFlags(MemPage *pPage, int flagByte){
-  Btree *pBt;     /* A copy of pPage->pBt */
+  BtShared *pBt;     /* A copy of pPage->pBt */
 
   assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
   pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
@@ -1017,7 +1376,7 @@
   int pc;            /* Address of a freeblock within pPage->aData[] */
   int hdr;           /* Offset to beginning of page header */
   u8 *data;          /* Equal to pPage->aData */
-  Btree *pBt;        /* The main btree structure */
+  BtShared *pBt;        /* The main btree structure */
   int usableSize;    /* Amount of usable space on each page */
   int cellOffset;    /* Offset from start of page to first cell pointer */
   int nFree;         /* Number of unused bytes on the page */
@@ -1090,7 +1449,7 @@
 */
 static void zeroPage(MemPage *pPage, int flags){
   unsigned char *data = pPage->aData;
-  Btree *pBt = pPage->pBt;
+  BtShared *pBt = pPage->pBt;
   int hdr = pPage->hdrOffset;
   int first;
 
@@ -1118,7 +1477,7 @@
 ** Get a page from the pager.  Initialize the MemPage.pBt and
 ** MemPage.aData elements if needed.
 */
-static int getPage(Btree *pBt, Pgno pgno, MemPage **ppPage){
+static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage){
   int rc;
   unsigned char *aData;
   MemPage *pPage;
@@ -1139,7 +1498,7 @@
 ** getPage() and initPage().
 */
 static int getAndInitPage(
-  Btree *pBt,          /* The database file */
+  BtShared *pBt,          /* The database file */
   Pgno pgno,           /* Number of the page to get */
   MemPage **ppPage,    /* Write the page pointer here */
   MemPage *pParent     /* Parent of the page */
@@ -1212,21 +1571,69 @@
 */
 int sqlite3BtreeOpen(
   const char *zFilename,  /* Name of the file containing the BTree database */
+  sqlite3 *pSqlite,       /* Associated database handle */
   Btree **ppBtree,        /* Pointer to new Btree object written here */
   int flags               /* Options */
 ){
-  Btree *pBt;
+  BtShared *pBt;          /* Shared part of btree structure */
+  Btree *p;               /* Handle to return */
   int rc;
   int nReserve;
   unsigned char zDbHeader[100];
+#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
+  const ThreadData *pTsdro;
+#endif
 
+  /* Set the variable isMemdb to true for an in-memory database, or 
+  ** false for a file-based database. This symbol is only required if
+  ** either of the shared-data or autovacuum features are compiled 
+  ** into the library.
+  */
+#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
+  #ifdef SQLITE_OMIT_MEMORYDB
+  const int isMemdb = !zFilename;
+  #else
+  const int isMemdb = !zFilename || (strcmp(zFilename, ":memory:")?0:1);
+  #endif
+#endif
+
+  p = sqliteMalloc(sizeof(Btree));
+  if( !p ){
+    return SQLITE_NOMEM;
+  }
+  p->inTrans = TRANS_NONE;
+  p->pSqlite = pSqlite;
+
+  /* Try to find an existing Btree structure opened on zFilename. */
+#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
+  pTsdro = sqlite3ThreadDataReadOnly();
+  if( pTsdro->useSharedData && zFilename && !isMemdb ){
+    char *zFullPathname = sqlite3OsFullPathname(zFilename);
+    if( !zFullPathname ){
+      sqliteFree(p);
+      return SQLITE_NOMEM;
+    }
+    for(pBt=pTsdro->pBtree; pBt; pBt=pBt->pNext){
+      assert( pBt->nRef>0 );
+      if( 0==strcmp(zFullPathname, sqlite3pager_filename(pBt->pPager)) ){
+        p->pBt = pBt;
+        *ppBtree = p;
+        pBt->nRef++;
+        sqliteFree(zFullPathname);
+        return SQLITE_OK;
+      }
+    }
+    sqliteFree(zFullPathname);
+  }
+#endif
+
   /*
   ** The following asserts make sure that structures used by the btree are
   ** the right size.  This is to guard against size changes that result
   ** when compiling on a different architecture.
   */
-  assert( sizeof(i64)==8 );
-  assert( sizeof(u64)==8 );
+  assert( sizeof(i64)==8 || sizeof(i64)==4 );
+  assert( sizeof(u64)==8 || sizeof(u64)==4 );
   assert( sizeof(u32)==4 );
   assert( sizeof(u16)==2 );
   assert( sizeof(Pgno)==4 );
@@ -1234,15 +1641,19 @@
   pBt = sqliteMalloc( sizeof(*pBt) );
   if( pBt==0 ){
     *ppBtree = 0;
+    sqliteFree(p);
     return SQLITE_NOMEM;
   }
   rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
   if( rc!=SQLITE_OK ){
     if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
     sqliteFree(pBt);
+    sqliteFree(p);
     *ppBtree = 0;
     return rc;
   }
+  p->pBt = pBt;
+
   sqlite3pager_set_destructor(pBt->pPager, pageDestructor);
   sqlite3pager_set_reiniter(pBt->pPager, pageReinit);
   pBt->pCursor = 0;
@@ -1263,11 +1674,7 @@
     ** then ":memory:" is just a regular file-name. Respect the auto-vacuum
     ** default in this case.
     */
-#ifndef SQLITE_OMIT_MEMORYDB
-    if( zFilename && strcmp(zFilename,":memory:") ){
-#else
-    if( zFilename ){
-#endif
+    if( zFilename && !isMemdb ){
       pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM;
     }
 #endif
@@ -1285,18 +1692,87 @@
   pBt->usableSize = pBt->pageSize - nReserve;
   assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
   sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
-  *ppBtree = pBt;
+
+#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
+  /* Add the new btree to the linked list starting at ThreadData.pBtree.
+  ** There is no chance that a malloc() may fail inside of the 
+  ** sqlite3ThreadData() call, as the ThreadData structure must have already
+  ** been allocated for pTsdro->useSharedData to be non-zero.
+  */
+  if( pTsdro->useSharedData && zFilename && !isMemdb ){
+    pBt->pNext = pTsdro->pBtree;
+    sqlite3ThreadData()->pBtree = pBt;
+  }
+#endif
+  pBt->nRef = 1;
+  *ppBtree = p;
   return SQLITE_OK;
 }
 
 /*
 ** Close an open database and invalidate all cursors.
 */
-int sqlite3BtreeClose(Btree *pBt){
-  while( pBt->pCursor ){
-    sqlite3BtreeCloseCursor(pBt->pCursor);
+int sqlite3BtreeClose(Btree *p){
+  BtShared *pBt = p->pBt;
+  BtCursor *pCur;
+
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  ThreadData *pTsd;
+#endif
+
+  /* Close all cursors opened via this handle.  */
+  pCur = pBt->pCursor;
+  while( pCur ){
+    BtCursor *pTmp = pCur;
+    pCur = pCur->pNext;
+    if( pTmp->pBtree==p ){
+      sqlite3BtreeCloseCursor(pTmp);
+    }
   }
+
+  /* Rollback any active transaction and free the handle structure.
+  ** The call to sqlite3BtreeRollback() drops any table-locks held by
+  ** this handle.
+  */
+  sqlite3BtreeRollback(p);
+  sqliteFree(p);
+
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  /* If there are still other outstanding references to the shared-btree
+  ** structure, return now. The remainder of this procedure cleans 
+  ** up the shared-btree.
+  */
+  assert( pBt->nRef>0 );
+  pBt->nRef--;
+  if( pBt->nRef ){
+    return SQLITE_OK;
+  }
+
+  /* Remove the shared-btree from the thread wide list. Call 
+  ** ThreadDataReadOnly() and then cast away the const property of the 
+  ** pointer to avoid allocating thread data if it is not really required.
+  */
+  pTsd = (ThreadData *)sqlite3ThreadDataReadOnly();
+  if( pTsd->pBtree==pBt ){
+    assert( pTsd==sqlite3ThreadData() );
+    pTsd->pBtree = pBt->pNext;
+  }else{
+    BtShared *pPrev;
+    for(pPrev=pTsd->pBtree; pPrev && pPrev->pNext!=pBt; pPrev=pPrev->pNext){}
+    if( pPrev ){
+      assert( pTsd==sqlite3ThreadData() );
+      pPrev->pNext = pBt->pNext;
+    }
+  }
+#endif
+
+  /* Close the pager and free the shared-btree structure */
+  assert( !pBt->pCursor );
   sqlite3pager_close(pBt->pPager);
+  if( pBt->xFreeSchema && pBt->pSchema ){
+    pBt->xFreeSchema(pBt->pSchema);
+  }
+  sqliteFree(pBt->pSchema);
   sqliteFree(pBt);
   return SQLITE_OK;
 }
@@ -1304,7 +1780,8 @@
 /*
 ** Change the busy handler callback function.
 */
-int sqlite3BtreeSetBusyHandler(Btree *pBt, BusyHandler *pHandler){
+int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
+  BtShared *pBt = p->pBt;
   pBt->pBusyHandler = pHandler;
   sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
   return SQLITE_OK;
@@ -1325,7 +1802,8 @@
 ** Synchronous is on by default so database corruption is not
 ** normally a worry.
 */
-int sqlite3BtreeSetCacheSize(Btree *pBt, int mxPage){
+int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
+  BtShared *pBt = p->pBt;
   sqlite3pager_set_cachesize(pBt->pPager, mxPage);
   return SQLITE_OK;
 }
@@ -1339,8 +1817,9 @@
 ** probability of damage to near zero but with a write performance reduction.
 */
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
-int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
-  sqlite3pager_set_safety_level(pBt->pPager, level);
+int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
+  BtShared *pBt = p->pBt;
+  sqlite3pager_set_safety_level(pBt->pPager, level, fullSync);
   return SQLITE_OK;
 }
 #endif
@@ -1349,7 +1828,8 @@
 ** Return TRUE if the given btree is set to safety level 1.  In other
 ** words, return TRUE if no sync() occurs on the disk files.
 */
-int sqlite3BtreeSyncDisabled(Btree *pBt){
+int sqlite3BtreeSyncDisabled(Btree *p){
+  BtShared *pBt = p->pBt;
   assert( pBt && pBt->pPager );
   return sqlite3pager_nosync(pBt->pPager);
 }
@@ -1370,7 +1850,8 @@
 ** If parameter nReserve is less than zero, then the number of reserved
 ** bytes per page is left unchanged.
 */
-int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){
+int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){
+  BtShared *pBt = p->pBt;
   if( pBt->pageSizeFixed ){
     return SQLITE_READONLY;
   }
@@ -1380,6 +1861,7 @@
   if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
         ((pageSize-1)&pageSize)==0 ){
     assert( (pageSize & 7)==0 );
+    assert( !pBt->pPage1 && !pBt->pCursor );
     pBt->pageSize = sqlite3pager_set_pagesize(pBt->pPager, pageSize);
   }
   pBt->usableSize = pBt->pageSize - nReserve;
@@ -1389,11 +1871,11 @@
 /*
 ** Return the currently defined page size
 */
-int sqlite3BtreeGetPageSize(Btree *pBt){
-  return pBt->pageSize;
+int sqlite3BtreeGetPageSize(Btree *p){
+  return p->pBt->pageSize;
 }
-int sqlite3BtreeGetReserve(Btree *pBt){
-  return pBt->pageSize - pBt->usableSize;
+int sqlite3BtreeGetReserve(Btree *p){
+  return p->pBt->pageSize - p->pBt->usableSize;
 }
 #endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
 
@@ -1403,7 +1885,8 @@
 ** is disabled. The default value for the auto-vacuum property is 
 ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
 */
-int sqlite3BtreeSetAutoVacuum(Btree *pBt, int autoVacuum){
+int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
+  BtShared *pBt = p->pBt;;
 #ifdef SQLITE_OMIT_AUTOVACUUM
   return SQLITE_READONLY;
 #else
@@ -1419,11 +1902,11 @@
 ** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
 ** enabled 1 is returned. Otherwise 0.
 */
-int sqlite3BtreeGetAutoVacuum(Btree *pBt){
+int sqlite3BtreeGetAutoVacuum(Btree *p){
 #ifdef SQLITE_OMIT_AUTOVACUUM
   return 0;
 #else
-  return pBt->autoVacuum;
+  return p->pBt->autoVacuum;
 #endif
 }
 
@@ -1438,7 +1921,7 @@
 ** is returned if we run out of memory.  SQLITE_PROTOCOL is returned
 ** if there is a locking protocol violation.
 */
-static int lockBtree(Btree *pBt){
+static int lockBtree(BtShared *pBt){
   int rc, pageSize;
   MemPage *pPage1;
   if( pBt->pPage1 ) return SQLITE_OK;
@@ -1510,11 +1993,18 @@
 ** This routine works like lockBtree() except that it also invokes the
 ** busy callback if there is lock contention.
 */
-static int lockBtreeWithRetry(Btree *pBt){
+static int lockBtreeWithRetry(Btree *pRef){
   int rc = SQLITE_OK;
-  if( pBt->inTrans==TRANS_NONE ){
-    rc = sqlite3BtreeBeginTrans(pBt, 0);
-    pBt->inTrans = TRANS_NONE;
+  if( pRef->inTrans==TRANS_NONE ){
+    u8 inTransaction = pRef->pBt->inTransaction;
+    btreeIntegrity(pRef);
+    rc = sqlite3BtreeBeginTrans(pRef, 0);
+    pRef->pBt->inTransaction = inTransaction;
+    pRef->inTrans = TRANS_NONE;
+    if( rc==SQLITE_OK ){
+      pRef->pBt->nTransaction--;
+    }
+    btreeIntegrity(pRef);
   }
   return rc;
 }
@@ -1530,11 +2020,11 @@
 **
 ** If there is a transaction in progress, this routine is a no-op.
 */
-static void unlockBtreeIfUnused(Btree *pBt){
-  if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
+static void unlockBtreeIfUnused(BtShared *pBt){
+  if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
     if( pBt->pPage1->aData==0 ){
       MemPage *pPage = pBt->pPage1;
-      pPage->aData = &((char*)pPage)[-pBt->pageSize];
+      pPage->aData = &((u8*)pPage)[-pBt->pageSize];
       pPage->pBt = pBt;
       pPage->pgno = 1;
     }
@@ -1548,7 +2038,7 @@
 ** Create a new database by initializing the first page of the
 ** file.
 */
-static int newDatabase(Btree *pBt){
+static int newDatabase(BtShared *pBt){
   MemPage *pP1;
   unsigned char *data;
   int rc;
@@ -1613,14 +2103,17 @@
 ** when A already has a read lock, we encourage A to give up and let B
 ** proceed.
 */
-int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){
+int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
+  BtShared *pBt = p->pBt;
   int rc = SQLITE_OK;
 
+  btreeIntegrity(p);
+
   /* If the btree is already in a write-transaction, or it
   ** is already in a read-transaction and a read-transaction
   ** is requested, this is a no-op.
   */
-  if( pBt->inTrans==TRANS_WRITE || (pBt->inTrans==TRANS_READ && !wrflag) ){
+  if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
     return SQLITE_OK;
   }
 
@@ -1629,6 +2122,14 @@
     return SQLITE_READONLY;
   }
 
+  /* If another database handle has already opened a write transaction 
+  ** on this shared-btree structure and a second write transaction is
+  ** requested, return SQLITE_BUSY.
+  */
+  if( pBt->inTransaction==TRANS_WRITE && wrflag ){
+    return SQLITE_BUSY;
+  }
+
   do {
     if( pBt->pPage1==0 ){
       rc = lockBtree(pBt);
@@ -1642,13 +2143,24 @@
     }
   
     if( rc==SQLITE_OK ){
-      pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
       if( wrflag ) pBt->inStmt = 0;
     }else{
       unlockBtreeIfUnused(pBt);
     }
-  }while( rc==SQLITE_BUSY && pBt->inTrans==TRANS_NONE &&
+  }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
           sqlite3InvokeBusyHandler(pBt->pBusyHandler) );
+
+  if( rc==SQLITE_OK ){
+    if( p->inTrans==TRANS_NONE ){
+      pBt->nTransaction++;
+    }
+    p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
+    if( p->inTrans>pBt->inTransaction ){
+      pBt->inTransaction = p->inTrans;
+    }
+  }
+
+  btreeIntegrity(p);
   return rc;
 }
 
@@ -1663,7 +2175,7 @@
   int i;                             /* Counter variable */
   int nCell;                         /* Number of cells in page pPage */
   int rc = SQLITE_OK;                /* Return code */
-  Btree *pBt = pPage->pBt;
+  BtShared *pBt = pPage->pBt;
   int isInitOrig = pPage->isInit;
   Pgno pgno = pPage->pgno;
 
@@ -1763,7 +2275,7 @@
 ** database. The pDbPage reference remains valid.
 */
 static int relocatePage(
-  Btree *pBt,              /* Btree */
+  BtShared *pBt,           /* Btree */
   MemPage *pDbPage,        /* Open page to move */
   u8 eType,                /* Pointer map 'type' entry for pDbPage */
   Pgno iPtrPage,           /* Pointer map 'page-no' entry for pDbPage */
@@ -1833,19 +2345,19 @@
 }
 
 /* Forward declaration required by autoVacuumCommit(). */
-static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8);
+static int allocatePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
 
 /*
 ** This routine is called prior to sqlite3pager_commit when a transaction
 ** is commited for an auto-vacuum database.
 */
-static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){
+static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
   Pager *pPager = pBt->pPager;
-  Pgno nFreeList;   /* Number of pages remaining on the free-list. */
-  int nPtrMap;      /* Number of pointer-map pages deallocated */
-  Pgno origSize;  /* Pages in the database file */
-  Pgno finSize;   /* Pages in the database file after truncation */
-  int rc;           /* Return code */
+  Pgno nFreeList;            /* Number of pages remaining on the free-list. */
+  int nPtrMap;               /* Number of pointer-map pages deallocated */
+  Pgno origSize;             /* Pages in the database file */
+  Pgno finSize;              /* Pages in the database file after truncation */
+  int rc;                    /* Return code */
   u8 eType;
   int pgsz = pBt->pageSize;  /* Page size for this database */
   Pgno iDbPage;              /* The database page to move */
@@ -1859,7 +2371,7 @@
 #endif
 
   assert( pBt->autoVacuum );
-  if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){
+  if( PTRMAP_ISPAGE(pBt, sqlite3pager_pagecount(pPager)) ){
     return SQLITE_CORRUPT_BKPT;
   }
 
@@ -1872,15 +2384,27 @@
     return SQLITE_OK;
   }
 
+  /* This block figures out how many pages there are in the database
+  ** now (variable origSize), and how many there will be after the
+  ** truncation (variable finSize).
+  **
+  ** The final size is the original size, less the number of free pages
+  ** in the database, less any pointer-map pages that will no longer
+  ** be required, less 1 if the pending-byte page was part of the database
+  ** but is not after the truncation.
+  **/
   origSize = sqlite3pager_pagecount(pPager);
-  nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
+  if( origSize==PENDING_BYTE_PAGE(pBt) ){
+    origSize--;
+  }
+  nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pBt, origSize)+pgsz/5)/(pgsz/5);
   finSize = origSize - nFreeList - nPtrMap;
-  if( origSize>=PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
+  if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
     finSize--;
-    if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){
-      finSize--;
-    }
   }
+  while( PTRMAP_ISPAGE(pBt, finSize) || finSize==PENDING_BYTE_PAGE(pBt) ){
+    finSize--;
+  }
   TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));
 
   /* Variable 'finSize' will be the size of the file in pages after
@@ -1891,7 +2415,7 @@
   */
   for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){
     /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
-    if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
+    if( PTRMAP_ISPAGE(pBt, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
       continue;
     }
 
@@ -1928,6 +2452,12 @@
     releasePage(pFreeMemPage);
     pFreeMemPage = 0;
 
+    /* Relocate the page into the body of the file. Note that although the 
+    ** page has moved within the database file, the pDbMemPage pointer 
+    ** remains valid. This means that this function can run without
+    ** invalidating cursors open on the btree. This is important in 
+    ** shared-cache mode.
+    */
     rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage);
     releasePage(pDbMemPage);
     if( rc!=SQLITE_OK ) goto autovacuum_out;
@@ -1941,8 +2471,8 @@
   if( rc!=SQLITE_OK ) goto autovacuum_out;
   put4byte(&pBt->pPage1->aData[32], 0);
   put4byte(&pBt->pPage1->aData[36], 0);
-  if( rc!=SQLITE_OK ) goto autovacuum_out;
   *nTrunc = finSize;
+  assert( finSize!=PENDING_BYTE_PAGE(pBt) );
 
 autovacuum_out:
   assert( nRef==*sqlite3pager_stats(pPager) );
@@ -1959,15 +2489,47 @@
 ** This will release the write lock on the database file.  If there
 ** are no active cursors, it also releases the read lock.
 */
-int sqlite3BtreeCommit(Btree *pBt){
-  int rc = SQLITE_OK;
-  if( pBt->inTrans==TRANS_WRITE ){
+int sqlite3BtreeCommit(Btree *p){
+  BtShared *pBt = p->pBt;
+
+  btreeIntegrity(p);
+
+  /* If the handle has a write-transaction open, commit the shared-btrees 
+  ** transaction and set the shared state to TRANS_READ.
+  */
+  if( p->inTrans==TRANS_WRITE ){
+    int rc;
+    assert( pBt->inTransaction==TRANS_WRITE );
+    assert( pBt->nTransaction>0 );
     rc = sqlite3pager_commit(pBt->pPager);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+    pBt->inTransaction = TRANS_READ;
+    pBt->inStmt = 0;
   }
-  pBt->inTrans = TRANS_NONE;
-  pBt->inStmt = 0;
+  unlockAllTables(p);
+
+  /* If the handle has any kind of transaction open, decrement the transaction
+  ** count of the shared btree. If the transaction count reaches 0, set
+  ** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below
+  ** will unlock the pager.
+  */
+  if( p->inTrans!=TRANS_NONE ){
+    pBt->nTransaction--;
+    if( 0==pBt->nTransaction ){
+      pBt->inTransaction = TRANS_NONE;
+    }
+  }
+
+  /* Set the handles current transaction state to TRANS_NONE and unlock
+  ** the pager if this call closed the only read or write transaction.
+  */
+  p->inTrans = TRANS_NONE;
   unlockBtreeIfUnused(pBt);
-  return rc;
+
+  btreeIntegrity(p);
+  return SQLITE_OK;
 }
 
 #ifndef NDEBUG
@@ -1976,29 +2538,30 @@
 ** in assert() expressions, so it is only compiled if NDEBUG is not
 ** defined.
 */
-static int countWriteCursors(Btree *pBt){
+static int countWriteCursors(BtShared *pBt){
   BtCursor *pCur;
   int r = 0;
   for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-    if( pCur->wrFlag ) r++;
+    if( pCur->wrFlag ) r++; 
   }
   return r;
 }
 #endif
 
-#ifdef SQLITE_TEST
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
 /*
 ** Print debugging information about all cursors to standard output.
 */
-void sqlite3BtreeCursorList(Btree *pBt){
+void sqlite3BtreeCursorList(Btree *p){
   BtCursor *pCur;
+  BtShared *pBt = p->pBt;
   for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
     MemPage *pPage = pCur->pPage;
     char *zMode = pCur->wrFlag ? "rw" : "ro";
     sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
        pCur, pCur->pgnoRoot, zMode,
        pPage ? pPage->pgno : 0, pCur->idx,
-       pCur->isValid ? "" : " eof"
+       (pCur->eState==CURSOR_VALID) ? "" : " eof"
     );
   }
 }
@@ -2013,11 +2576,41 @@
 ** This will release the write lock on the database file.  If there
 ** are no active cursors, it also releases the read lock.
 */
-int sqlite3BtreeRollback(Btree *pBt){
-  int rc = SQLITE_OK;
+int sqlite3BtreeRollback(Btree *p){
+  int rc;
+  BtShared *pBt = p->pBt;
   MemPage *pPage1;
-  if( pBt->inTrans==TRANS_WRITE ){
-    rc = sqlite3pager_rollback(pBt->pPager);
+
+  rc = saveAllCursors(pBt, 0, 0);
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  if( rc!=SQLITE_OK ){
+    /* This is a horrible situation. An IO or malloc() error occured whilst
+    ** trying to save cursor positions. If this is an automatic rollback (as
+    ** the result of a constraint, malloc() failure or IO error) then 
+    ** the cache may be internally inconsistent (not contain valid trees) so
+    ** we cannot simply return the error to the caller. Instead, abort 
+    ** all queries that may be using any of the cursors that failed to save.
+    */
+    while( pBt->pCursor ){
+      sqlite3 *db = pBt->pCursor->pBtree->pSqlite;
+      if( db ){
+        sqlite3AbortOtherActiveVdbes(db, 0);
+      }
+    }
+  }
+#endif
+  btreeIntegrity(p);
+  unlockAllTables(p);
+
+  if( p->inTrans==TRANS_WRITE ){
+    int rc2;
+
+    assert( TRANS_WRITE==pBt->inTransaction );
+    rc2 = sqlite3pager_rollback(pBt->pPager);
+    if( rc2!=SQLITE_OK ){
+      rc = rc2;
+    }
+
     /* The rollback may have destroyed the pPage1->aData value.  So
     ** call getPage() on page 1 again to make sure pPage1->aData is
     ** set correctly. */
@@ -2025,10 +2618,22 @@
       releasePage(pPage1);
     }
     assert( countWriteCursors(pBt)==0 );
+    pBt->inTransaction = TRANS_READ;
   }
-  pBt->inTrans = TRANS_NONE;
+
+  if( p->inTrans!=TRANS_NONE ){
+    assert( pBt->nTransaction>0 );
+    pBt->nTransaction--;
+    if( 0==pBt->nTransaction ){
+      pBt->inTransaction = TRANS_NONE;
+    }
+  }
+
+  p->inTrans = TRANS_NONE;
   pBt->inStmt = 0;
   unlockBtreeIfUnused(pBt);
+
+  btreeIntegrity(p);
   return rc;
 }
 
@@ -2047,11 +2652,13 @@
 ** error occurs within the statement, the effect of that one statement
 ** can be rolled back without having to rollback the entire transaction.
 */
-int sqlite3BtreeBeginStmt(Btree *pBt){
+int sqlite3BtreeBeginStmt(Btree *p){
   int rc;
-  if( (pBt->inTrans!=TRANS_WRITE) || pBt->inStmt ){
+  BtShared *pBt = p->pBt;
+  if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
+  assert( pBt->inTransaction==TRANS_WRITE );
   rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_stmt_begin(pBt->pPager);
   pBt->inStmt = 1;
   return rc;
@@ -2062,8 +2669,9 @@
 ** Commit the statment subtransaction currently in progress.  If no
 ** subtransaction is active, this is a no-op.
 */
-int sqlite3BtreeCommitStmt(Btree *pBt){
+int sqlite3BtreeCommitStmt(Btree *p){
   int rc;
+  BtShared *pBt = p->pBt;
   if( pBt->inStmt && !pBt->readOnly ){
     rc = sqlite3pager_stmt_commit(pBt->pPager);
   }else{
@@ -2081,12 +2689,16 @@
 ** to use a cursor that was open at the beginning of this operation
 ** will result in an error.
 */
-int sqlite3BtreeRollbackStmt(Btree *pBt){
-  int rc;
-  if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
-  rc = sqlite3pager_stmt_rollback(pBt->pPager);
-  assert( countWriteCursors(pBt)==0 );
-  pBt->inStmt = 0;
+int sqlite3BtreeRollbackStmt(Btree *p){
+  int rc = SQLITE_OK;
+  BtShared *pBt = p->pBt;
+  sqlite3MallocDisallow();
+  if( pBt->inStmt && !pBt->readOnly ){
+    rc = sqlite3pager_stmt_rollback(pBt->pPager);
+    assert( countWriteCursors(pBt)==0 );
+    pBt->inStmt = 0;
+  }
+  sqlite3MallocAllow();
   return rc;
 }
 
@@ -2150,7 +2762,7 @@
 ** always ignored for INTKEY tables.
 */
 int sqlite3BtreeCursor(
-  Btree *pBt,                                 /* The btree */
+  Btree *p,                                   /* The btree */
   int iTable,                                 /* Root page of table to open */
   int wrFlag,                                 /* 1 to write. 0 read-only */
   int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
@@ -2159,6 +2771,7 @@
 ){
   int rc;
   BtCursor *pCur;
+  BtShared *pBt = p->pBt;
 
   *ppCur = 0;
   if( wrFlag ){
@@ -2169,19 +2782,19 @@
       return SQLITE_LOCKED;
     }
   }
+
   if( pBt->pPage1==0 ){
-    rc = lockBtreeWithRetry(pBt);
+    rc = lockBtreeWithRetry(p);
     if( rc!=SQLITE_OK ){
       return rc;
     }
   }
-  pCur = sqliteMallocRaw( sizeof(*pCur) );
+  pCur = sqliteMalloc( sizeof(*pCur) );
   if( pCur==0 ){
     rc = SQLITE_NOMEM;
     goto create_cursor_exception;
   }
   pCur->pgnoRoot = (Pgno)iTable;
-  pCur->pPage = 0;  /* For exit-handler, in case getAndInitPage() fails. */
   if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){
     rc = SQLITE_EMPTY;
     goto create_cursor_exception;
@@ -2190,22 +2803,24 @@
   if( rc!=SQLITE_OK ){
     goto create_cursor_exception;
   }
+
+  /* Now that no other errors can occur, finish filling in the BtCursor
+  ** variables, link the cursor into the BtShared list and set *ppCur (the
+  ** output argument to this function).
+  */
   pCur->xCompare = xCmp ? xCmp : dfltCompare;
   pCur->pArg = pArg;
-  pCur->pBt = pBt;
+  pCur->pBtree = p;
   pCur->wrFlag = wrFlag;
-  pCur->idx = 0;
-  memset(&pCur->info, 0, sizeof(pCur->info));
   pCur->pNext = pBt->pCursor;
   if( pCur->pNext ){
     pCur->pNext->pPrev = pCur;
   }
-  pCur->pPrev = 0;
   pBt->pCursor = pCur;
-  pCur->isValid = 0;
+  pCur->eState = CURSOR_INVALID;
   *ppCur = pCur;
+
   return SQLITE_OK;
-
 create_cursor_exception:
   if( pCur ){
     releasePage(pCur->pPage);
@@ -2234,7 +2849,8 @@
 ** when the last cursor is closed.
 */
 int sqlite3BtreeCloseCursor(BtCursor *pCur){
-  Btree *pBt = pCur->pBt;
+  BtShared *pBt = pCur->pBtree->pBt;
+  restoreOrClearCursorPosition(pCur, 0);
   if( pCur->pPrev ){
     pCur->pPrev->pNext = pCur->pNext;
   }else{
@@ -2301,13 +2917,17 @@
 ** itself, not the number of bytes in the key.
 */
 int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
-  if( !pCur->isValid ){
-    *pSize = 0;
-  }else{
-    getCellInfo(pCur);
-    *pSize = pCur->info.nKey;
+  int rc = restoreOrClearCursorPosition(pCur, 1);
+  if( rc==SQLITE_OK ){
+    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
+    if( pCur->eState==CURSOR_INVALID ){
+      *pSize = 0;
+    }else{
+      getCellInfo(pCur);
+      *pSize = pCur->info.nKey;
+    }
   }
-  return SQLITE_OK;
+  return rc;
 }
 
 /*
@@ -2318,14 +2938,18 @@
 ** the database is empty) then *pSize is set to 0.
 */
 int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
-  if( !pCur->isValid ){
-    /* Not pointing at a valid entry - set *pSize to 0. */
-    *pSize = 0;
-  }else{
-    getCellInfo(pCur);
-    *pSize = pCur->info.nData;
+  int rc = restoreOrClearCursorPosition(pCur, 1);
+  if( rc==SQLITE_OK ){
+    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
+    if( pCur->eState==CURSOR_INVALID ){
+      /* Not pointing at a valid entry - set *pSize to 0. */
+      *pSize = 0;
+    }else{
+      getCellInfo(pCur);
+      *pSize = pCur->info.nData;
+    }
   }
-  return SQLITE_OK;
+  return rc;
 }
 
 /*
@@ -2348,19 +2972,18 @@
   Pgno nextPage;
   int rc;
   MemPage *pPage;
-  Btree *pBt;
+  BtShared *pBt;
   int ovflSize;
   u32 nKey;
 
   assert( pCur!=0 && pCur->pPage!=0 );
-  assert( pCur->isValid );
-  pBt = pCur->pBt;
+  assert( pCur->eState==CURSOR_VALID );
+  pBt = pCur->pBtree->pBt;
   pPage = pCur->pPage;
   pageIntegrity(pPage);
   assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
   getCellInfo(pCur);
-  aPayload = pCur->info.pCell;
-  aPayload += pCur->info.nHeader;
+  aPayload = pCur->info.pCell + pCur->info.nHeader;
   if( pPage->intKey ){
     nKey = 0;
   }else{
@@ -2429,14 +3052,18 @@
 ** the available payload.
 */
 int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
-  assert( pCur->isValid );
-  assert( pCur->pPage!=0 );
-  if( pCur->pPage->intKey ){
-    return SQLITE_CORRUPT_BKPT;
+  int rc = restoreOrClearCursorPosition(pCur, 1);
+  if( rc==SQLITE_OK ){
+    assert( pCur->eState==CURSOR_VALID );
+    assert( pCur->pPage!=0 );
+    if( pCur->pPage->intKey ){
+      return SQLITE_CORRUPT_BKPT;
+    }
+    assert( pCur->pPage->intKey==0 );
+    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+    rc = getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
   }
-  assert( pCur->pPage->intKey==0 );
-  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
-  return getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
+  return rc;
 }
 
 /*
@@ -2449,10 +3076,14 @@
 ** the available payload.
 */
 int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
-  assert( pCur->isValid );
-  assert( pCur->pPage!=0 );
-  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
-  return getPayload(pCur, offset, amt, pBuf, 1);
+  int rc = restoreOrClearCursorPosition(pCur, 1);
+  if( rc==SQLITE_OK ){
+    assert( pCur->eState==CURSOR_VALID );
+    assert( pCur->pPage!=0 );
+    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+    rc = getPayload(pCur, offset, amt, pBuf, 1);
+  }
+  return rc;
 }
 
 /*
@@ -2485,7 +3116,7 @@
   int nLocal;
 
   assert( pCur!=0 && pCur->pPage!=0 );
-  assert( pCur->isValid );
+  assert( pCur->eState==CURSOR_VALID );
   pPage = pCur->pPage;
   pageIntegrity(pPage);
   assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
@@ -2523,10 +3154,16 @@
 ** in the common case where no overflow pages are used.
 */
 const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
-  return (const void*)fetchPayload(pCur, pAmt, 0);
+  if( pCur->eState==CURSOR_VALID ){
+    return (const void*)fetchPayload(pCur, pAmt, 0);
+  }
+  return 0;
 }
 const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
-  return (const void*)fetchPayload(pCur, pAmt, 1);
+  if( pCur->eState==CURSOR_VALID ){
+    return (const void*)fetchPayload(pCur, pAmt, 1);
+  }
+  return 0;
 }
 
 
@@ -2538,9 +3175,9 @@
   int rc;
   MemPage *pNewPage;
   MemPage *pOldPage;
-  Btree *pBt = pCur->pBt;
+  BtShared *pBt = pCur->pBtree->pBt;
 
-  assert( pCur->isValid );
+  assert( pCur->eState==CURSOR_VALID );
   rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
   if( rc ) return rc;
   pageIntegrity(pNewPage);
@@ -2587,7 +3224,7 @@
   MemPage *pPage;
   int idxParent;
 
-  assert( pCur->isValid );
+  assert( pCur->eState==CURSOR_VALID );
   pPage = pCur->pPage;
   assert( pPage!=0 );
   assert( !isRootPage(pPage) );
@@ -2609,17 +3246,24 @@
 */
 static int moveToRoot(BtCursor *pCur){
   MemPage *pRoot;
-  int rc;
-  Btree *pBt = pCur->pBt;
+  int rc = SQLITE_OK;
+  BtShared *pBt = pCur->pBtree->pBt;
 
-  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0);
-  if( rc ){
-    pCur->isValid = 0;
-    return rc;
+  restoreOrClearCursorPosition(pCur, 0);
+  pRoot = pCur->pPage;
+  if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
+    assert( pRoot->isInit );
+  }else{
+    if( 
+      SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
+    ){
+      pCur->eState = CURSOR_INVALID;
+      return rc;
+    }
+    releasePage(pCur->pPage);
+    pageIntegrity(pRoot);
+    pCur->pPage = pRoot;
   }
-  releasePage(pCur->pPage);
-  pageIntegrity(pRoot);
-  pCur->pPage = pRoot;
   pCur->idx = 0;
   pCur->info.nSize = 0;
   if( pRoot->nCell==0 && !pRoot->leaf ){
@@ -2627,23 +3271,26 @@
     assert( pRoot->pgno==1 );
     subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
     assert( subpage>0 );
-    pCur->isValid = 1;
+    pCur->eState = CURSOR_VALID;
     rc = moveToChild(pCur, subpage);
   }
-  pCur->isValid = pCur->pPage->nCell>0;
+  pCur->eState = ((pCur->pPage->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
   return rc;
 }
 
 /*
 ** Move the cursor down to the left-most leaf entry beneath the
 ** entry to which it is currently pointing.
+**
+** The left-most leaf is the one with the smallest key - the first
+** in ascending order.
 */
 static int moveToLeftmost(BtCursor *pCur){
   Pgno pgno;
   int rc;
   MemPage *pPage;
 
-  assert( pCur->isValid );
+  assert( pCur->eState==CURSOR_VALID );
   while( !(pPage = pCur->pPage)->leaf ){
     assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
     pgno = get4byte(findCell(pPage, pCur->idx));
@@ -2659,13 +3306,16 @@
 ** between moveToLeftmost() and moveToRightmost().  moveToLeftmost()
 ** finds the left-most entry beneath the *entry* whereas moveToRightmost()
 ** finds the right-most entry beneath the *page*.
+**
+** The right-most entry is the one with the largest key - the last
+** key in ascending order.
 */
 static int moveToRightmost(BtCursor *pCur){
   Pgno pgno;
   int rc;
   MemPage *pPage;
 
-  assert( pCur->isValid );
+  assert( pCur->eState==CURSOR_VALID );
   while( !(pPage = pCur->pPage)->leaf ){
     pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
     pCur->idx = pPage->nCell;
@@ -2685,7 +3335,7 @@
   int rc;
   rc = moveToRoot(pCur);
   if( rc ) return rc;
-  if( pCur->isValid==0 ){
+  if( pCur->eState==CURSOR_INVALID ){
     assert( pCur->pPage->nCell==0 );
     *pRes = 1;
     return SQLITE_OK;
@@ -2704,12 +3354,12 @@
   int rc;
   rc = moveToRoot(pCur);
   if( rc ) return rc;
-  if( pCur->isValid==0 ){
+  if( CURSOR_INVALID==pCur->eState ){
     assert( pCur->pPage->nCell==0 );
     *pRes = 1;
     return SQLITE_OK;
   }
-  assert( pCur->isValid );
+  assert( pCur->eState==CURSOR_VALID );
   *pRes = 0;
   rc = moveToRightmost(pCur);
   return rc;
@@ -2720,7 +3370,7 @@
 **
 ** For INTKEY tables, only the nKey parameter is used.  pKey is
 ** ignored.  For other tables, nKey is the number of bytes of data
-** in nKey.  The comparison function specified when the cursor was
+** in pKey.  The comparison function specified when the cursor was
 ** created is used to compare keys.
 **
 ** If an exact match is not found, then the cursor is always
@@ -2744,11 +3394,13 @@
 */
 int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
   int rc;
+  int tryRightmost;
   rc = moveToRoot(pCur);
   if( rc ) return rc;
   assert( pCur->pPage );
   assert( pCur->pPage->isInit );
-  if( pCur->isValid==0 ){
+  tryRightmost = pCur->pPage->intKey;
+  if( pCur->eState==CURSOR_INVALID ){
     *pRes = -1;
     assert( pCur->pPage->nCell==0 );
     return SQLITE_OK;
@@ -2769,18 +3421,29 @@
       i64 nCellKey;
       pCur->idx = (lwr+upr)/2;
       pCur->info.nSize = 0;
-      sqlite3BtreeKeySize(pCur, &nCellKey);
       if( pPage->intKey ){
+        u8 *pCell;
+        if( tryRightmost ){
+          pCur->idx = upr;
+        }
+        pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
+        if( pPage->hasData ){
+          u32 dummy;
+          pCell += getVarint32(pCell, &dummy);
+        }
+        getVarint(pCell, (u64 *)&nCellKey);
         if( nCellKey<nKey ){
           c = -1;
         }else if( nCellKey>nKey ){
           c = +1;
+          tryRightmost = 0;
         }else{
           c = 0;
         }
       }else{
         int available;
         pCellKey = (void *)fetchPayload(pCur, &available, 0);
+        nCellKey = pCur->info.nKey;
         if( available>=nCellKey ){
           c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
         }else{
@@ -2840,7 +3503,11 @@
 ** the first entry.  TRUE is also returned if the table is empty.
 */
 int sqlite3BtreeEof(BtCursor *pCur){
-  return pCur->isValid==0;
+  /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
+  ** have been deleted? This API will need to change to return an error code
+  ** as well as the boolean result value.
+  */
+  return (CURSOR_VALID!=pCur->eState);
 }
 
 /*
@@ -2851,10 +3518,24 @@
 */
 int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   int rc;
-  MemPage *pPage = pCur->pPage;
+  MemPage *pPage;
 
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  rc = restoreOrClearCursorPosition(pCur, 1);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+  if( pCur->skip>0 ){
+    pCur->skip = 0;
+    *pRes = 0;
+    return SQLITE_OK;
+  }
+  pCur->skip = 0;
+#endif 
+
   assert( pRes!=0 );
-  if( pCur->isValid==0 ){
+  pPage = pCur->pPage;
+  if( CURSOR_INVALID==pCur->eState ){
     *pRes = 1;
     return SQLITE_OK;
   }
@@ -2874,7 +3555,7 @@
     do{
       if( isRootPage(pPage) ){
         *pRes = 1;
-        pCur->isValid = 0;
+        pCur->eState = CURSOR_INVALID;
         return SQLITE_OK;
       }
       moveToParent(pCur);
@@ -2906,7 +3587,21 @@
   int rc;
   Pgno pgno;
   MemPage *pPage;
-  if( pCur->isValid==0 ){
+
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  rc = restoreOrClearCursorPosition(pCur, 1);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+  if( pCur->skip<0 ){
+    pCur->skip = 0;
+    *pRes = 0;
+    return SQLITE_OK;
+  }
+  pCur->skip = 0;
+#endif
+
+  if( CURSOR_INVALID==pCur->eState ){
     *pRes = 1;
     return SQLITE_OK;
   }
@@ -2922,7 +3617,7 @@
   }else{
     while( pCur->idx==0 ){
       if( isRootPage(pPage) ){
-        pCur->isValid = 0;
+        pCur->eState = CURSOR_INVALID;
         *pRes = 1;
         return SQLITE_OK;
       }
@@ -2963,7 +3658,7 @@
 ** is only used by auto-vacuum databases when allocating a new table.
 */
 static int allocatePage(
-  Btree *pBt, 
+  BtShared *pBt, 
   MemPage **ppPage, 
   Pgno *pPgno, 
   Pgno nearby,
@@ -3150,7 +3845,7 @@
     *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1;
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){
+    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
       /* If *pPgno refers to a pointer-map page, allocate two new pages
       ** at the end of the file instead of one. The first allocated page
       ** becomes a new pointer-map page, the second is used by the caller.
@@ -3181,7 +3876,7 @@
 ** sqlite3pager_unref() is NOT called for pPage.
 */
 static int freePage(MemPage *pPage){
-  Btree *pBt = pPage->pBt;
+  BtShared *pBt = pPage->pBt;
   MemPage *pPage1 = pBt->pPage1;
   int rc, n, k;
 
@@ -3197,6 +3892,15 @@
   n = get4byte(&pPage1->aData[36]);
   put4byte(&pPage1->aData[36], n+1);
 
+#ifdef SQLITE_SECURE_DELETE
+  /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
+  ** always fully overwrite deleted information with zeros.
+  */
+  rc = sqlite3pager_write(pPage->aData);
+  if( rc ) return rc;
+  memset(pPage->aData, 0, pPage->pBt->pageSize);
+#endif
+
 #ifndef SQLITE_OMIT_AUTOVACUUM
   /* If the database supports auto-vacuum, write an entry in the pointer-map
   ** to indicate that the page is free.
@@ -3237,7 +3941,9 @@
       if( rc ) return rc;
       put4byte(&pTrunk->aData[4], k+1);
       put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
+#ifndef SQLITE_SECURE_DELETE
       sqlite3pager_dont_write(pBt->pPager, pPage->pgno);
+#endif
       TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
     }
     releasePage(pTrunk);
@@ -3249,7 +3955,7 @@
 ** Free any overflow pages associated with the given Cell.
 */
 static int clearCell(MemPage *pPage, unsigned char *pCell){
-  Btree *pBt = pPage->pBt;
+  BtShared *pBt = pPage->pBt;
   CellInfo info;
   Pgno ovflPgno;
   int rc;
@@ -3301,7 +4007,7 @@
   MemPage *pToRelease = 0;
   unsigned char *pPrior;
   unsigned char *pPayload;
-  Btree *pBt = pPage->pBt;
+  BtShared *pBt = pPage->pBt;
   Pgno pgnoOvfl = 0;
   int nHeader;
   CellInfo info;
@@ -3370,6 +4076,7 @@
     n = nPayload;
     if( n>spaceLeft ) n = spaceLeft;
     if( n>nSrc ) n = nSrc;
+    assert( pSrc );
     memcpy(pPayload, pSrc, n);
     nPayload -= n;
     pPayload += n;
@@ -3390,10 +4097,11 @@
 ** given in the second argument so that MemPage.pParent holds the
 ** pointer in the third argument.
 */
-static int reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){
+static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
   MemPage *pThis;
   unsigned char *aData;
 
+  assert( pNewParent!=0 );
   if( pgno==0 ) return SQLITE_OK;
   assert( pBt->pPager!=0 );
   aData = sqlite3pager_lookup(pBt->pPager, pgno);
@@ -3404,7 +4112,7 @@
       if( pThis->pParent!=pNewParent ){
         if( pThis->pParent ) sqlite3pager_unref(pThis->pParent->aData);
         pThis->pParent = pNewParent;
-        if( pNewParent ) sqlite3pager_ref(pNewParent->aData);
+        sqlite3pager_ref(pNewParent->aData);
       }
       pThis->idxParent = idx;
     }
@@ -3433,7 +4141,7 @@
 */
 static int reparentChildPages(MemPage *pPage){
   int i;
-  Btree *pBt = pPage->pBt;
+  BtShared *pBt = pPage->pBt;
   int rc = SQLITE_OK;
 
   if( pPage->leaf ) return SQLITE_OK;
@@ -3666,7 +4374,7 @@
   u8 *pCell;
   int szCell;
   CellInfo info;
-  Btree *pBt = pPage->pBt;
+  BtShared *pBt = pPage->pBt;
   int parentIdx = pParent->nCell;   /* pParent new divider cell index */
   int parentSize;                   /* Size of new divider cell */
   u8 parentCell[64];                /* Space for the new divider cell */
@@ -3775,7 +4483,7 @@
 */
 static int balance_nonroot(MemPage *pPage){
   MemPage *pParent;            /* The parent of pPage */
-  Btree *pBt;                  /* The whole database */
+  BtShared *pBt;                  /* The whole database */
   int nCell = 0;               /* Number of cells in apCell[] */
   int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
   int nOld;                    /* Number of pages in apOld[] */
@@ -3796,7 +4504,6 @@
   MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
   MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
   Pgno pgnoNew[NB+2];          /* Page numbers for each page in apNew[] */
-  int idxDiv[NB];              /* Indices of divider cells in pParent */
   u8 *apDiv[NB];               /* Divider cells in pParent */
   int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
   int szNew[NB+2];             /* Combined size of cells place on i-th page */
@@ -3815,8 +4522,10 @@
   assert( sqlite3pager_iswriteable(pPage->aData) );
   pBt = pPage->pBt;
   pParent = pPage->pParent;
-  sqlite3pager_write(pParent->aData);
   assert( pParent );
+  if( SQLITE_OK!=(rc = sqlite3pager_write(pParent->aData)) ){
+    return rc;
+  }
   TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
 
 #ifndef SQLITE_OMIT_QUICKBALANCE
@@ -3888,7 +4597,6 @@
   nDiv = 0;
   for(i=0, k=nxDiv; i<NB; i++, k++){
     if( k<pParent->nCell ){
-      idxDiv[i] = k;
       apDiv[i] = findCell(pParent, k);
       nDiv++;
       assert( !pParent->leaf );
@@ -4117,6 +4825,7 @@
       rc = sqlite3pager_write(pNew->aData);
       if( rc ) goto balance_cleanup;
     }else{
+      assert( i>0 );
       rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
       if( rc ) goto balance_cleanup;
       apNew[i] = pNew;
@@ -4268,6 +4977,8 @@
     }
   }
   assert( j==nCell );
+  assert( nOld>0 );
+  assert( nNew>0 );
   if( (pageFlags & PTF_LEAF)==0 ){
     memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4);
   }
@@ -4326,7 +5037,7 @@
   MemPage *pChild;             /* The only child page of pPage */
   Pgno pgnoChild;              /* Page number for pChild */
   int rc = SQLITE_OK;          /* Return code from subprocedures */
-  Btree *pBt;                  /* The main BTree structure */
+  BtShared *pBt;                  /* The main BTree structure */
   int mxCellPerPage;           /* Maximum number of cells per page */
   u8 **apCell;                 /* All cells from pages being balanced */
   int *szCell;                 /* Local size of all cells */
@@ -4428,7 +5139,7 @@
   int rc;             /* Return value from subprocedures */
   MemPage *pChild;    /* Pointer to a new child page */
   Pgno pgnoChild;     /* Page number of the new child page */
-  Btree *pBt;         /* The BTree */
+  BtShared *pBt;         /* The BTree */
   int usableSize;     /* Total usable size of a page */
   u8 *data;           /* Content of the parent page */
   u8 *cdata;          /* Content of the child page */
@@ -4517,10 +5228,12 @@
 ** a page entirely and we do not want to leave any cursors 
 ** pointing to non-existant pages or cells.
 */
-static int checkReadLocks(Btree *pBt, Pgno pgnoRoot, BtCursor *pExclude){
+static int checkReadLocks(BtShared *pBt, Pgno pgnoRoot, BtCursor *pExclude){
   BtCursor *p;
   for(p=pBt->pCursor; p; p=p->pNext){
+    u32 flags = (p->pBtree->pSqlite ? p->pBtree->pSqlite->flags : 0);
     if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue;
+    if( p->wrFlag==0 && flags&SQLITE_ReadUncommitted ) continue;
     if( p->wrFlag==0 ) return SQLITE_LOCKED;
     if( p->pPage->pgno!=p->pgnoRoot ){
       moveToRoot(p);
@@ -4547,11 +5260,11 @@
   int loc;
   int szNew;
   MemPage *pPage;
-  Btree *pBt = pCur->pBt;
+  BtShared *pBt = pCur->pBtree->pBt;
   unsigned char *oldCell;
   unsigned char *newCell = 0;
 
-  if( pBt->inTrans!=TRANS_WRITE ){
+  if( pBt->inTransaction!=TRANS_WRITE ){
     /* Must start a transaction before doing an insert */
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
@@ -4562,8 +5275,16 @@
   if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
     return SQLITE_LOCKED; /* The table pCur points to has a read lock */
   }
-  rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc);
-  if( rc ) return rc;
+
+  /* Save the positions of any other cursors open on this table */
+  restoreOrClearCursorPosition(pCur, 0);
+  if( 
+    SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
+    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc))
+  ){
+    return rc;
+  }
+
   pPage = pCur->pPage;
   assert( pPage->intKey || nKey>=0 );
   assert( pPage->leaf || !pPage->leafData );
@@ -4579,7 +5300,7 @@
   if( rc ) goto end_insert;
   assert( szNew==cellSizePtr(pPage, newCell) );
   assert( szNew<=MX_CELL_SIZE(pBt) );
-  if( loc==0 && pCur->isValid ){
+  if( loc==0 && CURSOR_VALID==pCur->eState ){
     int szOld;
     assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
     oldCell = findCell(pPage, pCur->idx);
@@ -4619,10 +5340,10 @@
   unsigned char *pCell;
   int rc;
   Pgno pgnoChild = 0;
-  Btree *pBt = pCur->pBt;
+  BtShared *pBt = pCur->pBtree->pBt;
 
   assert( pPage->isInit );
-  if( pBt->inTrans!=TRANS_WRITE ){
+  if( pBt->inTransaction!=TRANS_WRITE ){
     /* Must start a transaction before doing a delete */
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
@@ -4636,9 +5357,20 @@
   if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
     return SQLITE_LOCKED; /* The table pCur points to has a read lock */
   }
-  rc = sqlite3pager_write(pPage->aData);
-  if( rc ) return rc;
 
+  /* Restore the current cursor position (a no-op if the cursor is not in 
+  ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors 
+  ** open on the same table. Then call sqlite3pager_write() on the page
+  ** that the entry will be deleted from.
+  */
+  if( 
+    (rc = restoreOrClearCursorPosition(pCur, 1))!=0 ||
+    (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
+    (rc = sqlite3pager_write(pPage->aData))!=0
+  ){
+    return rc;
+  }
+
   /* Locate the cell within it's page and leave pCell pointing to the
   ** data. The clearCell() call frees any overflow pages associated with the
   ** cell. The cell itself is still intact.
@@ -4660,7 +5392,9 @@
     */
     BtCursor leafCur;
     unsigned char *pNext;
-    int szNext;
+    int szNext;  /* The compiler warning is wrong: szNext is always 
+                 ** initialized before use.  Adding an extra initialization
+                 ** to silence the compiler slows down the code. */
     int notUsed;
     unsigned char *tempCell = 0;
     assert( !pPage->leafData );
@@ -4722,11 +5456,12 @@
 **     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
 **     BTREE_ZERODATA                  Used for SQL indices
 */
-int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
+int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
+  BtShared *pBt = p->pBt;
   MemPage *pRoot;
   Pgno pgnoRoot;
   int rc;
-  if( pBt->inTrans!=TRANS_WRITE ){
+  if( pBt->inTransaction!=TRANS_WRITE ){
     /* Must start a transaction first */
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
@@ -4753,14 +5488,14 @@
     ** root page of the new table should go. meta[3] is the largest root-page
     ** created so far, so the new root-page is (meta[3]+1).
     */
-    rc = sqlite3BtreeGetMeta(pBt, 4, &pgnoRoot);
+    rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot);
     if( rc!=SQLITE_OK ) return rc;
     pgnoRoot++;
 
     /* The new root-page may not be allocated on a pointer-map page, or the
     ** PENDING_BYTE page.
     */
-    if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) ||
+    if( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
         pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
       pgnoRoot++;
     }
@@ -4820,7 +5555,7 @@
       releasePage(pRoot);
       return rc;
     }
-    rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot);
+    rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot);
     if( rc ){
       releasePage(pRoot);
       return rc;
@@ -4843,7 +5578,7 @@
 ** the page to the freelist.
 */
 static int clearDatabasePage(
-  Btree *pBt,           /* The BTree that contains the table */
+  BtShared *pBt,           /* The BTree that contains the table */
   Pgno pgno,            /* Page number to clear */
   MemPage *pParent,     /* Parent page.  NULL for the root */
   int freePageFlag      /* Deallocate page if true */
@@ -4894,23 +5629,35 @@
 ** read cursors on the table.  Open write cursors are moved to the
 ** root of the table.
 */
-int sqlite3BtreeClearTable(Btree *pBt, int iTable){
+int sqlite3BtreeClearTable(Btree *p, int iTable){
   int rc;
   BtCursor *pCur;
-  if( pBt->inTrans!=TRANS_WRITE ){
+  BtShared *pBt = p->pBt;
+  sqlite3 *db = p->pSqlite;
+  if( p->inTrans!=TRANS_WRITE ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
-  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-    if( pCur->pgnoRoot==(Pgno)iTable ){
-      if( pCur->wrFlag==0 ) return SQLITE_LOCKED;
-      moveToRoot(pCur);
+
+  /* If this connection is not in read-uncommitted mode and currently has
+  ** a read-cursor open on the table being cleared, return SQLITE_LOCKED.
+  */
+  if( 0==db || 0==(db->flags&SQLITE_ReadUncommitted) ){
+    for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+      if( pCur->pBtree==p && pCur->pgnoRoot==(Pgno)iTable ){
+        if( 0==pCur->wrFlag ){
+          return SQLITE_LOCKED;
+        }
+        moveToRoot(pCur);
+      }
     }
   }
-  rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0);
-  if( rc ){
-    sqlite3BtreeRollback(pBt);
+
+  /* Save the position of all cursors open on this table */
+  if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){
+    return rc;
   }
-  return rc;
+
+  return clearDatabasePage(pBt, (Pgno)iTable, 0, 0);
 }
 
 /*
@@ -4933,11 +5680,12 @@
 ** The last root page is recorded in meta[3] and the value of
 ** meta[3] is updated by this procedure.
 */
-int sqlite3BtreeDropTable(Btree *pBt, int iTable, int *piMoved){
+int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
   int rc;
   MemPage *pPage = 0;
+  BtShared *pBt = p->pBt;
 
-  if( pBt->inTrans!=TRANS_WRITE ){
+  if( p->inTrans!=TRANS_WRITE ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
 
@@ -4953,7 +5701,7 @@
 
   rc = getPage(pBt, (Pgno)iTable, &pPage);
   if( rc ) return rc;
-  rc = sqlite3BtreeClearTable(pBt, iTable);
+  rc = sqlite3BtreeClearTable(p, iTable);
   if( rc ){
     releasePage(pPage);
     return rc;
@@ -4968,7 +5716,7 @@
 #else
     if( pBt->autoVacuum ){
       Pgno maxRootPgno;
-      rc = sqlite3BtreeGetMeta(pBt, 4, &maxRootPgno);
+      rc = sqlite3BtreeGetMeta(p, 4, &maxRootPgno);
       if( rc!=SQLITE_OK ){
         releasePage(pPage);
         return rc;
@@ -5020,12 +5768,12 @@
       if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
         maxRootPgno--;
       }
-      if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){
+      if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){
         maxRootPgno--;
       }
       assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
 
-      rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno);
+      rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
     }else{
       rc = freePage(pPage);
       releasePage(pPage);
@@ -5050,10 +5798,21 @@
 ** layer (and the SetCookie and ReadCookie opcodes) the number of
 ** free pages is not visible.  So Cookie[0] is the same as Meta[1].
 */
-int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){
+int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
   int rc;
   unsigned char *pP1;
+  BtShared *pBt = p->pBt;
 
+  /* Reading a meta-data value requires a read-lock on page 1 (and hence
+  ** the sqlite_master table. We grab this lock regardless of whether or
+  ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
+  ** 1 is treated as a special case by queryTableLock() and lockTable()).
+  */
+  rc = queryTableLock(p, 1, READ_LOCK);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+
   assert( idx>=0 && idx<=15 );
   rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);
   if( rc ) return rc;
@@ -5067,18 +5826,21 @@
   if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
 #endif
 
-  return SQLITE_OK;
+  /* Grab the read-lock on page 1. */
+  rc = lockTable(p, 1, READ_LOCK);
+  return rc;
 }
 
 /*
 ** Write meta-information back into the database.  Meta[0] is
 ** read-only and may not be written.
 */
-int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){
+int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
+  BtShared *pBt = p->pBt;
   unsigned char *pP1;
   int rc;
   assert( idx>=1 && idx<=15 );
-  if( pBt->inTrans!=TRANS_WRITE ){
+  if( p->inTrans!=TRANS_WRITE ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
   assert( pBt->pPage1!=0 );
@@ -5094,6 +5856,9 @@
 ** is currently pointing to.
 */
 int sqlite3BtreeFlags(BtCursor *pCur){
+  /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
+  ** restoreOrClearCursorPosition() here.
+  */
   MemPage *pPage = pCur->pPage;
   return pPage ? pPage->aData[pPage->hdrOffset] : 0;
 }
@@ -5103,7 +5868,7 @@
 ** Print a disassembly of the given page on standard output.  This routine
 ** is used for debugging and testing only.
 */
-static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
+static int btreePageDump(BtShared *pBt, int pgno, int recursive, MemPage *pParent){
   int rc;
   MemPage *pPage;
   int i, j, c;
@@ -5199,12 +5964,12 @@
   fflush(stdout);
   return SQLITE_OK;
 }
-int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
-  return btreePageDump(pBt, pgno, recursive, 0);
+int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){
+  return btreePageDump(p->pBt, pgno, recursive, 0);
 }
 #endif
 
-#ifdef SQLITE_TEST
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
 /*
 ** Fill aResult[] with information about the entry and page that the
 ** cursor is pointing to.
@@ -5227,6 +5992,11 @@
   MemPage *pPage = pCur->pPage;
   BtCursor tmpCur;
 
+  int rc = restoreOrClearCursorPosition(pCur, 1);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+
   pageIntegrity(pPage);
   assert( pPage->isInit );
   getTempCursor(pCur, &tmpCur);
@@ -5273,8 +6043,8 @@
 ** Return the pager associated with a BTree.  This routine is used for
 ** testing and debugging only.
 */
-Pager *sqlite3BtreePager(Btree *pBt){
-  return pBt->pPager;
+Pager *sqlite3BtreePager(Btree *p){
+  return p->pBt->pPager;
 }
 
 /*
@@ -5283,7 +6053,7 @@
 */
 typedef struct IntegrityCk IntegrityCk;
 struct IntegrityCk {
-  Btree *pBt;    /* The tree being checked out */
+  BtShared *pBt;    /* The tree being checked out */
   Pager *pPager; /* The associated pager.  Also accessible by pBt->pPager */
   int nPage;     /* Number of pages in the database */
   int *anRef;    /* Number of times each page is referenced */
@@ -5463,19 +6233,14 @@
   IntegrityCk *pCheck,  /* Context for the sanity check */
   int iPage,            /* Page number of the page to check */
   MemPage *pParent,     /* Parent page */
-  char *zParentContext, /* Parent context */
-  char *zLowerBound,    /* All keys should be greater than this, if not NULL */
-  int nLower,           /* Number of characters in zLowerBound */
-  char *zUpperBound,    /* All keys should be less than this, if not NULL */
-  int nUpper            /* Number of characters in zUpperBound */
+  char *zParentContext  /* Parent context */
 ){
   MemPage *pPage;
   int i, rc, depth, d2, pgno, cnt;
   int hdr, cellStart;
   int nCell;
   u8 *data;
-  BtCursor cur;
-  Btree *pBt;
+  BtShared *pBt;
   int usableSize;
   char zContext[100];
   char *hit;
@@ -5484,7 +6249,7 @@
 
   /* Check that the page exists
   */
-  cur.pBt = pBt = pCheck->pBt;
+  pBt = pCheck->pBt;
   usableSize = pBt->usableSize;
   if( iPage==0 ) return 0;
   if( checkRef(pCheck, iPage, zParentContext) ) return 0;
@@ -5502,7 +6267,6 @@
   /* Check out all the cells.
   */
   depth = 0;
-  cur.pPage = pPage;
   for(i=0; i<pPage->nCell; i++){
     u8 *pCell;
     int sz;
@@ -5535,7 +6299,7 @@
         checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
       }
 #endif
-      d2 = checkTreePage(pCheck,pgno,pPage,zContext,0,0,0,0);
+      d2 = checkTreePage(pCheck,pgno,pPage,zContext);
       if( i>0 && d2!=depth ){
         checkAppendMsg(pCheck, zContext, "Child page depth differs");
       }
@@ -5550,7 +6314,7 @@
       checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
     }
 #endif
-    checkTreePage(pCheck, pgno, pPage, zContext,0,0,0,0);
+    checkTreePage(pCheck, pgno, pPage, zContext);
   }
  
   /* Check for complete coverage of the page
@@ -5618,13 +6382,14 @@
 ** and a pointer to that error message is returned.  The calling function
 ** is responsible for freeing the error message when it is done.
 */
-char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){
+char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
   int i;
   int nRef;
   IntegrityCk sCheck;
+  BtShared *pBt = p->pBt;
 
   nRef = *sqlite3pager_stats(pBt->pPager);
-  if( lockBtreeWithRetry(pBt)!=SQLITE_OK ){
+  if( lockBtreeWithRetry(p)!=SQLITE_OK ){
     return sqliteStrDup("Unable to acquire a read lock on the database");
   }
   sCheck.pBt = pBt;
@@ -5661,7 +6426,7 @@
       checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
     }
 #endif
-    checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0);
+    checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ");
   }
 
   /* Make sure every page in the file is referenced
@@ -5676,11 +6441,11 @@
     ** references to pointer-map pages.
     */
     if( sCheck.anRef[i]==0 && 
-       (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){
+       (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
       checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
     }
     if( sCheck.anRef[i]!=0 && 
-       (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){
+       (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
       checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
     }
 #endif
@@ -5706,17 +6471,17 @@
 /*
 ** Return the full pathname of the underlying database file.
 */
-const char *sqlite3BtreeGetFilename(Btree *pBt){
-  assert( pBt->pPager!=0 );
-  return sqlite3pager_filename(pBt->pPager);
+const char *sqlite3BtreeGetFilename(Btree *p){
+  assert( p->pBt->pPager!=0 );
+  return sqlite3pager_filename(p->pBt->pPager);
 }
 
 /*
 ** Return the pathname of the directory that contains the database file.
 */
-const char *sqlite3BtreeGetDirname(Btree *pBt){
-  assert( pBt->pPager!=0 );
-  return sqlite3pager_dirname(pBt->pPager);
+const char *sqlite3BtreeGetDirname(Btree *p){
+  assert( p->pBt->pPager!=0 );
+  return sqlite3pager_dirname(p->pBt->pPager);
 }
 
 /*
@@ -5724,9 +6489,9 @@
 ** value of this routine is the same regardless of whether the journal file
 ** has been created or not.
 */
-const char *sqlite3BtreeGetJournalname(Btree *pBt){
-  assert( pBt->pPager!=0 );
-  return sqlite3pager_journalname(pBt->pPager);
+const char *sqlite3BtreeGetJournalname(Btree *p){
+  assert( p->pBt->pPager!=0 );
+  return sqlite3pager_journalname(p->pBt->pPager);
 }
 
 #ifndef SQLITE_OMIT_VACUUM
@@ -5737,11 +6502,14 @@
 ** The size of file pBtFrom may be reduced by this operation.
 ** If anything goes wrong, the transaction on pBtFrom is rolled back.
 */
-int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
+int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
   int rc = SQLITE_OK;
   Pgno i, nPage, nToPage, iSkip;
 
-  if( pBtTo->inTrans!=TRANS_WRITE || pBtFrom->inTrans!=TRANS_WRITE ){
+  BtShared *pBtTo = pTo->pBt;
+  BtShared *pBtFrom = pFrom->pBt;
+
+  if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){
     return SQLITE_ERROR;
   }
   if( pBtTo->pCursor ) return SQLITE_BUSY;
@@ -5770,7 +6538,7 @@
     rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
   }
   if( rc ){
-    sqlite3BtreeRollback(pBtTo);
+    sqlite3BtreeRollback(pTo);
   }
   return rc;  
 }
@@ -5779,15 +6547,15 @@
 /*
 ** Return non-zero if a transaction is active.
 */
-int sqlite3BtreeIsInTrans(Btree *pBt){
-  return (pBt && (pBt->inTrans==TRANS_WRITE));
+int sqlite3BtreeIsInTrans(Btree *p){
+  return (p && (p->inTrans==TRANS_WRITE));
 }
 
 /*
 ** Return non-zero if a statement transaction is active.
 */
-int sqlite3BtreeIsInStmt(Btree *pBt){
-  return (pBt && pBt->inStmt);
+int sqlite3BtreeIsInStmt(Btree *p){
+  return (p->pBt && p->pBt->inStmt);
 }
 
 /*
@@ -5804,30 +6572,101 @@
 ** Once this is routine has returned, the only thing required to commit
 ** the write-transaction for this database file is to delete the journal.
 */
-int sqlite3BtreeSync(Btree *pBt, const char *zMaster){
-  if( pBt->inTrans==TRANS_WRITE ){
+int sqlite3BtreeSync(Btree *p, const char *zMaster){
+  int rc = SQLITE_OK;
+  if( p->inTrans==TRANS_WRITE ){
+    BtShared *pBt = p->pBt;
+    Pgno nTrunc = 0;
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    Pgno nTrunc = 0;
     if( pBt->autoVacuum ){
-      int rc = autoVacuumCommit(pBt, &nTrunc); 
-      if( rc!=SQLITE_OK ) return rc;
+      rc = autoVacuumCommit(pBt, &nTrunc); 
+      if( rc!=SQLITE_OK ){
+        return rc;
+      }
     }
-    return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
 #endif
-    return sqlite3pager_sync(pBt->pPager, zMaster, 0);
+    rc = sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
   }
-  return SQLITE_OK;
+  return rc;
 }
 
-#ifndef SQLITE_OMIT_GLOBALRECOVER
 /*
-** Reset the btree and underlying pager after a malloc() failure. Any
-** transaction that was active when malloc() failed is rolled back.
+** This function returns a pointer to a blob of memory associated with
+** a single shared-btree. The memory is used by client code for it's own
+** purposes (for example, to store a high-level schema associated with 
+** the shared-btree). The btree layer manages reference counting issues.
+**
+** The first time this is called on a shared-btree, nBytes bytes of memory
+** are allocated, zeroed, and returned to the caller. For each subsequent 
+** call the nBytes parameter is ignored and a pointer to the same blob
+** of memory returned. 
+**
+** Just before the shared-btree is closed, the function passed as the 
+** xFree argument when the memory allocation was made is invoked on the 
+** blob of allocated memory. This function should not call sqliteFree()
+** on the memory, the btree layer does that.
 */
-int sqlite3BtreeReset(Btree *pBt){
-  if( pBt->pCursor ) return SQLITE_BUSY;
-  pBt->inTrans = TRANS_NONE;
-  unlockBtreeIfUnused(pBt);
-  return sqlite3pager_reset(pBt->pPager);
+void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
+  BtShared *pBt = p->pBt;
+  if( !pBt->pSchema ){
+    pBt->pSchema = sqliteMalloc(nBytes);
+    pBt->xFreeSchema = xFree;
+  }
+  return pBt->pSchema;
 }
+
+/*
+** Return true if another user of the same shared btree as the argument
+** handle holds an exclusive lock on the sqlite_master table.
+*/
+int sqlite3BtreeSchemaLocked(Btree *p){
+  return (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
+}
+
+
+#ifndef SQLITE_OMIT_SHARED_CACHE
+/*
+** Obtain a lock on the table whose root page is iTab.  The
+** lock is a write lock if isWritelock is true or a read lock
+** if it is false.
+*/
+int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
+  int rc = SQLITE_OK;
+  u8 lockType = (isWriteLock?WRITE_LOCK:READ_LOCK);
+  rc = queryTableLock(p, iTab, lockType);
+  if( rc==SQLITE_OK ){
+    rc = lockTable(p, iTab, lockType);
+  }
+  return rc;
+}
 #endif
+
+/*
+** The following debugging interface has to be in this file (rather
+** than in, for example, test1.c) so that it can get access to
+** the definition of BtShared.
+*/
+#if defined(SQLITE_DEBUG) && defined(TCLSH)
+#include <tcl.h>
+int sqlite3_shared_cache_report(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  const ThreadData *pTd = sqlite3ThreadDataReadOnly();
+  if( pTd->useSharedData ){
+    BtShared *pBt;
+    Tcl_Obj *pRet = Tcl_NewObj();
+    for(pBt=pTd->pBtree; pBt; pBt=pBt->pNext){
+      const char *zFile = sqlite3pager_filename(pBt->pPager);
+      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
+      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
+    }
+    Tcl_SetObjResult(interp, pRet);
+  }
+#endif
+  return TCL_OK;
+}
+#endif

Modified: packages/libdbd-sqlite3-perl/trunk/btree.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/btree.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/btree.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -13,7 +13,7 @@
 ** subsystem.  See comments in the source code for a detailed description
 ** of what each interface routine does.
 **
-** @(#) $Id: btree.h,v 1.64 2005/08/27 16:36:49 drh Exp $
+** @(#) $Id: btree.h,v 1.70 2006/02/11 01:25:51 drh Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -36,10 +36,12 @@
 */
 typedef struct Btree Btree;
 typedef struct BtCursor BtCursor;
+typedef struct BtShared BtShared;
 
 
 int sqlite3BtreeOpen(
   const char *zFilename,   /* Name of database file to open */
+  sqlite3 *db,             /* Associated database connection */
   Btree **,                /* Return open Btree* here */
   int flags                /* Flags */
 );
@@ -57,7 +59,7 @@
 int sqlite3BtreeClose(Btree*);
 int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
 int sqlite3BtreeSetCacheSize(Btree*,int);
-int sqlite3BtreeSetSafetyLevel(Btree*,int);
+int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
 int sqlite3BtreeSyncDisabled(Btree*);
 int sqlite3BtreeSetPageSize(Btree*,int,int);
 int sqlite3BtreeGetPageSize(Btree*);
@@ -74,7 +76,9 @@
 int sqlite3BtreeIsInTrans(Btree*);
 int sqlite3BtreeIsInStmt(Btree*);
 int sqlite3BtreeSync(Btree*, const char *zMaster);
-int sqlite3BtreeReset(Btree *);
+void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
+int sqlite3BtreeSchemaLocked(Btree *);
+int sqlite3BtreeLockTable(Btree *, int, u8);
 
 const char *sqlite3BtreeGetFilename(Btree *);
 const char *sqlite3BtreeGetDirname(Btree *);

Modified: packages/libdbd-sqlite3-perl/trunk/build.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/build.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/build.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.351 2005/09/20 17:42:23 drh Exp $
+** $Id: build.c,v 1.393 2006/03/24 03:36:26 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -36,7 +36,89 @@
   pParse->nVar = 0;
 }
 
+#ifndef SQLITE_OMIT_SHARED_CACHE
 /*
+** The TableLock structure is only used by the sqlite3TableLock() and
+** codeTableLocks() functions.
+*/
+struct TableLock {
+  int iDb;             /* The database containing the table to be locked */
+  int iTab;            /* The root page of the table to be locked */
+  u8 isWriteLock;      /* True for write lock.  False for a read lock */
+  const char *zName;   /* Name of the table */
+};
+
+/*
+** Record the fact that we want to lock a table at run-time.  
+**
+** The table to be locked has root page iTab and is found in database iDb.
+** A read or a write lock can be taken depending on isWritelock.
+**
+** This routine just records the fact that the lock is desired.  The
+** code to make the lock occur is generated by a later call to
+** codeTableLocks() which occurs during sqlite3FinishCoding().
+*/
+void sqlite3TableLock(
+  Parse *pParse,     /* Parsing context */
+  int iDb,           /* Index of the database containing the table to lock */
+  int iTab,          /* Root page number of the table to be locked */
+  u8 isWriteLock,    /* True for a write lock */
+  const char *zName  /* Name of the table to be locked */
+){
+  int i;
+  int nBytes;
+  TableLock *p;
+
+  if( 0==sqlite3ThreadDataReadOnly()->useSharedData || iDb<0 ){
+    return;
+  }
+
+  for(i=0; i<pParse->nTableLock; i++){
+    p = &pParse->aTableLock[i];
+    if( p->iDb==iDb && p->iTab==iTab ){
+      p->isWriteLock = (p->isWriteLock || isWriteLock);
+      return;
+    }
+  }
+
+  nBytes = sizeof(TableLock) * (pParse->nTableLock+1);
+  sqliteReallocOrFree((void **)&pParse->aTableLock, nBytes);
+  if( pParse->aTableLock ){
+    p = &pParse->aTableLock[pParse->nTableLock++];
+    p->iDb = iDb;
+    p->iTab = iTab;
+    p->isWriteLock = isWriteLock;
+    p->zName = zName;
+  }
+}
+
+/*
+** Code an OP_TableLock instruction for each table locked by the
+** statement (configured by calls to sqlite3TableLock()).
+*/
+static void codeTableLocks(Parse *pParse){
+  int i;
+  Vdbe *pVdbe; 
+  assert( sqlite3ThreadDataReadOnly()->useSharedData || pParse->nTableLock==0 );
+
+  if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){
+    return;
+  }
+
+  for(i=0; i<pParse->nTableLock; i++){
+    TableLock *p = &pParse->aTableLock[i];
+    int p1 = p->iDb;
+    if( p->isWriteLock ){
+      p1 = -1*(p1+1);
+    }
+    sqlite3VdbeOp3(pVdbe, OP_TableLock, p1, p->iTab, p->zName, P3_STATIC);
+  }
+}
+#else
+  #define codeTableLocks(x)
+#endif
+
+/*
 ** This routine is called after a single SQL statement has been
 ** parsed and a VDBE program to execute that statement has been
 ** prepared.  This routine puts the finishing touches on the
@@ -50,13 +132,13 @@
   sqlite3 *db;
   Vdbe *v;
 
-  if( sqlite3_malloc_failed ) return;
+  if( sqlite3MallocFailed() ) return;
   if( pParse->nested ) return;
   if( !pParse->pVdbe ){
     if( pParse->rc==SQLITE_OK && pParse->nErr ){
       pParse->rc = SQLITE_ERROR;
+      return;
     }
-    return;
   }
 
   /* Begin by generating some termination code at the end of the
@@ -82,6 +164,12 @@
         sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
         sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
       }
+
+      /* Once all the cookies have been verified and transactions opened, 
+      ** obtain the required table-locks. This is a no-op unless the 
+      ** shared-cache feature is enabled.
+      */
+      codeTableLocks(pParse);
       sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
     }
 
@@ -99,7 +187,7 @@
 
   /* Get the VDBE program ready for execution
   */
-  if( v && pParse->nErr==0 ){
+  if( v && pParse->nErr==0 && !sqlite3MallocFailed() ){
     FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
     sqlite3VdbeTrace(v, trace);
     sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
@@ -168,11 +256,10 @@
   Table *p = 0;
   int i;
   assert( zName!=0 );
-  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
     if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
-    p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
+    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, strlen(zName)+1);
     if( p ) break;
   }
   return p;
@@ -224,11 +311,14 @@
 Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
   Index *p = 0;
   int i;
-  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
+    Schema *pSchema = db->aDb[j].pSchema;
     if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
-    p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
+    assert( pSchema || (j==1 && !db->aDb[1].pBt) );
+    if( pSchema ){
+      p = sqlite3HashFind(&pSchema->idxHash, zName, strlen(zName)+1);
+    }
     if( p ) break;
   }
   return p;
@@ -250,12 +340,11 @@
 ** it is not unlinked from the Table that it indexes.
 ** Unlinking from the Table must be done by the calling function.
 */
-static void sqliteDeleteIndex(sqlite3 *db, Index *p){
+static void sqliteDeleteIndex(Index *p){
   Index *pOld;
+  const char *zName = p->zName;
 
-  assert( db!=0 && p->zName!=0 );
-  pOld = sqlite3HashInsert(&db->aDb[p->iDb].idxHash, p->zName,
-                          strlen(p->zName)+1, 0);
+  pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen( zName)+1, 0);
   assert( pOld==0 || pOld==p );
   freeIndex(p);
 }
@@ -269,9 +358,10 @@
 void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
   Index *pIndex;
   int len;
+  Hash *pHash = &db->aDb[iDb].pSchema->idxHash;
 
   len = strlen(zIdxName);
-  pIndex = sqlite3HashInsert(&db->aDb[iDb].idxHash, zIdxName, len+1, 0);
+  pIndex = sqlite3HashInsert(pHash, zIdxName, len+1, 0);
   if( pIndex ){
     if( pIndex->pTable->pIndex==pIndex ){
       pIndex->pTable->pIndex = pIndex->pNext;
@@ -299,39 +389,21 @@
 ** single file indicated.
 */
 void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
-  HashElem *pElem;
-  Hash temp1;
-  Hash temp2;
   int i, j;
 
   assert( iDb>=0 && iDb<db->nDb );
-  db->flags &= ~SQLITE_Initialized;
   for(i=iDb; i<db->nDb; i++){
     Db *pDb = &db->aDb[i];
-    temp1 = pDb->tblHash;
-    temp2 = pDb->trigHash;
-    sqlite3HashInit(&pDb->trigHash, SQLITE_HASH_STRING, 0);
-    sqlite3HashClear(&pDb->aFKey);
-    sqlite3HashClear(&pDb->idxHash);
-    for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
-      sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
+    if( pDb->pSchema ){
+      sqlite3SchemaFree(pDb->pSchema);
     }
-    sqlite3HashClear(&temp2);
-    sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0);
-    for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
-      Table *pTab = sqliteHashData(pElem);
-      sqlite3DeleteTable(db, pTab);
-    }
-    sqlite3HashClear(&temp1);
-    pDb->pSeqTab = 0;
-    DbClearProperty(db, i, DB_SchemaLoaded);
     if( iDb>0 ) return;
   }
   assert( iDb==0 );
   db->flags &= ~SQLITE_InternChanges;
 
   /* If one or more of the auxiliary database files has been closed,
-  ** then remove then from the auxiliary database list.  We take the
+  ** then remove them from the auxiliary database list.  We take the
   ** opportunity to do this here since we have just deleted all of the
   ** schema hash tables and therefore do not have to make any changes
   ** to any of those tables.
@@ -394,6 +466,7 @@
       sqliteFree(pCol->zName);
       sqlite3ExprDelete(pCol->pDflt);
       sqliteFree(pCol->zType);
+      sqliteFree(pCol->zColl);
     }
     sqliteFree(pTable->aCol);
   }
@@ -420,6 +493,8 @@
   Index *pIndex, *pNext;
   FKey *pFKey, *pNextFKey;
 
+  db = 0;
+
   if( pTable==0 ) return;
 
   /* Do not delete the table until the reference count reaches zero. */
@@ -433,8 +508,8 @@
   */
   for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
     pNext = pIndex->pNext;
-    assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
-    sqliteDeleteIndex(db, pIndex);
+    assert( pIndex->pSchema==pTable->pSchema );
+    sqliteDeleteIndex(pIndex);
   }
 
 #ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -443,8 +518,7 @@
   */
   for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
     pNextFKey = pFKey->pNextFrom;
-    assert( pTable->iDb<db->nDb );
-    assert( sqlite3HashFind(&db->aDb[pTable->iDb].aFKey,
+    assert( sqlite3HashFind(&pTable->pSchema->aFKey,
                            pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
     sqliteFree(pFKey);
   }
@@ -456,6 +530,9 @@
   sqliteFree(pTable->zName);
   sqliteFree(pTable->zColAff);
   sqlite3SelectDelete(pTable->pSelect);
+#ifndef SQLITE_OMIT_CHECK
+  sqlite3ExprDelete(pTable->pCheck);
+#endif
   sqliteFree(pTable);
 }
 
@@ -472,14 +549,14 @@
   assert( iDb>=0 && iDb<db->nDb );
   assert( zTabName && zTabName[0] );
   pDb = &db->aDb[iDb];
-  p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0);
+  p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, strlen(zTabName)+1,0);
   if( p ){
 #ifndef SQLITE_OMIT_FOREIGN_KEY
     for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
       int nTo = strlen(pF1->zTo) + 1;
-      pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo);
+      pF2 = sqlite3HashFind(&pDb->pSchema->aFKey, pF1->zTo, nTo);
       if( pF2==pF1 ){
-        sqlite3HashInsert(&pDb->aFKey, pF1->zTo, nTo, pF1->pNextTo);
+        sqlite3HashInsert(&pDb->pSchema->aFKey, pF1->zTo, nTo, pF1->pNextTo);
       }else{
         while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
         if( pF2 ){
@@ -506,7 +583,7 @@
 char *sqlite3NameFromToken(Token *pName){
   char *zName;
   if( pName ){
-    zName = sqliteStrNDup(pName->z, pName->n);
+    zName = sqliteStrNDup((char*)pName->z, pName->n);
     sqlite3Dequote(zName);
   }else{
     zName = 0;
@@ -518,7 +595,9 @@
 ** Open the sqlite_master table stored in database number iDb for
 ** writing. The table is opened using cursor 0.
 */
-void sqlite3OpenMasterTable(Vdbe *v, int iDb){
+void sqlite3OpenMasterTable(Parse *p, int iDb){
+  Vdbe *v = sqlite3GetVdbe(p);
+  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
   sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
   sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);
   sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
@@ -613,8 +692,7 @@
 ** Begin constructing a new table representation in memory.  This is
 ** the first of several action routines that get called in response
 ** to a CREATE TABLE statement.  In particular, this routine is called
-** after seeing tokens "CREATE" and "TABLE" and the table name.  The
-** pStart token is the CREATE and pName is the table name.  The isTemp
+** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
 ** flag is true if the table should be stored in the auxiliary database
 ** file instead of in the main database file.  This is normally the case
 ** when the "TEMP" or "TEMPORARY" keyword occurs in between
@@ -628,11 +706,11 @@
 */
 void sqlite3StartTable(
   Parse *pParse,   /* Parser context */
-  Token *pStart,   /* The "CREATE" token */
   Token *pName1,   /* First part of the name of the table or view */
   Token *pName2,   /* Second part of the name of the table or view */
   int isTemp,      /* True if this is a TEMP table */
-  int isView       /* True if this is a VIEW */
+  int isView,      /* True if this is a VIEW */
+  int noErr        /* Do nothing if table already exists */
 ){
   Table *pTable;
   char *zName = 0; /* The name of the new table */
@@ -710,7 +788,9 @@
   }
   pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
   if( pTable ){
-    sqlite3ErrorMsg(pParse, "table %T already exists", pName);
+    if( !noErr ){
+      sqlite3ErrorMsg(pParse, "table %T already exists", pName);
+    }
     goto begin_table_error;
   }
   if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){
@@ -728,7 +808,7 @@
   pTable->aCol = 0;
   pTable->iPKey = -1;
   pTable->pIndex = 0;
-  pTable->iDb = iDb;
+  pTable->pSchema = db->aDb[iDb].pSchema;
   pTable->nRef = 1;
   if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable);
   pParse->pNewTable = pTable;
@@ -739,7 +819,7 @@
   */
 #ifndef SQLITE_OMIT_AUTOINCREMENT
   if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
-    db->aDb[iDb].pSeqTab = pTable;
+    pTable->pSchema->pSeqTab = pTable;
   }
 #endif
 
@@ -753,6 +833,7 @@
   */
   if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
     int lbl;
+    int fileFormat;
     sqlite3BeginWriteOperation(pParse, 0, iDb);
 
     /* If the file format and encoding in the database have not been set, 
@@ -761,9 +842,11 @@
     sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);   /* file_format */
     lbl = sqlite3VdbeMakeLabel(v);
     sqlite3VdbeAddOp(v, OP_If, 0, lbl);
-    sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
+    fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
+                  1 : SQLITE_DEFAULT_FILE_FORMAT;
+    sqlite3VdbeAddOp(v, OP_Integer, fileFormat, 0);
     sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
-    sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
+    sqlite3VdbeAddOp(v, OP_Integer, ENC(db), 0);
     sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
     sqlite3VdbeResolveLabel(v, lbl);
 
@@ -783,7 +866,7 @@
     {
       sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
     }
-    sqlite3OpenMasterTable(v, iDb);
+    sqlite3OpenMasterTable(pParse, iDb);
     sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
     sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
     sqlite3VdbeAddOp(v, OP_Null, 0, 0);
@@ -855,7 +938,6 @@
   ** be called next to set pCol->affinity correctly.
   */
   pCol->affinity = SQLITE_AFF_NONE;
-  pCol->pColl = pParse->db->pDfltColl;
   p->nCol++;
 }
 
@@ -891,6 +973,9 @@
 ** 'CLOB'        | SQLITE_AFF_TEXT
 ** 'TEXT'        | SQLITE_AFF_TEXT
 ** 'BLOB'        | SQLITE_AFF_NONE
+** 'REAL'        | SQLITE_AFF_REAL
+** 'FLOA'        | SQLITE_AFF_REAL
+** 'DOUB'        | SQLITE_AFF_REAL
 **
 ** If none of the substrings in the above table are found,
 ** SQLITE_AFF_NUMERIC is returned.
@@ -911,10 +996,21 @@
     }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){       /* TEXT */
       aff = SQLITE_AFF_TEXT;
     }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */
+        && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
+      aff = SQLITE_AFF_NONE;
+#ifndef SQLITE_OMIT_FLOATING_POINT
+    }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l')          /* REAL */
         && aff==SQLITE_AFF_NUMERIC ){
-      aff = SQLITE_AFF_NONE;
+      aff = SQLITE_AFF_REAL;
+    }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a')          /* FLOA */
+        && aff==SQLITE_AFF_NUMERIC ){
+      aff = SQLITE_AFF_REAL;
+    }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b')          /* DOUB */
+        && aff==SQLITE_AFF_NUMERIC ){
+      aff = SQLITE_AFF_REAL;
+#endif
     }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */
-      aff = SQLITE_AFF_INTEGER; 
+      aff = SQLITE_AFF_INTEGER;
       break;
     }
   }
@@ -993,7 +1089,8 @@
   Parse *pParse,    /* Parsing context */
   ExprList *pList,  /* List of field names to be indexed */
   int onError,      /* What to do with a uniqueness conflict */
-  int autoInc       /* True if the AUTOINCREMENT keyword is present */
+  int autoInc,      /* True if the AUTOINCREMENT keyword is present */
+  int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
 ){
   Table *pTab = pParse->pNewTable;
   char *zType = 0;
@@ -1024,7 +1121,8 @@
   if( iCol>=0 && iCol<pTab->nCol ){
     zType = pTab->aCol[iCol].zType;
   }
-  if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){
+  if( zType && sqlite3StrICmp(zType, "INTEGER")==0
+        && sortOrder==SQLITE_SO_ASC ){
     pTab->iPKey = iCol;
     pTab->keyConf = onError;
     pTab->autoInc = autoInc;
@@ -1034,7 +1132,7 @@
        "INTEGER PRIMARY KEY");
 #endif
   }else{
-    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);
+    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
     pList = 0;
   }
 
@@ -1044,46 +1142,50 @@
 }
 
 /*
+** Add a new CHECK constraint to the table currently under construction.
+*/
+void sqlite3AddCheckConstraint(
+  Parse *pParse,    /* Parsing context */
+  Expr *pCheckExpr  /* The check expression */
+){
+#ifndef SQLITE_OMIT_CHECK
+  Table *pTab = pParse->pNewTable;
+  if( pTab ){
+    /* The CHECK expression must be duplicated so that tokens refer
+    ** to malloced space and not the (ephemeral) text of the CREATE TABLE
+    ** statement */
+    pTab->pCheck = sqlite3ExprAnd(pTab->pCheck, sqlite3ExprDup(pCheckExpr));
+  }
+#endif
+  sqlite3ExprDelete(pCheckExpr);
+}
+
+/*
 ** Set the collation function of the most recently parsed table column
 ** to the CollSeq given.
 */
 void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
   Table *p;
-  Index *pIdx;
-  CollSeq *pColl;
   int i;
 
   if( (p = pParse->pNewTable)==0 ) return;
   i = p->nCol-1;
 
-  pColl = sqlite3LocateCollSeq(pParse, zType, nType);
-  p->aCol[i].pColl = pColl;
-
-  /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
-  ** then an index may have been created on this column before the
-  ** collation type was added. Correct this if it is the case.
-  */
-  for(pIdx = p->pIndex; pIdx; pIdx=pIdx->pNext){
-    assert( pIdx->nColumn==1 );
-    if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl;
-  }
-}
-
-/*
-** Call sqlite3CheckCollSeq() for all collating sequences in an index,
-** in order to verify that all the necessary collating sequences are
-** loaded.
-*/
-int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){
-  if( pIdx ){
-    int i;
-    for(i=0; i<pIdx->nColumn; i++){
-      if( sqlite3CheckCollSeq(pParse, pIdx->keyInfo.aColl[i]) ){
-        return SQLITE_ERROR;
+  if( sqlite3LocateCollSeq(pParse, zType, nType) ){
+    Index *pIdx;
+    p->aCol[i].zColl = sqliteStrNDup(zType, nType);
+  
+    /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
+    ** then an index may have been created on this column before the
+    ** collation type was added. Correct this if it is the case.
+    */
+    for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
+      assert( pIdx->nColumn==1 );
+      if( pIdx->aiColumn[0]==i ){
+        pIdx->azColl[0] = p->aCol[i].zColl;
       }
     }
   }
-  return SQLITE_OK;
 }
 
 /*
@@ -1102,10 +1204,11 @@
 */
 CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
   sqlite3 *db = pParse->db;
-  u8 enc = db->enc;
+  u8 enc = ENC(db);
   u8 initbusy = db->init.busy;
+  CollSeq *pColl;
 
-  CollSeq *pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
+  pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
   if( !initbusy && (!pColl || !pColl->xCmp) ){
     pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
     if( !pColl ){
@@ -1138,7 +1241,7 @@
 ** 1 chance in 2^32.  So we're safe enough.
 */
 void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){
-  sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].schema_cookie+1, 0);
+  sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, 0);
   sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
 }
 
@@ -1186,7 +1289,7 @@
 ** table.  Memory to hold the text of the statement is obtained
 ** from sqliteMalloc() and must be freed by the calling function.
 */
-static char *createTableStmt(Table *p){
+static char *createTableStmt(Table *p, int isTemp){
   int i, k, n;
   char *zStmt;
   char *zSep, *zSep2, *zEnd, *z;
@@ -1212,7 +1315,7 @@
   n += 35 + 6*p->nCol;
   zStmt = sqliteMallocRaw( n );
   if( zStmt==0 ) return 0;
-  strcpy(zStmt, !OMIT_TEMPDB&&p->iDb==1 ? "CREATE TEMP TABLE ":"CREATE TABLE ");
+  strcpy(zStmt, !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE ");
   k = strlen(zStmt);
   identPut(zStmt, &k, p->zName);
   zStmt[k++] = '(';
@@ -1259,13 +1362,40 @@
 ){
   Table *p;
   sqlite3 *db = pParse->db;
+  int iDb;
 
-  if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3_malloc_failed ) return;
+  if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3MallocFailed() ) {
+    return;
+  }
   p = pParse->pNewTable;
   if( p==0 ) return;
 
   assert( !db->init.busy || !pSelect );
 
+  iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
+
+#ifndef SQLITE_OMIT_CHECK
+  /* Resolve names in all CHECK constraint expressions.
+  */
+  if( p->pCheck ){
+    SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
+    NameContext sNC;                /* Name context for pParse->pNewTable */
+
+    memset(&sNC, 0, sizeof(sNC));
+    memset(&sSrc, 0, sizeof(sSrc));
+    sSrc.nSrc = 1;
+    sSrc.a[0].zName = p->zName;
+    sSrc.a[0].pTab = p;
+    sSrc.a[0].iCursor = -1;
+    sNC.pParse = pParse;
+    sNC.pSrcList = &sSrc;
+    sNC.isCheck = 1;
+    if( sqlite3ExprResolveNames(&sNC, p->pCheck) ){
+      return;
+    }
+  }
+#endif /* !defined(SQLITE_OMIT_CHECK) */
+
   /* If the db->init.busy is 1 it means we are reading the SQL off the
   ** "sqlite_master" or "sqlite_temp_master" table on the disk.
   ** So do not write to the disk again.  Extract the root page number
@@ -1318,11 +1448,16 @@
     ** Once the SELECT has been coded by sqlite3Select(), it is in a
     ** suitable state to query for the column names and types to be used
     ** by the new table.
+    **
+    ** A shared-cache write-lock is not required to write to the new table,
+    ** as a schema-lock must have already been obtained to create it. Since
+    ** a schema-lock excludes all other database users, the write-lock would
+    ** be redundant.
     */
     if( pSelect ){
       Table *pSelTab;
       sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
-      sqlite3VdbeAddOp(v, OP_Integer, p->iDb, 0);
+      sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
       sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0);
       pParse->nTab = 2;
       sqlite3Select(pParse, pSelect, SRT_Table, 1, 0, 0, 0, 0);
@@ -1341,7 +1476,7 @@
 
     /* Compute the complete text of the CREATE statement */
     if( pSelect ){
-      zStmt = createTableStmt(p);
+      zStmt = createTableStmt(p, p->pSchema==pParse->db->aDb[1].pSchema);
     }else{
       n = pEnd->z - pParse->sNameToken.z + 1;
       zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z);
@@ -1357,22 +1492,22 @@
       "UPDATE %Q.%s "
          "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q "
        "WHERE rowid=#1",
-      db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb),
+      db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
       zType,
       p->zName,
       p->zName,
       zStmt
     );
     sqliteFree(zStmt);
-    sqlite3ChangeCookie(db, v, p->iDb);
+    sqlite3ChangeCookie(db, v, iDb);
 
 #ifndef SQLITE_OMIT_AUTOINCREMENT
     /* Check to see if we need to create an sqlite_sequence table for
     ** keeping track of autoincrement keys.
     */
     if( p->autoInc ){
-      Db *pDb = &db->aDb[p->iDb];
-      if( pDb->pSeqTab==0 ){
+      Db *pDb = &db->aDb[iDb];
+      if( pDb->pSchema->pSeqTab==0 ){
         sqlite3NestedParse(pParse,
           "CREATE TABLE %Q.sqlite_sequence(name,seq)",
           pDb->zName
@@ -1382,7 +1517,7 @@
 #endif
 
     /* Reparse everything to update our internal data structures */
-    sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
+    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
         sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
   }
 
@@ -1392,8 +1527,8 @@
   if( db->init.busy && pParse->nErr==0 ){
     Table *pOld;
     FKey *pFKey; 
-    Db *pDb = &db->aDb[p->iDb];
-    pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p);
+    Schema *pSchema = p->pSchema;
+    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p);
     if( pOld ){
       assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
       return;
@@ -1401,8 +1536,8 @@
 #ifndef SQLITE_OMIT_FOREIGN_KEY
     for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
       int nTo = strlen(pFKey->zTo) + 1;
-      pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo);
-      sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey);
+      pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo);
+      sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey);
     }
 #endif
     pParse->pNewTable = 0;
@@ -1411,9 +1546,14 @@
 
 #ifndef SQLITE_OMIT_ALTERTABLE
     if( !p->pSelect ){
+      const char *zName = (const char *)pParse->sNameToken.z;
+      int nName;
       assert( !pSelect && pCons && pEnd );
-      if( pCons->z==0 ) pCons = pEnd;
-      p->addColOffset = 13 + (pCons->z - pParse->sNameToken.z);
+      if( pCons->z==0 ){
+        pCons = pEnd;
+      }
+      nName = (const char *)pCons->z - zName;
+      p->addColOffset = 13 + sqlite3utf8CharLen(zName, nName);
     }
 #endif
   }
@@ -1437,20 +1577,22 @@
   Token sEnd;
   DbFixer sFix;
   Token *pName;
+  int iDb;
 
   if( pParse->nVar>0 ){
     sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
     sqlite3SelectDelete(pSelect);
     return;
   }
-  sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1);
+  sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0);
   p = pParse->pNewTable;
   if( p==0 || pParse->nErr ){
     sqlite3SelectDelete(pSelect);
     return;
   }
   sqlite3TwoPartName(pParse, pName1, pName2, &pName);
-  if( sqlite3FixInit(&sFix, pParse, p->iDb, "view", pName)
+  iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
+  if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
     && sqlite3FixSelect(&sFix, pSelect)
   ){
     sqlite3SelectDelete(pSelect);
@@ -1464,6 +1606,9 @@
   */
   p->pSelect = sqlite3SelectDup(pSelect);
   sqlite3SelectDelete(pSelect);
+  if( sqlite3MallocFailed() ){
+    return;
+  }
   if( !pParse->db->init.busy ){
     sqlite3ViewGetColumnNames(pParse, p);
   }
@@ -1517,12 +1662,10 @@
   ** Actually, this error is caught previously and so the following test
   ** should always fail.  But we will leave it in place just to be safe.
   */
-#if 0
   if( pTable->nCol<0 ){
     sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
     return 1;
   }
-#endif
   assert( pTable->nCol>=0 );
 
   /* If we get this far, it means we need to compute the table names.
@@ -1534,24 +1677,28 @@
   */
   assert( pTable->pSelect );
   pSel = sqlite3SelectDup(pTable->pSelect);
-  n = pParse->nTab;
-  sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
-  pTable->nCol = -1;
-  pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
-  pParse->nTab = n;
-  if( pSelTab ){
-    assert( pTable->aCol==0 );
-    pTable->nCol = pSelTab->nCol;
-    pTable->aCol = pSelTab->aCol;
-    pSelTab->nCol = 0;
-    pSelTab->aCol = 0;
-    sqlite3DeleteTable(0, pSelTab);
-    DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
-  }else{
-    pTable->nCol = 0;
+  if( pSel ){
+    n = pParse->nTab;
+    sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
+    pTable->nCol = -1;
+    pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
+    pParse->nTab = n;
+    if( pSelTab ){
+      assert( pTable->aCol==0 );
+      pTable->nCol = pSelTab->nCol;
+      pTable->aCol = pSelTab->aCol;
+      pSelTab->nCol = 0;
+      pSelTab->aCol = 0;
+      sqlite3DeleteTable(0, pSelTab);
+      pTable->pSchema->flags |= DB_UnresetViews;
+    }else{
+      pTable->nCol = 0;
+      nErr++;
+    }
+    sqlite3SelectDelete(pSel);
+  } else {
     nErr++;
   }
-  sqlite3SelectDelete(pSel);
   return nErr;  
 }
 #endif /* SQLITE_OMIT_VIEW */
@@ -1563,7 +1710,7 @@
 static void sqliteViewResetAll(sqlite3 *db, int idx){
   HashElem *i;
   if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
-  for(i=sqliteHashFirst(&db->aDb[idx].tblHash); i; i=sqliteHashNext(i)){
+  for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
     Table *pTab = sqliteHashData(i);
     if( pTab->pSelect ){
       sqliteResetColumnNames(pTab);
@@ -1580,26 +1727,37 @@
 ** used by SQLite when the btree layer moves a table root page. The
 ** root-page of a table or index in database iDb has changed from iFrom
 ** to iTo.
+**
+** Ticket #1728:  The symbol table might still contain information
+** on tables and/or indices that are the process of being deleted.
+** If you are unlucky, one of those deleted indices or tables might
+** have the same rootpage number as the real table or index that is
+** being moved.  So we cannot stop searching after the first match 
+** because the first match might be for one of the deleted indices
+** or tables and not the table/index that is actually being moved.
+** We must continue looping until all tables and indices with
+** rootpage==iFrom have been converted to have a rootpage of iTo
+** in order to be certain that we got the right one.
 */
 #ifndef SQLITE_OMIT_AUTOVACUUM
 void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
   HashElem *pElem;
-  
-  for(pElem=sqliteHashFirst(&pDb->tblHash); pElem; pElem=sqliteHashNext(pElem)){
+  Hash *pHash;
+
+  pHash = &pDb->pSchema->tblHash;
+  for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
     Table *pTab = sqliteHashData(pElem);
     if( pTab->tnum==iFrom ){
       pTab->tnum = iTo;
-      return;
     }
   }
-  for(pElem=sqliteHashFirst(&pDb->idxHash); pElem; pElem=sqliteHashNext(pElem)){
+  pHash = &pDb->pSchema->idxHash;
+  for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
     Index *pIdx = sqliteHashData(pElem);
     if( pIdx->tnum==iFrom ){
       pIdx->tnum = iTo;
-      return;
     }
   }
-  assert(0);
 }
 #endif
 
@@ -1636,9 +1794,10 @@
 static void destroyTable(Parse *pParse, Table *pTab){
 #ifdef SQLITE_OMIT_AUTOVACUUM
   Index *pIdx;
-  destroyRootPage(pParse, pTab->tnum, pTab->iDb);
+  int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+  destroyRootPage(pParse, pTab->tnum, iDb);
   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-    destroyRootPage(pParse, pIdx->tnum, pIdx->iDb);
+    destroyRootPage(pParse, pIdx->tnum, iDb);
   }
 #else
   /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
@@ -1669,14 +1828,18 @@
     }
     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
       int iIdx = pIdx->tnum;
-      assert( pIdx->iDb==pTab->iDb );
+      assert( pIdx->pSchema==pTab->pSchema );
       if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
         iLargest = iIdx;
       }
     }
-    if( iLargest==0 ) return;
-    destroyRootPage(pParse, iLargest, pTab->iDb);
-    iDestroyed = iLargest;
+    if( iLargest==0 ){
+      return;
+    }else{
+      int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+      destroyRootPage(pParse, iLargest, iDb);
+      iDestroyed = iLargest;
+    }
   }
 #endif
 }
@@ -1685,24 +1848,31 @@
 ** This routine is called to do the work of a DROP TABLE statement.
 ** pName is the name of the table to be dropped.
 */
-void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
+void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
   Table *pTab;
   Vdbe *v;
   sqlite3 *db = pParse->db;
   int iDb;
 
-  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table;
+  if( pParse->nErr || sqlite3MallocFailed() ){
+    goto exit_drop_table;
+  }
   assert( pName->nSrc==1 );
   pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);
 
-  if( pTab==0 ) goto exit_drop_table;
-  iDb = pTab->iDb;
+  if( pTab==0 ){
+    if( noErr ){
+      sqlite3ErrorClear(pParse);
+    }
+    goto exit_drop_table;
+  }
+  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   assert( iDb>=0 && iDb<db->nDb );
 #ifndef SQLITE_OMIT_AUTHORIZATION
   {
     int code;
-    const char *zTab = SCHEMA_TABLE(pTab->iDb);
-    const char *zDb = db->aDb[pTab->iDb].zName;
+    const char *zTab = SCHEMA_TABLE(iDb);
+    const char *zDb = db->aDb[iDb].zName;
     if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
       goto exit_drop_table;
     }
@@ -1727,7 +1897,7 @@
     }
   }
 #endif
-  if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){
+  if( pTab->readOnly || pTab==db->aDb[iDb].pSchema->pSeqTab ){
     sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
     goto exit_drop_table;
   }
@@ -1752,7 +1922,6 @@
   v = sqlite3GetVdbe(pParse);
   if( v ){
     Trigger *pTrigger;
-    int iDb = pTab->iDb;
     Db *pDb = &db->aDb[iDb];
     sqlite3BeginWriteOperation(pParse, 0, iDb);
 
@@ -1762,8 +1931,9 @@
     */
     pTrigger = pTab->pTrigger;
     while( pTrigger ){
-      assert( pTrigger->iDb==iDb || pTrigger->iDb==1 );
-      sqlite3DropTriggerPtr(pParse, pTrigger, 1);
+      assert( pTrigger->pSchema==pTab->pSchema || 
+          pTrigger->pSchema==db->aDb[1].pSchema );
+      sqlite3DropTriggerPtr(pParse, pTrigger);
       pTrigger = pTrigger->pNext;
     }
 
@@ -1958,21 +2128,18 @@
   int addr1;                     /* Address of top of loop */
   int tnum;                      /* Root page of index */
   Vdbe *v;                       /* Generate code into this virtual machine */
+  KeyInfo *pKey;                 /* KeyInfo for index */
+  int iDb = sqlite3SchemaToIndex(pParse->db, pIndex->pSchema);
 
 #ifndef SQLITE_OMIT_AUTHORIZATION
   if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
-      pParse->db->aDb[pIndex->iDb].zName ) ){
+      pParse->db->aDb[iDb].zName ) ){
     return;
   }
 #endif
 
-  /* Ensure all the required collation sequences are available. This
-  ** routine will invoke the collation-needed callback if necessary (and
-  ** if one has been registered).
-  */
-  if( sqlite3CheckIndexCollSeq(pParse, pIndex) ){
-    return;
-  }
+  /* Require a write-lock on the table to perform this operation */
+  sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
 
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) return;
@@ -1981,12 +2148,12 @@
     tnum = 0;
   }else{
     tnum = pIndex->tnum;
-    sqlite3VdbeAddOp(v, OP_Clear, tnum, pIndex->iDb);
+    sqlite3VdbeAddOp(v, OP_Clear, tnum, iDb);
   }
-  sqlite3VdbeAddOp(v, OP_Integer, pIndex->iDb, 0);
-  sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum,
-                    (char*)&pIndex->keyInfo, P3_KEYINFO);
-  sqlite3OpenTableForReading(v, iTab, pTab);
+  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
+  pKey = sqlite3IndexKeyinfo(pParse, pIndex);
+  sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, (char *)pKey, P3_KEYINFO_HANDOFF);
+  sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
   addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
   sqlite3GenerateIndexKey(v, pIndex, iTab);
   if( pIndex->onError!=OE_None ){
@@ -2027,21 +2194,31 @@
   ExprList *pList,   /* A list of columns to be indexed */
   int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
   Token *pStart,     /* The CREATE token that begins a CREATE TABLE statement */
-  Token *pEnd        /* The ")" that closes the CREATE INDEX statement */
+  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
+  int sortOrder,     /* Sort order of primary key when pList==NULL */
+  int ifNotExist     /* Omit error if index already exists */
 ){
-  Table *pTab = 0;   /* Table to be indexed */
-  Index *pIndex = 0; /* The index to be created */
-  char *zName = 0;
+  Table *pTab = 0;     /* Table to be indexed */
+  Index *pIndex = 0;   /* The index to be created */
+  char *zName = 0;     /* Name of the index */
+  int nName;           /* Number of characters in zName */
   int i, j;
-  Token nullId;    /* Fake token for an empty ID list */
-  DbFixer sFix;    /* For assigning database names to pTable */
+  Token nullId;        /* Fake token for an empty ID list */
+  DbFixer sFix;        /* For assigning database names to pTable */
+  int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
   sqlite3 *db = pParse->db;
+  Db *pDb;             /* The specific table containing the indexed database */
+  int iDb;             /* Index of the database that is being written */
+  Token *pName = 0;    /* Unqualified name of the index to create */
+  struct ExprList_item *pListItem; /* For looping over pList */
+  int nCol;
+  int nExtra = 0;
+  char *zExtra;
 
-  int iDb;          /* Index of the database that is being written */
-  Token *pName = 0; /* Unqualified name of the index to create */
+  if( pParse->nErr || sqlite3MallocFailed() ){
+    goto exit_create_index;
+  }
 
-  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_create_index;
-
   /*
   ** Find the table that is to be indexed.  Return early if not found.
   */
@@ -2060,7 +2237,7 @@
     ** is a temp table. If so, set the database to 1.
     */
     pTab = sqlite3SrcListLookup(pParse, pTblName);
-    if( pName2 && pName2->n==0 && pTab && pTab->iDb==1 ){
+    if( pName2 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
       iDb = 1;
     }
 #endif
@@ -2075,12 +2252,14 @@
     pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName, 
         pTblName->a[0].zDatabase);
     if( !pTab ) goto exit_create_index;
-    assert( iDb==pTab->iDb );
+    assert( db->aDb[iDb].pSchema==pTab->pSchema );
   }else{
     assert( pName==0 );
-    pTab =  pParse->pNewTable;
-    iDb = pTab->iDb;
+    pTab = pParse->pNewTable;
+    if( !pTab ) goto exit_create_index;
+    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   }
+  pDb = &db->aDb[iDb];
 
   if( pTab==0 || pParse->nErr ) goto exit_create_index;
   if( pTab->readOnly ){
@@ -2116,8 +2295,10 @@
     }
     if( !db->init.busy ){
       if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
-      if( sqlite3FindIndex(db, zName, db->aDb[iDb].zName)!=0 ){
-        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+      if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
+        if( !ifNotExist ){
+          sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+        }
         goto exit_create_index;
       }
       if( sqlite3FindTable(db, zName, 0)!=0 ){
@@ -2140,7 +2321,7 @@
   */
 #ifndef SQLITE_OMIT_AUTHORIZATION
   {
-    const char *zDb = db->aDb[iDb].zName;
+    const char *zDb = pDb->zName;
     if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
       goto exit_create_index;
     }
@@ -2157,56 +2338,96 @@
   ** So create a fake list to simulate this.
   */
   if( pList==0 ){
-    nullId.z = pTab->aCol[pTab->nCol-1].zName;
-    nullId.n = strlen(nullId.z);
+    nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName;
+    nullId.n = strlen((char*)nullId.z);
     pList = sqlite3ExprListAppend(0, 0, &nullId);
     if( pList==0 ) goto exit_create_index;
+    pList->a[0].sortOrder = sortOrder;
   }
 
+  /* Figure out how many bytes of space are required to store explicitly
+  ** specified collation sequence names.
+  */
+  for(i=0; i<pList->nExpr; i++){
+    Expr *pExpr = pList->a[i].pExpr;
+    if( pExpr ){
+      nExtra += (1 + strlen(pExpr->pColl->zName));
+    }
+  }
+
   /* 
   ** Allocate the index structure. 
   */
-  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + sizeof(int) +
-                        (sizeof(int)*2 + sizeof(CollSeq*))*pList->nExpr );
-  if( sqlite3_malloc_failed ) goto exit_create_index;
-  pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
-  pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
-  pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
+  nName = strlen(zName);
+  nCol = pList->nExpr;
+  pIndex = sqliteMalloc( 
+      sizeof(Index) +              /* Index structure  */
+      sizeof(int)*nCol +           /* Index.aiColumn   */
+      sizeof(int)*(nCol+1) +       /* Index.aiRowEst   */
+      sizeof(char *)*nCol +        /* Index.azColl     */
+      sizeof(u8)*nCol +            /* Index.aSortOrder */
+      nName + 1 +                  /* Index.zName      */
+      nExtra                       /* Collation sequence names */
+  );
+  if( sqlite3MallocFailed() ) goto exit_create_index;
+  pIndex->azColl = (char**)(&pIndex[1]);
+  pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
+  pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]);
+  pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]);
+  pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
+  zExtra = (char *)(&pIndex->zName[nName+1]);
   strcpy(pIndex->zName, zName);
   pIndex->pTable = pTab;
   pIndex->nColumn = pList->nExpr;
   pIndex->onError = onError;
   pIndex->autoIndex = pName==0;
-  pIndex->iDb = iDb;
+  pIndex->pSchema = db->aDb[iDb].pSchema;
 
+  /* Check to see if we should honor DESC requests on index columns
+  */
+  if( pDb->pSchema->file_format>=4 ){
+    sortOrderMask = -1;   /* Honor DESC */
+  }else{
+    sortOrderMask = 0;    /* Ignore DESC */
+  }
+
   /* Scan the names of the columns of the table to be indexed and
   ** load the column indices into the Index structure.  Report an error
   ** if any column is not found.
   */
-  for(i=0; i<pList->nExpr; i++){
-    for(j=0; j<pTab->nCol; j++){
-      if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
+  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
+    const char *zColName = pListItem->zName;
+    Column *pTabCol;
+    int requestedSortOrder;
+    char *zColl;                   /* Collation sequence */
+
+    for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
+      if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
     }
     if( j>=pTab->nCol ){
       sqlite3ErrorMsg(pParse, "table %s has no column named %s",
-        pTab->zName, pList->a[i].zName);
+        pTab->zName, zColName);
       goto exit_create_index;
     }
     pIndex->aiColumn[i] = j;
-    if( pList->a[i].pExpr ){
-      assert( pList->a[i].pExpr->pColl );
-      pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl;
+    if( pListItem->pExpr ){
+      assert( pListItem->pExpr->pColl );
+      zColl = zExtra;
+      strcpy(zExtra, pListItem->pExpr->pColl->zName);
+      zExtra += (strlen(zColl) + 1);
     }else{
-      pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;
+      zColl = pTab->aCol[j].zColl;
+      if( !zColl ){
+        zColl = db->pDfltColl->zName;
+      }
     }
-    assert( pIndex->keyInfo.aColl[i] );
-    if( !db->init.busy && 
-        sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i]) 
-    ){
+    if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){
       goto exit_create_index;
     }
+    pIndex->azColl[i] = zColl;
+    requestedSortOrder = pListItem->sortOrder & sortOrderMask;
+    pIndex->aSortOrder[i] = requestedSortOrder;
   }
-  pIndex->keyInfo.nField = pList->nExpr;
   sqlite3DefaultRowEst(pIndex);
 
   if( pTab==pParse->pNewTable ){
@@ -2232,8 +2453,11 @@
 
       if( pIdx->nColumn!=pIndex->nColumn ) continue;
       for(k=0; k<pIdx->nColumn; k++){
+        const char *z1 = pIdx->azColl[k];
+        const char *z2 = pIndex->azColl[k];
         if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
-        if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
+        if( pIdx->aSortOrder[k]!=pIndex->aSortOrder[k] ) break;
+        if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
       }
       if( k==pIdx->nColumn ){
         if( pIdx->onError!=pIndex->onError ){
@@ -2262,7 +2486,7 @@
   */
   if( db->init.busy ){
     Index *p;
-    p = sqlite3HashInsert(&db->aDb[pIndex->iDb].idxHash, 
+    p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
                          pIndex->zName, strlen(pIndex->zName)+1, pIndex);
     if( p ){
       assert( p==pIndex );  /* Malloc must have failed */
@@ -2297,6 +2521,7 @@
     v = sqlite3GetVdbe(pParse);
     if( v==0 ) goto exit_create_index;
 
+
     /* Create the rootpage for the index
     */
     sqlite3BeginWriteOperation(pParse, 1, iDb);
@@ -2375,6 +2600,22 @@
 }
 
 /*
+** Generate code to make sure the file format number is at least minFormat.
+** The generated code will increase the file format number if necessary.
+*/
+void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
+  Vdbe *v;
+  v = sqlite3GetVdbe(pParse);
+  if( v ){
+    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
+    sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
+    sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
+    sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
+    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
+  }
+}
+
+/*
 ** Fill the Index.aiRowEst[] array with default information - information
 ** to be used when we have not run the ANALYZE command.
 **
@@ -2409,12 +2650,13 @@
 ** This routine will drop an existing named index.  This routine
 ** implements the DROP INDEX statement.
 */
-void sqlite3DropIndex(Parse *pParse, SrcList *pName){
+void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
   Index *pIndex;
   Vdbe *v;
   sqlite3 *db = pParse->db;
+  int iDb;
 
-  if( pParse->nErr || sqlite3_malloc_failed ){
+  if( pParse->nErr || sqlite3MallocFailed() ){
     goto exit_drop_index;
   }
   assert( pName->nSrc==1 );
@@ -2423,7 +2665,9 @@
   }
   pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
   if( pIndex==0 ){
-    sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
+    if( !ifExists ){
+      sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
+    }
     pParse->checkSchema = 1;
     goto exit_drop_index;
   }
@@ -2432,16 +2676,17 @@
       "or PRIMARY KEY constraint cannot be dropped", 0);
     goto exit_drop_index;
   }
+  iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
 #ifndef SQLITE_OMIT_AUTHORIZATION
   {
     int code = SQLITE_DROP_INDEX;
     Table *pTab = pIndex->pTable;
-    const char *zDb = db->aDb[pIndex->iDb].zName;
-    const char *zTab = SCHEMA_TABLE(pIndex->iDb);
+    const char *zDb = db->aDb[iDb].zName;
+    const char *zTab = SCHEMA_TABLE(iDb);
     if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
       goto exit_drop_index;
     }
-    if( !OMIT_TEMPDB && pIndex->iDb ) code = SQLITE_DROP_TEMP_INDEX;
+    if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX;
     if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
       goto exit_drop_index;
     }
@@ -2451,7 +2696,6 @@
   /* Generate code to remove the index and from the master table */
   v = sqlite3GetVdbe(pParse);
   if( v ){
-    int iDb = pIndex->iDb;
     sqlite3NestedParse(pParse,
        "DELETE FROM %Q.%s WHERE name=%Q",
        db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
@@ -2611,6 +2855,7 @@
   pItem->zName = sqlite3NameFromToken(pTable);
   pItem->zDatabase = sqlite3NameFromToken(pDatabase);
   pItem->iCursor = -1;
+  pItem->isPopulated = 0;
   pList->nSrc++;
   return pList;
 }
@@ -2621,11 +2866,14 @@
 void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
   int i;
   struct SrcList_item *pItem;
-  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
-    if( pItem->iCursor>=0 ) break;
-    pItem->iCursor = pParse->nTab++;
-    if( pItem->pSelect ){
-      sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
+  assert(pList || sqlite3MallocFailed() );
+  if( pList ){
+    for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
+      if( pItem->iCursor>=0 ) break;
+      pItem->iCursor = pParse->nTab++;
+      if( pItem->pSelect ){
+        sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
+      }
     }
   }
 }
@@ -2667,7 +2915,7 @@
   int i;
 
   if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
-  if( pParse->nErr || sqlite3_malloc_failed ) return;
+  if( pParse->nErr || sqlite3MallocFailed() ) return;
   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
 
   v = sqlite3GetVdbe(pParse);
@@ -2688,7 +2936,7 @@
   Vdbe *v;
 
   if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
-  if( pParse->nErr || sqlite3_malloc_failed ) return;
+  if( pParse->nErr || sqlite3MallocFailed() ) return;
   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
 
   v = sqlite3GetVdbe(pParse);
@@ -2705,7 +2953,7 @@
   Vdbe *v;
 
   if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
-  if( pParse->nErr || sqlite3_malloc_failed ) return;
+  if( pParse->nErr || sqlite3MallocFailed() ) return;
   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
 
   v = sqlite3GetVdbe(pParse);
@@ -2718,7 +2966,7 @@
 ** 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){
+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);
@@ -2737,6 +2985,7 @@
         return 1;
       }
     }
+    assert( db->aDb[1].pSchema );
   }
   return 0;
 }
@@ -2777,11 +3026,11 @@
   if( iDb>=0 ){
     assert( iDb<db->nDb );
     assert( db->aDb[iDb].pBt!=0 || iDb==1 );
-    assert( iDb<32 );
+    assert( iDb<MAX_ATTACHED+2 );
     mask = 1<<iDb;
     if( (pParse->cookieMask & mask)==0 ){
       pParse->cookieMask |= mask;
-      pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie;
+      pParse->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
       if( !OMIT_TEMPDB && iDb==1 ){
         sqlite3OpenTempDatabase(pParse);
       }
@@ -2825,12 +3074,13 @@
 ** true if it does and false if it does not.
 */
 #ifndef SQLITE_OMIT_REINDEX
-static int collationMatch(CollSeq *pColl, Index *pIndex){
-  int n = pIndex->keyInfo.nField;
-  CollSeq **pp = pIndex->keyInfo.aColl;
-  while( n-- ){
-    if( *pp==pColl ) return 1;
-    pp++;
+static int collationMatch(const char *zColl, Index *pIndex){
+  int i;
+  for(i=0; i<pIndex->nColumn; i++){
+    const char *z = pIndex->azColl[i];
+    if( z==zColl || (z && zColl && 0==sqlite3StrICmp(z, zColl)) ){
+      return 1;
+    }
   }
   return 0;
 }
@@ -2841,12 +3091,13 @@
 ** If pColl==0 then recompute all indices of pTab.
 */
 #ifndef SQLITE_OMIT_REINDEX
-static void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
+static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
   Index *pIndex;              /* An index associated with pTab */
 
   for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
-    if( pColl==0 || collationMatch(pColl,pIndex) ){
-      sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);
+    if( zColl==0 || collationMatch(zColl, pIndex) ){
+      int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+      sqlite3BeginWriteOperation(pParse, 0, iDb);
       sqlite3RefillIndex(pParse, pIndex, -1);
     }
   }
@@ -2859,7 +3110,7 @@
 ** all indices everywhere.
 */
 #ifndef SQLITE_OMIT_REINDEX
-static void reindexDatabases(Parse *pParse, CollSeq *pColl){
+static void reindexDatabases(Parse *pParse, char const *zColl){
   Db *pDb;                    /* A single database */
   int iDb;                    /* The database index number */
   sqlite3 *db = pParse->db;   /* The database connection */
@@ -2867,10 +3118,10 @@
   Table *pTab;                /* A table in the database */
 
   for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
-    if( pDb==0 ) continue;
-    for(k=sqliteHashFirst(&pDb->tblHash);  k; k=sqliteHashNext(k)){
+    assert( pDb!=0 );
+    for(k=sqliteHashFirst(&pDb->pSchema->tblHash);  k; k=sqliteHashNext(k)){
       pTab = (Table*)sqliteHashData(k);
-      reindexTable(pParse, pTab, pColl);
+      reindexTable(pParse, pTab, zColl);
     }
   }
 }
@@ -2910,9 +3161,14 @@
     reindexDatabases(pParse, 0);
     return;
   }else if( pName2==0 || pName2->z==0 ){
-    pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0);
+    assert( pName1->z );
+    pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0);
     if( pColl ){
-      reindexDatabases(pParse, pColl);
+      char *zColl = sqliteStrNDup((const char *)pName1->z, pName1->n);
+      if( zColl ){
+        reindexDatabases(pParse, zColl);
+        sqliteFree(zColl);
+      }
       return;
     }
   }
@@ -2936,3 +3192,38 @@
   sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
 }
 #endif
+
+/*
+** Return a dynamicly allocated KeyInfo structure that can be used
+** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
+**
+** If successful, a pointer to the new structure is returned. In this case
+** the caller is responsible for calling sqliteFree() on the returned 
+** pointer. If an error occurs (out of memory or missing collation 
+** sequence), NULL is returned and the state of pParse updated to reflect
+** the error.
+*/
+KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
+  int i;
+  int nCol = pIdx->nColumn;
+  int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
+  KeyInfo *pKey = (KeyInfo *)sqliteMalloc(nBytes);
+
+  if( pKey ){
+    pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
+    assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
+    for(i=0; i<nCol; i++){
+      char *zColl = pIdx->azColl[i];
+      assert( zColl );
+      pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1);
+      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
+    }
+    pKey->nField = nCol;
+  }
+
+  if( pParse->nErr ){
+    sqliteFree(pKey);
+    pKey = 0;
+  }
+  return pKey;
+}

Modified: packages/libdbd-sqlite3-perl/trunk/callback.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/callback.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/callback.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -13,7 +13,7 @@
 ** This file contains functions used to access the internal hash tables
 ** of user defined functions and collation sequences.
 **
-** $Id: callback.c,v 1.3 2005/08/14 01:20:38 drh Exp $
+** $Id: callback.c,v 1.14 2006/03/14 11:08:28 drh Exp $
 */
 
 #include "sqliteInt.h"
@@ -29,17 +29,19 @@
   if( db->xCollNeeded ){
     char *zExternal = sqliteStrNDup(zName, nName);
     if( !zExternal ) return;
-    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
+    db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
     sqliteFree(zExternal);
   }
 #ifndef SQLITE_OMIT_UTF16
   if( db->xCollNeeded16 ){
     char const *zExternal;
-    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
-    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
+    sqlite3_value *pTmp = sqlite3ValueNew();
+    sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
     zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
-    if( !zExternal ) return;
-    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
+    if( zExternal ){
+      db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
+    }
+    sqlite3ValueFree(pTmp);
   }
 #endif
 }
@@ -90,14 +92,14 @@
 
   p = pColl;
   if( !p ){
-    p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
+    p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
   }
   if( !p || !p->xCmp ){
     /* No collation sequence of this type for this encoding is registered.
     ** Call the collation factory to see if it can supply us with one.
     */
     callCollNeeded(db, zName, nName);
-    p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
+    p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
   }
   if( p && !p->xCmp && synthCollSeq(db, p) ){
     p = 0;
@@ -128,6 +130,7 @@
       pParse->nErr++;
       return SQLITE_ERROR;
     }
+    assert( p==pColl );
   }
   return SQLITE_OK;
 }
@@ -175,8 +178,11 @@
       ** return the pColl pointer to be deleted (because it wasn't added
       ** to the hash table).
       */
-      assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) );
-      sqliteFree(pDel);
+      assert( !pDel || (sqlite3MallocFailed() && pDel==pColl) );
+      if( pDel ){
+        sqliteFree(pDel);
+        pColl = 0;
+      }
     }
   }
   return pColl;
@@ -197,7 +203,12 @@
   int nName,
   int create
 ){
-  CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);
+  CollSeq *pColl;
+  if( zName ){
+    pColl = findCollSeqEntry(db, zName, nName, create);
+  }else{
+    pColl = db->pDfltColl;
+  }
   assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
   assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
   if( pColl ) pColl += enc-1;
@@ -286,7 +297,7 @@
   ** new entry to the hash table and return it.
   */
   if( createFlag && bestmatch<6 && 
-      (pBest = sqliteMalloc(sizeof(*pBest)+nName)) ){
+      (pBest = sqliteMalloc(sizeof(*pBest)+nName))!=0 ){
     pBest->nArg = nArg;
     pBest->pNext = pFirst;
     pBest->iPrefEnc = enc;
@@ -303,3 +314,54 @@
   }
   return 0;
 }
+
+/*
+** Free all resources held by the schema structure. The void* argument points
+** at a Schema struct. This function does not call sqliteFree() on the 
+** pointer itself, it just cleans up subsiduary resources (i.e. the contents
+** of the schema hash tables).
+*/
+void sqlite3SchemaFree(void *p){
+  Hash temp1;
+  Hash temp2;
+  HashElem *pElem;
+  Schema *pSchema = (Schema *)p;
+
+  temp1 = pSchema->tblHash;
+  temp2 = pSchema->trigHash;
+  sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
+  sqlite3HashClear(&pSchema->aFKey);
+  sqlite3HashClear(&pSchema->idxHash);
+  for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
+    sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
+  }
+  sqlite3HashClear(&temp2);
+  sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
+  for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
+    Table *pTab = sqliteHashData(pElem);
+    sqlite3DeleteTable(0, pTab);
+  }
+  sqlite3HashClear(&temp1);
+  pSchema->pSeqTab = 0;
+  pSchema->flags &= ~DB_SchemaLoaded;
+}
+
+/*
+** Find and return the schema associated with a BTree.  Create
+** a new one if necessary.
+*/
+Schema *sqlite3SchemaGet(Btree *pBt){
+  Schema * p;
+  if( pBt ){
+    p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree);
+  }else{
+    p = (Schema *)sqliteMalloc(sizeof(Schema));
+  }
+  if( p && 0==p->file_format ){
+    sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
+    sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
+    sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
+    sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
+  }
+  return p;
+}

Copied: packages/libdbd-sqlite3-perl/trunk/complete.c (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/complete.c)

Modified: packages/libdbd-sqlite3-perl/trunk/date.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/date.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/date.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -16,7 +16,7 @@
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: date.c,v 1.45 2005/06/25 18:42:14 drh Exp $
+** $Id: date.c,v 1.54 2006/01/31 20:49:13 drh Exp $
 **
 ** NOTES:
 **
@@ -105,18 +105,20 @@
     val = 0;
     while( N-- ){
       if( !isdigit(*(u8*)zDate) ){
-        return cnt;
+        goto end_getDigits;
       }
       val = val*10 + *zDate - '0';
       zDate++;
     }
     if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
-      return cnt;
+      goto end_getDigits;
     }
     *pVal = val;
     zDate++;
     cnt++;
   }while( nextC );
+end_getDigits:
+  va_end(ap);
   return cnt;
 }
 
@@ -236,7 +238,7 @@
   if( p->validHMS ){
     p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
     if( p->validTZ ){
-      p->rJD += p->tz*60/86400.0;
+      p->rJD -= p->tz*60/86400.0;
       p->validHMS = 0;
       p->validTZ = 0;
     }
@@ -639,10 +641,10 @@
   int i;
   if( argc==0 ) return 1;
   if( SQLITE_NULL==sqlite3_value_type(argv[0]) || 
-      parseDateOrTime(sqlite3_value_text(argv[0]), p) ) return 1;
+      parseDateOrTime((char*)sqlite3_value_text(argv[0]), p) ) return 1;
   for(i=1; i<argc; i++){
     if( SQLITE_NULL==sqlite3_value_type(argv[i]) || 
-        parseModifier(sqlite3_value_text(argv[i]), p) ) return 1;
+        parseModifier((char*)sqlite3_value_text(argv[i]), p) ) return 1;
   }
   return 0;
 }
@@ -755,7 +757,7 @@
   DateTime x;
   int n, i, j;
   char *z;
-  const char *zFmt = sqlite3_value_text(argv[0]);
+  const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
   char zBuf[100];
   if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return;
   for(i=0, n=1; zFmt[i]; i++, n++){
@@ -816,20 +818,20 @@
         case 'H':  sprintf(&z[j],"%02d",x.h); j+=2; break;
         case 'W': /* Fall thru */
         case 'j': {
-          int n;             /* Number of days since 1st day of year */
+          int nDay;             /* Number of days since 1st day of year */
           DateTime y = x;
           y.validJD = 0;
           y.M = 1;
           y.D = 1;
           computeJD(&y);
-          n = x.rJD - y.rJD;
+          nDay = x.rJD - y.rJD;
           if( zFmt[i]=='W' ){
             int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
             wd = ((int)(x.rJD+0.5)) % 7;
-            sprintf(&z[j],"%02d",(n+7-wd)/7);
+            sprintf(&z[j],"%02d",(nDay+7-wd)/7);
             j += 2;
           }else{
-            sprintf(&z[j],"%03d",n+1);
+            sprintf(&z[j],"%03d",nDay+1);
             j += 3;
           }
           break;
@@ -974,7 +976,7 @@
   int i;
 
   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
+    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
         SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
   }
 #else
@@ -989,7 +991,7 @@
   int i;
 
   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-    sqlite3_create_function(db, aFuncs[i].zName, 0, SQLITE_UTF8, 
+    sqlite3CreateFunc(db, aFuncs[i].zName, 0, SQLITE_UTF8, 
         aFuncs[i].zFormat, currentTimeFunc, 0, 0);
   }
 #endif

Modified: packages/libdbd-sqlite3-perl/trunk/dbdimp.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/dbdimp.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/dbdimp.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,4 +1,4 @@
-/* $Id: dbdimp.c,v 1.57 2005/12/02 17:28:53 matt Exp $ */
+/* $Id: dbdimp.c,v 1.58 2006/04/10 01:50:05 matt Exp $ */
 
 #include "SQLiteXS.h"
 
@@ -740,7 +740,7 @@
     PUSHMARK(SP);
     for ( i=0; i < argc; i++ ) {
         SV *arg;
-        int len;
+        int len = sqlite3_value_bytes(value[i]);
         int type = sqlite3_value_type(value[i]);
         
         /* warn("func dispatch type: %d, value: %s\n", type, sqlite3_value_text(value[i])); */
@@ -752,10 +752,9 @@
                 arg = sv_2mortal(newSVnv(sqlite3_value_double(value[i])));
                 break;
             case SQLITE_TEXT:
-                arg = sv_2mortal(newSVpv(sqlite3_value_text(value[i]),0));
+                arg = sv_2mortal(newSVpv(sqlite3_value_text(value[i]),len));
                 break;
             case SQLITE_BLOB:
-                len = sqlite3_value_bytes(value[i]);
                 arg = sv_2mortal(newSVpvn(sqlite3_value_blob(value[i]), len));
                 break;
             default:

Modified: packages/libdbd-sqlite3-perl/trunk/dbdimp.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/dbdimp.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/dbdimp.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,4 +1,4 @@
-/* $Id: dbdimp.h,v 1.16 2005/08/05 21:21:02 matt Exp $ */
+/* $Id: dbdimp.h,v 1.17 2006/04/10 01:50:05 matt Exp $ */
 
 #ifndef _DBDIMP_H
 #define _DBDIMP_H   1
@@ -77,6 +77,7 @@
 
 static SV *
 newUTF8SVpv(char *s, STRLEN len) {
+  dTHX;
   register SV *sv;
 
   sv = newSVpv(s, len);
@@ -86,6 +87,7 @@
 
 static SV *
 newUTF8SVpvn(char *s, STRLEN len) {
+  dTHX;
   register SV *sv;
 
   sv = newSV(0);

Modified: packages/libdbd-sqlite3-perl/trunk/debian/changelog
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/debian/changelog	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/debian/changelog	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,3 +1,9 @@
+libdbd-sqlite3-perl (1.12-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Krzysztof Krzyzaniak (eloy) <eloy at debian.org>  Tue, 18 Apr 2006 17:19:48 +0200
+
 libdbd-sqlite3-perl (1.11-2) unstable; urgency=low
 
   * dbdimp.c: fix incorrect use of sqlite3_prepare(), unearthed by

Modified: packages/libdbd-sqlite3-perl/trunk/delete.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/delete.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/delete.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** in order to generate code for DELETE FROM statements.
 **
-** $Id: delete.c,v 1.111 2005/09/20 17:42:23 drh Exp $
+** $Id: delete.c,v 1.122 2006/02/24 02:53:50 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -59,14 +59,19 @@
 /*
 ** Generate code that will open a table for reading.
 */
-void sqlite3OpenTableForReading(
-  Vdbe *v,        /* Generate code into this VDBE */
+void sqlite3OpenTable(
+  Parse *p,       /* Generate code into this VDBE */
   int iCur,       /* The cursor number of the table */
-  Table *pTab     /* The table to be opened */
+  int iDb,        /* The database index in sqlite3.aDb[] */
+  Table *pTab,    /* The table to be opened */
+  int opcode      /* OP_OpenRead or OP_OpenWrite */
 ){
-  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+  Vdbe *v = sqlite3GetVdbe(p);
+  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
+  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
+  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
   VdbeComment((v, "# %s", pTab->zName));
-  sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
+  sqlite3VdbeAddOp(v, opcode, iCur, pTab->tnum);
   sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
 }
 
@@ -95,6 +100,7 @@
   AuthContext sContext;  /* Authorization context */
   int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
   NameContext sNC;       /* Name context to resolve expressions in */
+  int iDb;
 
 #ifndef SQLITE_OMIT_TRIGGER
   int isView;                  /* True if attempting to delete from a view */
@@ -102,7 +108,7 @@
 #endif
 
   sContext.pParse = 0;
-  if( pParse->nErr || sqlite3_malloc_failed ){
+  if( pParse->nErr || sqlite3MallocFailed() ){
     goto delete_from_cleanup;
   }
   db = pParse->db;
@@ -134,8 +140,9 @@
   if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
     goto delete_from_cleanup;
   }
-  assert( pTab->iDb<db->nDb );
-  zDb = db->aDb[pTab->iDb].zName;
+  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+  assert( iDb<db->nDb );
+  zDb = db->aDb[iDb].zName;
   if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
     goto delete_from_cleanup;
   }
@@ -176,7 +183,7 @@
     goto delete_from_cleanup;
   }
   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
-  sqlite3BeginWriteOperation(pParse, triggers_exist, pTab->iDb);
+  sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);
 
   /* If we are trying to delete from a view, realize that view into
   ** a ephemeral table.
@@ -203,20 +210,24 @@
       /* If counting rows deleted, just count the total number of
       ** entries in the table. */
       int endOfLoop = sqlite3VdbeMakeLabel(v);
-      int addr;
+      int addr2;
       if( !isView ){
-        sqlite3OpenTableForReading(v, iCur, pTab);
+        sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
       }
       sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
-      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
-      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
+      addr2 = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
+      sqlite3VdbeAddOp(v, OP_Next, iCur, addr2);
       sqlite3VdbeResolveLabel(v, endOfLoop);
       sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
     }
     if( !isView ){
-      sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
+      sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb);
+      if( !pParse->nested ){
+        sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
+      }
       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-        sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
+        assert( pIdx->pSchema==pTab->pSchema );
+        sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb);
       }
     }
   }
@@ -225,13 +236,6 @@
   ** the table and pick which records to delete.
   */
   else{
-    /* Ensure all required collation sequences are available. */
-    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-      if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
-        goto delete_from_cleanup;
-      }
-    }
-
     /* Begin the database scan
     */
     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
@@ -269,7 +273,7 @@
       addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
       if( !isView ){
         sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
-        sqlite3OpenTableForReading(v, iCur, pTab);
+        sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
       }
       sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
       sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
@@ -339,7 +343,7 @@
   if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
     sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
   }
 
 delete_from_cleanup:
@@ -378,8 +382,11 @@
 ){
   int addr;
   addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
-  sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
+  sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0);
   sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
+  if( count ){
+    sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
+  }
   sqlite3VdbeJumpHere(v, addr);
 }
 
@@ -400,7 +407,6 @@
 **       deleted.
 */
 void sqlite3GenerateRowIndexDelete(
-  sqlite3 *db,       /* The database containing the index */
   Vdbe *v,           /* Generate code into this VDBE */
   Table *pTab,       /* Table containing the row to be deleted */
   int iCur,          /* Cursor number for the table */

Copied: packages/libdbd-sqlite3-perl/trunk/earlyexit.pl (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/earlyexit.pl)

Modified: packages/libdbd-sqlite3-perl/trunk/experimental.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/experimental.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/experimental.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,9 +12,10 @@
 ** This file contains C code routines that are not a part of the official
 ** SQLite API.  These routines are unsupported.
 **
-** $Id: experimental.c,v 1.3 2005/03/02 05:18:30 drh Exp $
+** $Id: experimental.c,v 1.4 2006/01/31 20:49:13 drh Exp $
 */
 #include "sqliteInt.h"
+#include "os.h"
 
 /*
 ** Set all the parameters in the compiled SQL statement to NULL.

Modified: packages/libdbd-sqlite3-perl/trunk/expr.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/expr.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/expr.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.230 2005/09/23 21:11:54 drh Exp $
+** $Id: expr.c,v 1.257 2006/03/17 13:56:34 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -75,12 +75,10 @@
 char sqlite3CompareAffinity(Expr *pExpr, char aff2){
   char aff1 = sqlite3ExprAffinity(pExpr);
   if( aff1 && aff2 ){
-    /* Both sides of the comparison are columns. If one has numeric or
-    ** integer affinity, use that. Otherwise use no affinity.
+    /* Both sides of the comparison are columns. If one has numeric
+    ** affinity, use that. Otherwise use no affinity.
     */
-    if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){
-      return SQLITE_AFF_INTEGER;
-    }else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
+    if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
       return SQLITE_AFF_NUMERIC;
     }else{
       return SQLITE_AFF_NONE;
@@ -89,7 +87,6 @@
     /* Neither side of the comparison is a column.  Compare the
     ** results directly.
     */
-    /* return SQLITE_AFF_NUMERIC;  // Ticket #805 */
     return SQLITE_AFF_NONE;
   }else{
     /* One side is a column, the other is not. Use the columns affinity. */
@@ -129,11 +126,14 @@
 */
 int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
   char aff = comparisonAffinity(pExpr);
-  return 
-    (aff==SQLITE_AFF_NONE) ||
-    (aff==SQLITE_AFF_NUMERIC && idx_affinity==SQLITE_AFF_INTEGER) ||
-    (aff==SQLITE_AFF_INTEGER && idx_affinity==SQLITE_AFF_NUMERIC) ||
-    (aff==idx_affinity);
+  switch( aff ){
+    case SQLITE_AFF_NONE:
+      return 1;
+    case SQLITE_AFF_TEXT:
+      return idx_affinity==SQLITE_AFF_TEXT;
+    default:
+      return sqlite3IsNumericAffinity(idx_affinity);
+  }
 }
 
 /*
@@ -235,7 +235,7 @@
   if( p==0 ){
     return 0;  /* Malloc failed */
   }
-  depth = atoi(&pToken->z[1]);
+  depth = atoi((char*)&pToken->z[1]);
   p->iTable = pParse->nMem++;
   sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
   sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
@@ -263,7 +263,7 @@
 void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
   assert( pRight!=0 );
   assert( pLeft!=0 );
-  if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){
+  if( !sqlite3MallocFailed() && pRight->z && pLeft->z ){
     assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
     if( pLeft->dyn==0 && pRight->dyn==0 ){
       pExpr->span.z = pLeft->z;
@@ -280,6 +280,7 @@
 */
 Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
   Expr *pNew;
+  assert( pToken );
   pNew = sqliteMalloc( sizeof(Expr) );
   if( pNew==0 ){
     sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
@@ -287,12 +288,8 @@
   }
   pNew->op = TK_FUNCTION;
   pNew->pList = pList;
-  if( pToken ){
-    assert( pToken->dyn==0 );
-    pNew->token = *pToken;
-  }else{
-    pNew->token.z = 0;
-  }
+  assert( pToken->dyn==0 );
+  pNew->token = *pToken;
   pNew->span = pNew->token;
   return pNew;
 }
@@ -327,7 +324,7 @@
     /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
     ** use it as the variable number */
     int i;
-    pExpr->iTable = i = atoi(&pToken->z[1]);
+    pExpr->iTable = i = atoi((char*)&pToken->z[1]);
     if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
       sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
           SQLITE_MAX_VARIABLE_NUMBER);
@@ -355,10 +352,10 @@
       pExpr->iTable = ++pParse->nVar;
       if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
         pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
-        sqlite3ReallocOrFree((void**)&pParse->apVarExpr,
+        sqliteReallocOrFree((void**)&pParse->apVarExpr,
                        pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
       }
-      if( !sqlite3_malloc_failed ){
+      if( !sqlite3MallocFailed() ){
         assert( pParse->apVarExpr!=0 );
         pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
       }
@@ -415,7 +412,7 @@
   if( pNew==0 ) return 0;
   memcpy(pNew, p, sizeof(*pNew));
   if( p->token.z!=0 ){
-    pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
+    pNew->token.z = (u8*)sqliteStrNDup((char*)p->token.z, p->token.n);
     pNew->token.dyn = 1;
   }else{
     assert( pNew->token.z==0 );
@@ -432,7 +429,7 @@
   if( pTo->dyn ) sqliteFree((char*)pTo->z);
   if( pFrom->z ){
     pTo->n = pFrom->n;
-    pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
+    pTo->z = (u8*)sqliteStrNDup((char*)pFrom->z, pFrom->n);
     pTo->dyn = 1;
   }else{
     pTo->z = 0;
@@ -462,7 +459,8 @@
       sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
     }
     assert( pNewExpr==0 || pNewExpr->span.z!=0 
-            || pOldExpr->span.z==0 || sqlite3_malloc_failed );
+            || pOldExpr->span.z==0
+            || sqlite3MallocFailed() );
     pItem->zName = sqliteStrDup(pOldItem->zName);
     pItem->sortOrder = pOldItem->sortOrder;
     pItem->isAgg = pOldItem->isAgg;
@@ -497,6 +495,7 @@
     pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
     pNewItem->jointype = pOldItem->jointype;
     pNewItem->iCursor = pOldItem->iCursor;
+    pNewItem->isPopulated = pOldItem->isPopulated;
     pTab = pNewItem->pTab = pOldItem->pTab;
     if( pTab ){
       pTab->nRef++;
@@ -752,7 +751,7 @@
 int sqlite3ExprIsInteger(Expr *p, int *pValue){
   switch( p->op ){
     case TK_INTEGER: {
-      if( sqlite3GetInt32(p->token.z, pValue) ){
+      if( sqlite3GetInt32((char*)p->token.z, pValue) ){
         return 1;
       }
       break;
@@ -809,7 +808,7 @@
 ** in pParse and return non-zero.  Return zero on success.
 */
 static int lookupName(
-  Parse *pParse,      /* The parsing context */
+  Parse *pParse,       /* The parsing context */
   Token *pDbToken,     /* Name of the database containing table, or NULL */
   Token *pTableToken,  /* Name of table containing column, or NULL */
   Token *pColumnToken, /* Name of the column. */
@@ -831,22 +830,24 @@
   zDb = sqlite3NameFromToken(pDbToken);
   zTab = sqlite3NameFromToken(pTableToken);
   zCol = sqlite3NameFromToken(pColumnToken);
-  if( sqlite3_malloc_failed ){
+  if( sqlite3MallocFailed() ){
     goto lookupname_end;
   }
 
   pExpr->iTable = -1;
   while( pNC && cnt==0 ){
+    ExprList *pEList;
     SrcList *pSrcList = pNC->pSrcList;
-    ExprList *pEList = pNC->pEList;
 
-    /* assert( zTab==0 || pEList==0 ); */
     if( pSrcList ){
       for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
-        Table *pTab = pItem->pTab;
+        Table *pTab;
+        int iDb;
         Column *pCol;
   
-        if( pTab==0 ) continue;
+        pTab = pItem->pTab;
+        assert( pTab!=0 );
+        iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
         assert( pTab->nCol>0 );
         if( zTab ){
           if( pItem->zAlias ){
@@ -855,27 +856,28 @@
           }else{
             char *zTabName = pTab->zName;
             if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
-            if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
+            if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
               continue;
             }
           }
         }
         if( 0==(cntTab++) ){
           pExpr->iTable = pItem->iCursor;
-          pExpr->iDb = pTab->iDb;
+          pExpr->pSchema = pTab->pSchema;
           pMatch = pItem;
         }
         for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
           if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
+            const char *zColl = pTab->aCol[j].zColl;
             IdList *pUsing;
             cnt++;
             pExpr->iTable = pItem->iCursor;
             pMatch = pItem;
-            pExpr->iDb = pTab->iDb;
+            pExpr->pSchema = pTab->pSchema;
             /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
             pExpr->iColumn = j==pTab->iPKey ? -1 : j;
             pExpr->affinity = pTab->aCol[j].affinity;
-            pExpr->pColl = pTab->aCol[j].pColl;
+            pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
             if( pItem->jointype & JT_NATURAL ){
               /* If this match occurred in the left table of a natural join,
               ** then skip the right table to avoid a duplicate match */
@@ -919,17 +921,18 @@
       }
 
       if( pTab ){ 
-        int j;
+        int iCol;
         Column *pCol = pTab->aCol;
 
-        pExpr->iDb = pTab->iDb;
+        pExpr->pSchema = pTab->pSchema;
         cntTab++;
-        for(j=0; j < pTab->nCol; j++, pCol++) {
+        for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
           if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
+            const char *zColl = pTab->aCol[iCol].zColl;
             cnt++;
-            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
-            pExpr->affinity = pTab->aCol[j].affinity;
-            pExpr->pColl = pTab->aCol[j].pColl;
+            pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
+            pExpr->affinity = pTab->aCol[iCol].affinity;
+            pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
             pExpr->pTab = pTab;
             break;
           }
@@ -959,7 +962,7 @@
     ** Note that the expression in the result set should have already been
     ** resolved by the time the WHERE clause is resolved.
     */
-    if( cnt==0 && pEList!=0 && zTab==0 ){
+    if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
       for(j=0; j<pEList->nExpr; j++){
         char *zAs = pEList->a[j].zName;
         if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
@@ -1006,9 +1009,9 @@
     char *zErr;
     zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
     if( zDb ){
-      sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, 0);
+      sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0);
     }else if( zTab ){
-      sqlite3SetString(&z, zTab, ".", zCol, 0);
+      sqlite3SetString(&z, zTab, ".", zCol, (char*)0);
     }else{
       z = sqliteStrDup(zCol);
     }
@@ -1077,20 +1080,19 @@
 */
 static int nameResolverStep(void *pArg, Expr *pExpr){
   NameContext *pNC = (NameContext*)pArg;
-  SrcList *pSrcList;
   Parse *pParse;
 
   if( pExpr==0 ) return 1;
   assert( pNC!=0 );
-  pSrcList = pNC->pSrcList;
   pParse = pNC->pParse;
 
   if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1;
   ExprSetProperty(pExpr, EP_Resolved);
 #ifndef NDEBUG
-  if( pSrcList ){
+  if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
+    SrcList *pSrcList = pNC->pSrcList;
     int i;
-    for(i=0; i<pSrcList->nSrc; i++){
+    for(i=0; i<pNC->pSrcList->nSrc; i++){
       assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
     }
   }
@@ -1149,9 +1151,9 @@
       int nId;                    /* Number of characters in function name */
       const char *zId;            /* The function name. */
       FuncDef *pDef;              /* Information about the function */
-      int enc = pParse->db->enc;  /* The database encoding */
+      int enc = ENC(pParse->db);  /* The database encoding */
 
-      zId = pExpr->token.z;
+      zId = (char*)pExpr->token.z;
       nId = pExpr->token.n;
       pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
       if( pDef==0 ){
@@ -1197,13 +1199,27 @@
     case TK_IN: {
       if( pExpr->pSelect ){
         int nRef = pNC->nRef;
+#ifndef SQLITE_OMIT_CHECK
+        if( pNC->isCheck ){
+          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
+        }
+#endif
         sqlite3SelectResolve(pParse, pExpr->pSelect, pNC);
         assert( pNC->nRef>=nRef );
         if( nRef!=pNC->nRef ){
           ExprSetProperty(pExpr, EP_VarSelect);
         }
       }
+      break;
     }
+#ifndef SQLITE_OMIT_CHECK
+    case TK_VARIABLE: {
+      if( pNC->isCheck ){
+        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
+      }
+      break;
+    }
+#endif
   }
   return 0;
 }
@@ -1261,17 +1277,16 @@
 
 
 /*
-** Generate code for subqueries and IN operators.
+** Generate code for scalar subqueries used as an expression
+** and IN operators.  Examples:
 **
-** IN operators comes in two forms:
+**     (SELECT a FROM b)          -- subquery
+**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
+**     x IN (4,5,11)              -- IN operator with list on right-hand side
+**     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
 **
-**           expr IN (exprlist)
-** and
-**           expr IN (SELECT ...)
-**
-** The first form is handled by creating a set holding the list
-** of allowed values.  The second form causes the SELECT to generate 
-** a temporary table.
+** The pExpr parameter describes the expression that contains the IN
+** operator or subquery.
 */
 #ifndef SQLITE_OMIT_SUBQUERY
 void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
@@ -1293,7 +1308,7 @@
     int mem = pParse->nMem++;
     sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
     testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
-    assert( testAddr>0 || sqlite3_malloc_failed );
+    assert( testAddr>0 || sqlite3MallocFailed() );
     sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
   }
 
@@ -1366,11 +1381,7 @@
           ** expression we need to rerun this code each time.
           */
           if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){
-            VdbeOp *aOp = sqlite3VdbeGetOp(v, testAddr-1);
-            int i;
-            for(i=0; i<3; i++){
-              aOp[i].opcode = OP_Noop;
-            }
+            sqlite3VdbeChangeToNoop(v, testAddr-1, 3);
             testAddr = 0;
           }
 
@@ -1390,21 +1401,25 @@
       ** value of this select in a memory cell and record the number
       ** of the memory cell in iColumn.
       */
+      static const Token one = { (u8*)"1", 0, 1 };
+      Select *pSel;
+      int iMem;
       int sop;
-      Select *pSel;
 
-      pExpr->iColumn = pParse->nMem++;
+      pExpr->iColumn = iMem = pParse->nMem++;
       pSel = pExpr->pSelect;
       if( pExpr->op==TK_SELECT ){
         sop = SRT_Mem;
+        sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0);
+        VdbeComment((v, "# Init subquery result"));
       }else{
-        static const Token one = { "1", 0, 1 };
         sop = SRT_Exists;
-        sqlite3ExprListDelete(pSel->pEList);
-        pSel->pEList = sqlite3ExprListAppend(0, 
-                          sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
+        sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem);
+        VdbeComment((v, "# Init EXISTS result"));
       }
-      sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0);
+      sqlite3ExprDelete(pSel->pLimit);
+      pSel->pLimit = sqlite3Expr(TK_INTEGER, 0, 0, &one);
+      sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0);
       break;
     }
   }
@@ -1444,6 +1459,8 @@
 void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
   Vdbe *v = pParse->pVdbe;
   int op;
+  int stackChng = 1;    /* Amount of change to stack depth */
+
   if( v==0 ) return;
   if( pExpr==0 ){
     sqlite3VdbeAddOp(v, OP_Null, 0, 0);
@@ -1465,16 +1482,27 @@
       /* Otherwise, fall thru into the TK_COLUMN case */
     }
     case TK_COLUMN: {
-      if( pExpr->iColumn>=0 ){
-        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
-        sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn);
+      if( pExpr->iTable<0 ){
+        /* This only happens when coding check constraints */
+        assert( pParse->ckOffset>0 );
+        sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
+      }else if( pExpr->iColumn>=0 ){
+        Table *pTab = pExpr->pTab;
+        int iCol = pExpr->iColumn;
+        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, iCol);
+        sqlite3ColumnDefault(v, pTab, iCol);
+#ifndef SQLITE_OMIT_FLOATING_POINT
+        if( pTab && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){
+          sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0);
+        }
+#endif
       }else{
         sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0);
       }
       break;
     }
     case TK_INTEGER: {
-      codeInteger(v, pExpr->token.z, pExpr->token.n);
+      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n);
       break;
     }
     case TK_FLOAT:
@@ -1482,7 +1510,7 @@
       assert( TK_FLOAT==OP_Real );
       assert( TK_STRING==OP_String8 );
       sqlite3DequoteExpr(pExpr);
-      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
+      sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
       break;
     }
     case TK_NULL: {
@@ -1495,7 +1523,7 @@
       const char *z;
       assert( TK_BLOB==OP_HexBlob );
       n = pExpr->token.n - 3;
-      z = pExpr->token.z + 2;
+      z = (char*)pExpr->token.z + 2;
       assert( n>=0 );
       if( n==0 ){
         z = "";
@@ -1507,7 +1535,7 @@
     case TK_VARIABLE: {
       sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
       if( pExpr->token.n>1 ){
-        sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
+        sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n);
       }
       break;
     }
@@ -1518,16 +1546,17 @@
 #ifndef SQLITE_OMIT_CAST
     case TK_CAST: {
       /* Expressions of the form:   CAST(pLeft AS token) */
-      int aff, op;
+      int aff, to_op;
       sqlite3ExprCode(pParse, pExpr->pLeft);
       aff = sqlite3AffinityType(&pExpr->token);
-      switch( aff ){
-        case SQLITE_AFF_INTEGER:   op = OP_ToInt;      break;
-        case SQLITE_AFF_NUMERIC:   op = OP_ToNumeric;  break;
-        case SQLITE_AFF_TEXT:      op = OP_ToText;     break;
-        case SQLITE_AFF_NONE:      op = OP_ToBlob;     break;
-      }
-      sqlite3VdbeAddOp(v, op, 0, 0);
+      to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
+      assert( to_op==OP_ToText    || aff!=SQLITE_AFF_TEXT    );
+      assert( to_op==OP_ToBlob    || aff!=SQLITE_AFF_NONE    );
+      assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
+      assert( to_op==OP_ToInt     || aff!=SQLITE_AFF_INTEGER );
+      assert( to_op==OP_ToReal    || aff!=SQLITE_AFF_REAL    );
+      sqlite3VdbeAddOp(v, to_op, 0, 0);
+      stackChng = 0;
       break;
     }
 #endif /* SQLITE_OMIT_CAST */
@@ -1546,6 +1575,7 @@
       sqlite3ExprCode(pParse, pExpr->pLeft);
       sqlite3ExprCode(pParse, pExpr->pRight);
       codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
+      stackChng = -1;
       break;
     }
     case TK_AND:
@@ -1574,6 +1604,7 @@
       sqlite3ExprCode(pParse, pExpr->pLeft);
       sqlite3ExprCode(pParse, pExpr->pRight);
       sqlite3VdbeAddOp(v, op, 0, 0);
+      stackChng = -1;
       break;
     }
     case TK_UMINUS: {
@@ -1581,8 +1612,7 @@
       assert( pLeft );
       if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
         Token *p = &pLeft->token;
-        char *z = sqliteMalloc( p->n + 2 );
-        sprintf(z, "-%.*s", p->n, p->z);
+        char *z = sqlite3MPrintf("-%.*s", p->n, p->z);
         if( pLeft->op==TK_FLOAT ){
           sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
         }else{
@@ -1599,6 +1629,7 @@
       assert( TK_NOT==OP_Not );
       sqlite3ExprCode(pParse, pExpr->pLeft);
       sqlite3VdbeAddOp(v, op, 0, 0);
+      stackChng = 0;
       break;
     }
     case TK_ISNULL:
@@ -1611,11 +1642,17 @@
       dest = sqlite3VdbeCurrentAddr(v) + 2;
       sqlite3VdbeAddOp(v, op, 1, dest);
       sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
+      stackChng = 0;
       break;
     }
     case TK_AGG_FUNCTION: {
       AggInfo *pInfo = pExpr->pAggInfo;
-      sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);
+      if( pInfo==0 ){
+        sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
+            &pExpr->span);
+      }else{
+        sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);
+      }
       break;
     }
     case TK_CONST_FUNC:
@@ -1627,9 +1664,9 @@
       const char *zId;
       int constMask = 0;
       int i;
-      u8 enc = pParse->db->enc;
+      u8 enc = ENC(pParse->db);
       CollSeq *pColl = 0;
-      zId = pExpr->token.z;
+      zId = (char*)pExpr->token.z;
       nId = pExpr->token.n;
       pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
       assert( pDef!=0 );
@@ -1647,12 +1684,15 @@
         sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
       }
       sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF);
+      stackChng = 1-nExpr;
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
     case TK_EXISTS:
     case TK_SELECT: {
-      sqlite3CodeSubselect(pParse, pExpr);
+      if( pExpr->iColumn==0 ){
+        sqlite3CodeSubselect(pParse, pExpr);
+      }
       sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
       VdbeComment((v, "# load subquery result"));
       break;
@@ -1660,6 +1700,7 @@
     case TK_IN: {
       int addr;
       char affinity;
+      int ckOffset = pParse->ckOffset;
       sqlite3CodeSubselect(pParse, pExpr);
 
       /* Figure out the affinity to use to create a key from the results
@@ -1669,6 +1710,7 @@
       affinity = comparisonAffinity(pExpr);
 
       sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
+      pParse->ckOffset = ckOffset+1;
 
       /* Code the <expr> from "<expr> IN (...)". The temporary table
       ** pExpr->iTable contains the values that make up the (...) set.
@@ -1705,6 +1747,7 @@
     case TK_UPLUS:
     case TK_AS: {
       sqlite3ExprCode(pParse, pExpr->pLeft);
+      stackChng = 0;
       break;
     }
     case TK_CASE: {
@@ -1763,17 +1806,23 @@
                  pExpr->iColumn == OE_Fail );
          sqlite3DequoteExpr(pExpr);
          sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
-                        pExpr->token.z, pExpr->token.n);
+                        (char*)pExpr->token.z, pExpr->token.n);
       } else {
          assert( pExpr->iColumn == OE_Ignore );
          sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
          sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
          VdbeComment((v, "# raise(IGNORE)"));
       }
+      stackChng = 0;
+      break;
     }
 #endif
-    break;
   }
+
+  if( pParse->ckOffset ){
+    pParse->ckOffset += stackChng;
+    assert( pParse->ckOffset );
+  }
 }
 
 #ifndef SQLITE_OMIT_TRIGGER
@@ -1840,6 +1889,7 @@
 void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
   Vdbe *v = pParse->pVdbe;
   int op = 0;
+  int ckOffset = pParse->ckOffset;
   if( v==0 || pExpr==0 ) return;
   op = pExpr->op;
   switch( op ){
@@ -1914,6 +1964,7 @@
       break;
     }
   }
+  pParse->ckOffset = ckOffset;
 }
 
 /*
@@ -1927,6 +1978,7 @@
 void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
   Vdbe *v = pParse->pVdbe;
   int op = 0;
+  int ckOffset = pParse->ckOffset;
   if( v==0 || pExpr==0 ) return;
 
   /* The value of pExpr->op and op are related as follows:
@@ -2023,6 +2075,7 @@
       break;
     }
   }
+  pParse->ckOffset = ckOffset;
 }
 
 /*
@@ -2031,10 +2084,8 @@
 */
 int sqlite3ExprCompare(Expr *pA, Expr *pB){
   int i;
-  if( pA==0 ){
-    return pB==0;
-  }else if( pB==0 ){
-    return 0;
+  if( pA==0||pB==0 ){
+    return pB==pA;
   }
   if( pA->op!=pB->op ) return 0;
   if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0;
@@ -2056,7 +2107,9 @@
   if( pA->token.z ){
     if( pB->token.z==0 ) return 0;
     if( pB->token.n!=pA->token.n ) return 0;
-    if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
+    if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){
+      return 0;
+    }
   }
   return 1;
 }
@@ -2180,14 +2233,14 @@
         if( i>=pAggInfo->nFunc ){
           /* pExpr is original.  Make a new entry in pAggInfo->aFunc[]
           */
-          u8 enc = pParse->db->enc;
+          u8 enc = ENC(pParse->db);
           i = addAggInfoFunc(pAggInfo);
           if( i>=0 ){
             pItem = &pAggInfo->aFunc[i];
             pItem->pExpr = pExpr;
             pItem->iMem = pParse->nMem++;
             pItem->pFunc = sqlite3FindFunction(pParse->db,
-                   pExpr->token.z, pExpr->token.n,
+                   (char*)pExpr->token.z, pExpr->token.n,
                    pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);
             if( pExpr->flags & EP_Distinct ){
               pItem->iDistinct = pParse->nTab++;

Modified: packages/libdbd-sqlite3-perl/trunk/func.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/func.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/func.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -16,11 +16,11 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.110 2005/09/08 20:37:43 drh Exp $
+** $Id: func.c,v 1.126 2006/03/16 16:19:56 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
-#include <math.h>
+/* #include <math.h> */
 #include <stdlib.h>
 #include <assert.h>
 #include "vdbeInt.h"
@@ -101,7 +101,7 @@
       break;
     }
     case SQLITE_TEXT: {
-      const char *z = sqlite3_value_text(argv[0]);
+      const unsigned char *z = sqlite3_value_text(argv[0]);
       for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
       sqlite3_result_int(context, len);
       break;
@@ -121,7 +121,13 @@
   switch( sqlite3_value_type(argv[0]) ){
     case SQLITE_INTEGER: {
       i64 iVal = sqlite3_value_int64(argv[0]);
-      if( iVal<0 ) iVal = iVal * -1;
+      if( iVal<0 ){
+        if( (iVal<<1)==0 ){
+          sqlite3_result_error(context, "integer overflow", -1);
+          return;
+        }
+        iVal = -iVal;
+      } 
       sqlite3_result_int64(context, iVal);
       break;
     }
@@ -131,7 +137,7 @@
     }
     default: {
       double rVal = sqlite3_value_double(argv[0]);
-      if( rVal<0 ) rVal = rVal * -1.0;
+      if( rVal<0 ) rVal = -rVal;
       sqlite3_result_double(context, rVal);
       break;
     }
@@ -146,8 +152,8 @@
   int argc,
   sqlite3_value **argv
 ){
-  const char *z;
-  const char *z2;
+  const unsigned char *z;
+  const unsigned char *z2;
   int i;
   int p1, p2, len;
 
@@ -178,7 +184,7 @@
   }
   while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
   if( p2<0 ) p2 = 0;
-  sqlite3_result_text(context, &z[p1], p2, SQLITE_TRANSIENT);
+  sqlite3_result_text(context, (char*)&z[p1], p2, SQLITE_TRANSIENT);
 }
 
 /*
@@ -195,10 +201,10 @@
     if( n>30 ) n = 30;
     if( n<0 ) n = 0;
   }
-  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
+  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
   r = sqlite3_value_double(argv[0]);
   sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
-  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+  sqlite3_result_double(context, atof(zBuf));
 }
 
 /*
@@ -210,11 +216,11 @@
   if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
   z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
   if( z==0 ) return;
-  strcpy(z, sqlite3_value_text(argv[0]));
+  strcpy((char*)z, (char*)sqlite3_value_text(argv[0]));
   for(i=0; z[i]; i++){
     z[i] = toupper(z[i]);
   }
-  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+  sqlite3_result_text(context, (char*)z, -1, SQLITE_TRANSIENT);
   sqliteFree(z);
 }
 static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
@@ -223,11 +229,11 @@
   if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
   z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
   if( z==0 ) return;
-  strcpy(z, sqlite3_value_text(argv[0]));
+  strcpy((char*)z, (char*)sqlite3_value_text(argv[0]));
   for(i=0; z[i]; i++){
     z[i] = tolower(z[i]);
   }
-  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+  sqlite3_result_text(context, (char*)z, -1, SQLITE_TRANSIENT);
   sqliteFree(z);
 }
 
@@ -258,9 +264,11 @@
   int argc,
   sqlite3_value **argv
 ){
-  int r;
+  sqlite_int64 r;
   sqlite3Randomness(sizeof(r), &r);
-  sqlite3_result_int(context, r);
+  if( (r<<1)==0 ) r = 0;  /* Prevent 0x8000.... as the result so that we */
+                          /* can always do abs() of the result */
+  sqlite3_result_int64(context, r);
 }
 
 /*
@@ -495,7 +503,7 @@
     ** Otherwise, return an error.
     */
     const unsigned char *zEsc = sqlite3_value_text(argv[2]);
-    if( sqlite3utf8CharLen(zEsc, -1)!=1 ){
+    if( sqlite3utf8CharLen((char*)zEsc, -1)!=1 ){
       sqlite3_result_error(context, 
           "ESCAPE expression must be a single character", -1);
       return;
@@ -592,7 +600,7 @@
     }
     case SQLITE_TEXT: {
       int i,j,n;
-      const char *zArg = sqlite3_value_text(argv[0]);
+      const unsigned char *zArg = sqlite3_value_text(argv[0]);
       char *z;
 
       for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
@@ -692,7 +700,7 @@
     zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
   }
   zBuf[n] = 0;
-  sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
+  sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT);
 }
 #endif /* SQLITE_TEST */
 
@@ -728,17 +736,17 @@
   test_destructor_count_var++;
   assert( nArg==1 );
   if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
-  len = sqlite3ValueBytes(argv[0], db->enc); 
+  len = sqlite3ValueBytes(argv[0], ENC(db)); 
   zVal = sqliteMalloc(len+3);
   zVal[len] = 0;
   zVal[len-1] = 0;
   assert( zVal );
   zVal++;
-  memcpy(zVal, sqlite3ValueText(argv[0], db->enc), len);
-  if( db->enc==SQLITE_UTF8 ){
+  memcpy(zVal, sqlite3ValueText(argv[0], ENC(db)), len);
+  if( ENC(db)==SQLITE_UTF8 ){
     sqlite3_result_text(pCtx, zVal, -1, destructor);
 #ifndef SQLITE_OMIT_UTF16
-  }else if( db->enc==SQLITE_UTF16LE ){
+  }else if( ENC(db)==SQLITE_UTF16LE ){
     sqlite3_result_text16le(pCtx, zVal, -1, destructor);
   }else{
     sqlite3_result_text16be(pCtx, zVal, -1, destructor);
@@ -776,7 +784,7 @@
   char *zRet = sqliteMalloc(nArg*2);
   if( !zRet ) return;
   for(i=0; i<nArg; i++){
-    char const *z = sqlite3_value_text(argv[i]);
+    char const *z = (char*)sqlite3_value_text(argv[i]);
     if( z ){
       char *zAux = sqlite3_get_auxdata(pCtx, i);
       if( zAux ){
@@ -807,7 +815,7 @@
   int nArg,
   sqlite3_value **argv
 ){
-  sqlite3_result_error(pCtx, sqlite3_value_text(argv[0]), 0);
+  sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), 0);
 }
 #endif /* SQLITE_TEST */
 
@@ -817,25 +825,53 @@
 */
 typedef struct SumCtx SumCtx;
 struct SumCtx {
-  double sum;     /* Sum of terms */
-  int cnt;        /* Number of elements summed */
-  u8 seenFloat;   /* True if there has been any floating point value */
+  double rSum;      /* Floating point sum */
+  i64 iSum;         /* Integer sum */   
+  i64 cnt;          /* Number of elements summed */
+  u8 overflow;      /* True if integer overflow seen */
+  u8 approx;        /* True if non-integer value was input to the sum */
 };
 
 /*
-** Routines used to compute the sum or average.
+** Routines used to compute the sum, average, and total.
+**
+** The SUM() function follows the (broken) SQL standard which means
+** that it returns NULL if it sums over no inputs.  TOTAL returns
+** 0.0 in that case.  In addition, TOTAL always returns a float where
+** SUM might return an integer if it never encounters a floating point
+** value.
+**
+** I am told that SUM() should raise an exception if it encounters
+** a integer overflow.  But after pondering this, I decided that 
+** behavior leads to brittle programs.  So instead, I have coded
+** SUM() to revert to using floating point if it encounters an
+** integer overflow.  The answer may not be exact, but it will be
+** close.  If the SUM() function returns an integer, the value is
+** exact.  If SUM() returns a floating point value, it means the
+** value might be approximated.
 */
 static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
   SumCtx *p;
   int type;
   assert( argc==1 );
   p = sqlite3_aggregate_context(context, sizeof(*p));
-  type = sqlite3_value_type(argv[0]);
+  type = sqlite3_value_numeric_type(argv[0]);
   if( p && type!=SQLITE_NULL ){
-    p->sum += sqlite3_value_double(argv[0]);
     p->cnt++;
-    if( type==SQLITE_FLOAT ){
-      p->seenFloat = 1;
+    if( type==SQLITE_INTEGER ){
+      i64 v = sqlite3_value_int64(argv[0]);
+      p->rSum += v;
+      if( (p->approx|p->overflow)==0 ){
+        i64 iNewSum = p->iSum + v;
+        int s1 = p->iSum >> (sizeof(i64)*8-1);
+        int s2 = v       >> (sizeof(i64)*8-1);
+        int s3 = iNewSum >> (sizeof(i64)*8-1);
+        p->overflow = (s1&s2&~s3) | (~s1&~s2&s3);
+        p->iSum = iNewSum;
+      }
+    }else{
+      p->rSum += sqlite3_value_double(argv[0]);
+      p->approx = 1;
     }
   }
 }
@@ -843,10 +879,12 @@
   SumCtx *p;
   p = sqlite3_aggregate_context(context, 0);
   if( p && p->cnt>0 ){
-    if( p->seenFloat ){
-      sqlite3_result_double(context, p->sum);
+    if( p->overflow ){
+      sqlite3_result_error(context,"integer overflow",-1);
+    }else if( p->approx ){
+      sqlite3_result_double(context, p->rSum);
     }else{
-      sqlite3_result_int64(context, (i64)p->sum);
+      sqlite3_result_int64(context, p->iSum);
     }
   }
 }
@@ -854,28 +892,22 @@
   SumCtx *p;
   p = sqlite3_aggregate_context(context, 0);
   if( p && p->cnt>0 ){
-    sqlite3_result_double(context, p->sum/(double)p->cnt);
+    sqlite3_result_double(context, p->rSum/(double)p->cnt);
   }
 }
+static void totalFinalize(sqlite3_context *context){
+  SumCtx *p;
+  p = sqlite3_aggregate_context(context, 0);
+  sqlite3_result_double(context, p ? p->rSum : 0.0);
+}
 
 /*
-** An instance of the following structure holds the context of a
-** variance or standard deviation computation.
-*/
-typedef struct StdDevCtx StdDevCtx;
-struct StdDevCtx {
-  double sum;     /* Sum of terms */
-  double sum2;    /* Sum of the squares of terms */
-  int cnt;        /* Number of terms counted */
-};
-
-/*
 ** The following structure keeps track of state information for the
 ** count() aggregate function.
 */
 typedef struct CountCtx CountCtx;
 struct CountCtx {
-  int n;
+  i64 n;
 };
 
 /*
@@ -891,7 +923,7 @@
 static void countFinalize(sqlite3_context *context){
   CountCtx *p;
   p = sqlite3_aggregate_context(context, 0);
-  sqlite3_result_int(context, p ? p->n : 0);
+  sqlite3_result_int64(context, p ? p->n : 0);
 }
 
 /*
@@ -1000,6 +1032,7 @@
     { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
     { "max",    1, 2, 1, minmaxStep,   minMaxFinalize },
     { "sum",    1, 0, 0, sumStep,      sumFinalize    },
+    { "total",  1, 0, 0, sumStep,      totalFinalize    },
     { "avg",    1, 0, 0, sumStep,      avgFinalize    },
     { "count",  0, 0, 0, countStep,    countFinalize  },
     { "count",  1, 0, 0, countStep,    countFinalize  },
@@ -1012,7 +1045,7 @@
       case 1: pArg = db; break;
       case 2: pArg = (void *)(-1); break;
     }
-    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
+    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
         aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
     if( aFuncs[i].needCollSeq ){
       FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, 
@@ -1025,13 +1058,16 @@
 #ifndef SQLITE_OMIT_ALTERTABLE
   sqlite3AlterFunctions(db);
 #endif
+#ifndef SQLITE_OMIT_PARSER
+  sqlite3AttachFunctions(db);
+#endif
   for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
     void *pArg = 0;
     switch( aAggs[i].argType ){
       case 1: pArg = db; break;
       case 2: pArg = (void *)(-1); break;
     }
-    sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
+    sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
         pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
     if( aAggs[i].needCollSeq ){
       FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
@@ -1043,7 +1079,7 @@
   }
   sqlite3RegisterDateTimeFunctions(db);
 #ifdef SQLITE_SSE
-  sqlite3SseFunctions(db);
+  (void)sqlite3SseFunctions(db);
 #endif
 #ifdef SQLITE_CASE_SENSITIVE_LIKE
   sqlite3RegisterLikeFunctions(db, 1);
@@ -1075,9 +1111,9 @@
   }else{
     pInfo = (struct compareInfo*)&likeInfoNorm;
   }
-  sqlite3_create_function(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
-  sqlite3_create_function(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
-  sqlite3_create_function(db, "glob", 2, SQLITE_UTF8, 
+  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
+  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
+  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
       (struct compareInfo*)&globInfo, likeFunc, 0,0);
   setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
   setLikeOptFlag(db, "like", 
@@ -1099,7 +1135,7 @@
   if( pExpr->pList->nExpr!=2 ){
     return 0;
   }
-  pDef = sqlite3FindFunction(db, pExpr->token.z, pExpr->token.n, 2,
+  pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
                              SQLITE_UTF8, 0);
   if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
     return 0;

Modified: packages/libdbd-sqlite3-perl/trunk/getsqlite.pl
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/getsqlite.pl	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/getsqlite.pl	2006-04-18 15:20:48 UTC (rev 2605)
@@ -47,6 +47,13 @@
 src/test3.c
 src/test4.c
 src/test5.c
+src/test6.c
+src/test7.c
+src/test8.c
+src/test9.c
+src/test_async.c
+src/test_md5.c
+src/test_server.c
 src/tclsqlite.c
 src/shell.c
 src/lemon.c

Modified: packages/libdbd-sqlite3-perl/trunk/hash.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/hash.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/hash.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This is the implementation of generic hash-tables
 ** used in SQLite.
 **
-** $Id: hash.c,v 1.16 2005/01/31 12:56:44 danielk1977 Exp $
+** $Id: hash.c,v 1.18 2006/02/14 10:48:39 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <assert.h>
@@ -41,6 +41,8 @@
   pNew->count = 0;
   pNew->htsize = 0;
   pNew->ht = 0;
+  pNew->xMalloc = sqlite3MallocX;
+  pNew->xFree = sqlite3FreeX;
 }
 
 /* Remove all entries from a hash table.  Reclaim all memory.
@@ -53,15 +55,15 @@
   assert( pH!=0 );
   elem = pH->first;
   pH->first = 0;
-  if( pH->ht ) sqliteFree(pH->ht);
+  if( pH->ht ) pH->xFree(pH->ht);
   pH->ht = 0;
   pH->htsize = 0;
   while( elem ){
     HashElem *next_elem = elem->next;
     if( pH->copyKey && elem->pKey ){
-      sqliteFree(elem->pKey);
+      pH->xFree(elem->pKey);
     }
-    sqliteFree(elem);
+    pH->xFree(elem);
     elem = next_elem;
   }
   pH->count = 0;
@@ -222,9 +224,9 @@
   int (*xHash)(const void*,int); /* The hash function */
 
   assert( (new_size & (new_size-1))==0 );
-  new_ht = (struct _ht *)sqliteMalloc( new_size*sizeof(struct _ht) );
+  new_ht = (struct _ht *)pH->xMalloc( new_size*sizeof(struct _ht) );
   if( new_ht==0 ) return;
-  if( pH->ht ) sqliteFree(pH->ht);
+  if( pH->ht ) pH->xFree(pH->ht);
   pH->ht = new_ht;
   pH->htsize = new_size;
   xHash = hashFunction(pH->keyClass);
@@ -290,10 +292,15 @@
     pEntry->chain = 0;
   }
   if( pH->copyKey && elem->pKey ){
-    sqliteFree(elem->pKey);
+    pH->xFree(elem->pKey);
   }
-  sqliteFree( elem );
+  pH->xFree( elem );
   pH->count--;
+  if( pH->count<=0 ){
+    assert( pH->first==0 );
+    assert( pH->count==0 );
+    sqlite3HashClear(pH);
+  }
 }
 
 /* Attempt to locate an element of the hash table pH with a key
@@ -353,12 +360,12 @@
     return old_data;
   }
   if( data==0 ) return 0;
-  new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
+  new_elem = (HashElem*)pH->xMalloc( sizeof(HashElem) );
   if( new_elem==0 ) return data;
   if( pH->copyKey && pKey!=0 ){
-    new_elem->pKey = sqliteMallocRaw( nKey );
+    new_elem->pKey = pH->xMalloc( nKey );
     if( new_elem->pKey==0 ){
-      sqliteFree(new_elem);
+      pH->xFree(new_elem);
       return data;
     }
     memcpy((void*)new_elem->pKey, pKey, nKey);
@@ -371,7 +378,7 @@
     rehash(pH,8);
     if( pH->htsize==0 ){
       pH->count = 0;
-      sqliteFree(new_elem);
+      pH->xFree(new_elem);
       return data;
     }
   }

Modified: packages/libdbd-sqlite3-perl/trunk/hash.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/hash.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/hash.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This is the header file for the generic hash-table implemenation
 ** used in SQLite.
 **
-** $Id: hash.h,v 1.8 2004/08/20 14:08:51 drh Exp $
+** $Id: hash.h,v 1.9 2006/02/14 10:48:39 danielk1977 Exp $
 */
 #ifndef _SQLITE_HASH_H_
 #define _SQLITE_HASH_H_
@@ -34,6 +34,8 @@
   char copyKey;           /* True if copy of key made on insert */
   int count;              /* Number of entries in this table */
   HashElem *first;        /* The first element of the array */
+  void *(*xMalloc)(int);  /* malloc() function to use */
+  void (*xFree)(void *);  /* free() function to use */
   int htsize;             /* Number of buckets in the hash table */
   struct _ht {            /* the hash table */
     int count;               /* Number of entries with this hash */

Modified: packages/libdbd-sqlite3-perl/trunk/insert.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/insert.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/insert.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.143 2005/09/20 17:42:23 drh Exp $
+** $Id: insert.c,v 1.164 2006/03/15 16:26:10 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -23,10 +23,11 @@
 **
 **  Character      Column affinity
 **  ------------------------------
-**  'n'            NUMERIC
-**  'i'            INTEGER
-**  't'            TEXT
-**  'o'            NONE
+**  'a'            TEXT
+**  'b'            NONE
+**  'c'            NUMERIC
+**  'd'            INTEGER
+**  'e'            REAL
 */
 void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
   if( !pIdx->zColAff ){
@@ -61,10 +62,11 @@
 **
 **  Character      Column affinity
 **  ------------------------------
-**  'n'            NUMERIC
-**  'i'            INTEGER
-**  't'            TEXT
-**  'o'            NONE
+**  'a'            TEXT
+**  'b'            NONE
+**  'c'            NUMERIC
+**  'd'            INTEGER
+**  'e'            REAL
 */
 void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
   /* The first time a column affinity string for a particular table
@@ -102,15 +104,15 @@
 **
 ** No checking is done for sub-selects that are part of expressions.
 */
-static int selectReadsTable(Select *p, int iDb, int iTab){
+static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
   int i;
   struct SrcList_item *pItem;
   if( p->pSrc==0 ) return 0;
   for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
     if( pItem->pSelect ){
-      if( selectReadsTable(pItem->pSelect, iDb, iTab) ) return 1;
+      if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1;
     }else{
-      if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1;
+      if( pItem->pTab->pSchema==pSchema && pItem->pTab->tnum==iTab ) return 1;
     }
   }
   return 0;
@@ -212,6 +214,7 @@
   int newIdx = -1;      /* Cursor for the NEW table */
   Db *pDb;              /* The database containing table being inserted into */
   int counterMem = 0;   /* Memory cell holding AUTOINCREMENT counter */
+  int iDb;
 
 #ifndef SQLITE_OMIT_TRIGGER
   int isView;                 /* True if attempting to insert into a view */
@@ -219,10 +222,12 @@
 #endif
 
 #ifndef SQLITE_OMIT_AUTOINCREMENT
-  int counterRowid;     /* Memory cell holding rowid of autoinc counter */
+  int counterRowid = 0;  /* Memory cell holding rowid of autoinc counter */
 #endif
 
-  if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
+  if( pParse->nErr || sqlite3MallocFailed() ){
+    goto insert_cleanup;
+  }
   db = pParse->db;
 
   /* Locate the table into which we will be inserting new information.
@@ -234,8 +239,9 @@
   if( pTab==0 ){
     goto insert_cleanup;
   }
-  assert( pTab->iDb<db->nDb );
-  pDb = &db->aDb[pTab->iDb];
+  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+  assert( iDb<db->nDb );
+  pDb = &db->aDb[iDb];
   zDb = pDb->zName;
   if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
     goto insert_cleanup;
@@ -263,7 +269,7 @@
   if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
     goto insert_cleanup;
   }
-  if( pTab==0 ) goto insert_cleanup;
+  assert( pTab!=0 );
 
   /* If pTab is really a view, make sure it has been initialized.
   */
@@ -271,19 +277,12 @@
     goto insert_cleanup;
   }
 
-  /* Ensure all required collation sequences are available. */
-  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-    if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
-      goto insert_cleanup;
-    }
-  }
-
   /* Allocate a VDBE
   */
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto insert_cleanup;
   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
-  sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, pTab->iDb);
+  sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, iDb);
 
   /* if there are row triggers, allocate a temp table for new.* references. */
   if( triggers_exist ){
@@ -298,22 +297,20 @@
   */
   if( pTab->autoInc ){
     int iCur = pParse->nTab;
-    int base = sqlite3VdbeCurrentAddr(v);
+    int addr = sqlite3VdbeCurrentAddr(v);
     counterRowid = pParse->nMem++;
     counterMem = pParse->nMem++;
-    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-    sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum);
-    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
-    sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13);
+    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
+    sqlite3VdbeAddOp(v, OP_Rewind, iCur, addr+13);
     sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
     sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
-    sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
+    sqlite3VdbeAddOp(v, OP_Ne, 0x100, addr+12);
     sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
     sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
     sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
     sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
-    sqlite3VdbeAddOp(v, OP_Goto, 0, base+13);
-    sqlite3VdbeAddOp(v, OP_Next, iCur, base+4);
+    sqlite3VdbeAddOp(v, OP_Goto, 0, addr+13);
+    sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4);
     sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
   }
 #endif /* SQLITE_OMIT_AUTOINCREMENT */
@@ -336,7 +333,9 @@
 
     /* Resolve the expressions in the SELECT statement and execute it. */
     rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
-    if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
+    if( rc || pParse->nErr || sqlite3MallocFailed() ){
+      goto insert_cleanup;
+    }
 
     iCleanup = sqlite3VdbeMakeLabel(v);
     sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
@@ -351,7 +350,7 @@
     ** of the tables being read by the SELECT statement.  Also use a 
     ** temp table in the case of row triggers.
     */
-    if( triggers_exist || selectReadsTable(pSelect, pTab->iDb, pTab->tnum) ){
+    if( triggers_exist || selectReadsTable(pSelect,pTab->pSchema,pTab->tnum) ){
       useTempTable = 1;
     }
 
@@ -362,7 +361,6 @@
       srcTab = pParse->nTab++;
       sqlite3VdbeResolveLabel(v, iInsertBlock);
       sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
-      sqlite3TableAffinityStr(v, pTab);
       sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
       sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
@@ -635,7 +633,7 @@
   /* Update the count of rows that are inserted
   */
   if( (db->flags & SQLITE_CountRows)!=0 ){
-    sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0);
+    sqlite3VdbeAddOp(v, OP_MemIncr, 1, iCntMem);
   }
 
   if( triggers_exist ){
@@ -682,12 +680,10 @@
   */
   if( pTab->autoInc ){
     int iCur = pParse->nTab;
-    int base = sqlite3VdbeCurrentAddr(v);
-    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum);
-    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
+    int addr = sqlite3VdbeCurrentAddr(v);
+    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
     sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
-    sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
+    sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+7);
     sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
     sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
     sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
@@ -707,7 +703,7 @@
     sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
     sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
   }
 
 insert_cleanup:
@@ -870,7 +866,24 @@
 
   /* Test all CHECK constraints
   */
-  /**** TBD ****/
+#ifndef SQLITE_OMIT_CHECK
+  if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
+    int allOk = sqlite3VdbeMakeLabel(v);
+    assert( pParse->ckOffset==0 );
+    pParse->ckOffset = nCol;
+    sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, 1);
+    assert( pParse->ckOffset==nCol );
+    pParse->ckOffset = 0;
+    onError = overrideError!=OE_Default ? overrideError : OE_Abort;
+    if( onError==OE_Ignore || onError==OE_Replace ){
+      sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
+      sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
+    }else{
+      sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
+    }
+    sqlite3VdbeResolveLabel(v, allOk);
+  }
+#endif /* !defined(SQLITE_OMIT_CHECK) */
 
   /* If we have an INTEGER PRIMARY KEY, make sure the primary key
   ** of the new record does not previously exist.  Except, if this
@@ -904,7 +917,7 @@
         break;
       }
       case OE_Replace: {
-        sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
+        sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
         if( isUpdate ){
           sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
           sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
@@ -1067,9 +1080,13 @@
   if( pParse->nested ){
     pik_flags = 0;
   }else{
-    pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
+    pik_flags = OPFLAG_NCHANGE;
+    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
   }
   sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
+  if( !pParse->nested ){
+    sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
+  }
   
   if( isUpdate && rowidChng ){
     sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
@@ -1088,18 +1105,17 @@
   int op           /* OP_OpenRead or OP_OpenWrite */
 ){
   int i;
+  int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   Index *pIdx;
   Vdbe *v = sqlite3GetVdbe(pParse);
   assert( v!=0 );
-  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-  VdbeComment((v, "# %s", pTab->zName));
-  sqlite3VdbeAddOp(v, op, base, pTab->tnum);
-  sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
+  sqlite3OpenTable(pParse, base, iDb, pTab, op);
   for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
-    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
+    assert( pIdx->pSchema==pTab->pSchema );
+    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
     VdbeComment((v, "# %s", pIdx->zName));
-    sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
-                   (char*)&pIdx->keyInfo, P3_KEYINFO);
+    sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF);
   }
   if( pParse->nTab<=base+i ){
     pParse->nTab = base+i;

Modified: packages/libdbd-sqlite3-perl/trunk/keywordhash.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/keywordhash.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/keywordhash.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,28 +1,28 @@
-/* Hash score: 158 */
+/* Hash score: 159 */
 static int keywordCode(const char *z, int n){
-  static const char zText[535] =
+  static const char zText[537] =
     "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER"
     "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYANALYZE"
     "XCLUSIVEXISTSTATEMENTANDEFERRABLEATTACHAVINGLOBEFOREIGNOREINDEX"
     "AUTOINCREMENTBEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETE"
     "CASECASTCOLLATECOLUMNCOMMITCONFLICTCONSTRAINTERSECTCREATECROSS"
     "CURRENT_DATECURRENT_TIMESTAMPLANDESCDETACHDISTINCTDROPRAGMATCH"
-    "FAILIMITFROMFULLGROUPDATEIMMEDIATEINSERTINSTEADINTOFFSETISNULL"
+    "FAILIMITFROMFULLGROUPDATEIFIMMEDIATEINSERTINSTEADINTOFFSETISNULL"
     "JOINORDEREPLACEOUTERESTRICTPRIMARYQUERYRIGHTROLLBACKROWHENUNION"
     "UNIQUEUSINGVACUUMVALUESVIEWHERE";
   static const unsigned char aHash[127] = {
-      91,  80, 106,  90,   0,   4,   0,   0, 113,   0,  83,   0,   0,
-      94,  44,  76,  92,   0, 105, 108,  96,   0,   0,  10,   0,   0,
-     112,   0, 109, 102,   0,  28,  48,   0,  41,   0,   0,  65,  71,
-       0,  63,  19,   0, 104,  36, 103,   0, 107,  75,   0,   0,  33,
-       0,  61,  37,   0,   8,   0, 114,  38,  12,   0,  77,  40,  25,
+      92,  80, 107,  91,   0,   4,   0,   0, 114,   0,  83,   0,   0,
+      96,  44,  76,  93,   0, 106, 109,  97,  90,   0,  10,   0,   0,
+     113,   0, 110, 103,   0,  28,  48,   0,  41,   0,   0,  65,  71,
+       0,  63,  19,   0, 105,  36, 104,   0, 108,  75,   0,   0,  33,
+       0,  61,  37,   0,   8,   0, 115,  38,  12,   0,  77,  40,  25,
       66,   0,   0,  31,  81,  53,  30,  50,  20,  88,   0,  34,   0,
       74,  26,   0,  72,   0,   0,   0,  64,  47,  67,  22,  87,  29,
-      69,  86,   0,   1,   0,   9, 100,  58,  18,   0, 111,  82,  98,
-      54,   6,  85,   0,   0,  49,  93,   0, 101,   0,  70,   0,   0,
-      15,   0, 115,  51,  56,   0,   2,  55,   0, 110,
+      69,  86,   0,   1,   0,   9, 101,  58,  18,   0, 112,  82,  99,
+      54,   6,  85,   0,   0,  49,  94,   0, 102,   0,  70,   0,   0,
+      15,   0, 116,  51,  56,   0,   2,  55,   0, 111,
   };
-  static const unsigned char aNext[115] = {
+  static const unsigned char aNext[116] = {
        0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,
        0,   0,   0,   0,   0,   0,   0,   0,  17,   0,   0,   0,   0,
        0,  11,   0,   0,   0,   0,   5,  13,   0,   7,   0,   0,   0,
@@ -30,32 +30,32 @@
        0,   0,  16,   0,  23,  52,   0,   0,   0,   0,  45,   0,  59,
        0,   0,   0,   0,   0,   0,   0,   0,  42,  73,   0,  24,  60,
       21,   0,  79,   0,   0,  68,   0,   0,  84,  46,   0,   0,   0,
-       0,   0,   0,   0,  39,  95,  97,   0,   0,  99,   0,  32,   0,
-      14,  27,  78,   0,  57,  89,   0,  35,   0,  62,   0,
+       0,   0,   0,   0,   0,  39,  95,  98,   0,   0, 100,   0,  32,
+       0,  14,  27,  78,   0,  57,  89,   0,  35,   0,  62,   0,
   };
-  static const unsigned char aLen[115] = {
+  static const unsigned char aLen[116] = {
        5,   5,   4,   4,   9,   2,   3,   8,   2,   6,   4,   3,   7,
       11,   2,   7,   5,   5,   4,   5,   3,   5,  10,   6,   4,   6,
        7,   6,   7,   9,   3,   7,   9,   6,   9,   3,  10,   6,   6,
        4,   6,   3,   7,   6,   7,   5,  13,   2,   2,   5,   5,   6,
        7,   3,   7,   4,   4,   2,   7,   3,   8,   6,   4,   4,   7,
        6,   6,   8,  10,   9,   6,   5,  12,  17,  12,   4,   4,   6,
-       8,   2,   4,   6,   5,   4,   5,   4,   4,   5,   6,   9,   6,
-       7,   4,   2,   6,   3,   6,   4,   5,   7,   5,   8,   7,   5,
-       5,   8,   3,   4,   5,   6,   5,   6,   6,   4,   5,
+       8,   2,   4,   6,   5,   4,   5,   4,   4,   5,   6,   2,   9,
+       6,   7,   4,   6,   2,   3,   6,   4,   5,   7,   5,   8,   7,
+       5,   5,   8,   3,   4,   5,   6,   5,   6,   6,   4,   5,
   };
-  static const unsigned short int aOffset[115] = {
+  static const unsigned short int aOffset[116] = {
        0,   4,   7,  10,  10,  14,  19,  21,  26,  27,  32,  34,  36,
       42,  51,  52,  57,  61,  65,  67,  71,  74,  78,  86,  91,  94,
       99, 105, 108, 113, 118, 122, 128, 136, 141, 150, 152, 162, 167,
      172, 175, 177, 177, 181, 185, 187, 192, 194, 196, 205, 208, 212,
      218, 224, 224, 227, 230, 234, 236, 237, 241, 248, 254, 258, 262,
      269, 275, 281, 289, 296, 305, 311, 316, 328, 328, 344, 348, 352,
-     358, 359, 366, 369, 373, 378, 381, 386, 390, 394, 397, 403, 412,
-     418, 425, 428, 428, 431, 434, 440, 444, 448, 455, 459, 467, 474,
-     479, 484, 492, 494, 498, 503, 509, 514, 520, 526, 529,
+     358, 359, 366, 369, 373, 378, 381, 386, 390, 394, 397, 403, 405,
+     414, 420, 427, 430, 430, 433, 436, 442, 446, 450, 457, 461, 469,
+     476, 481, 486, 494, 496, 500, 505, 511, 516, 522, 528, 531,
   };
-  static const unsigned char aCode[115] = {
+  static const unsigned char aCode[116] = {
     TK_ABORT,      TK_TABLE,      TK_JOIN_KW,    TK_TEMP,       TK_TEMP,       
     TK_OR,         TK_ADD,        TK_DATABASE,   TK_AS,         TK_SELECT,     
     TK_THEN,       TK_END,        TK_DEFAULT,    TK_TRANSACTION,TK_ON,         
@@ -73,17 +73,18 @@
     TK_CREATE,     TK_JOIN_KW,    TK_CTIME_KW,   TK_CTIME_KW,   TK_CTIME_KW,   
     TK_PLAN,       TK_DESC,       TK_DETACH,     TK_DISTINCT,   TK_IS,         
     TK_DROP,       TK_PRAGMA,     TK_MATCH,      TK_FAIL,       TK_LIMIT,      
-    TK_FROM,       TK_JOIN_KW,    TK_GROUP,      TK_UPDATE,     TK_IMMEDIATE,  
-    TK_INSERT,     TK_INSTEAD,    TK_INTO,       TK_OF,         TK_OFFSET,     
-    TK_SET,        TK_ISNULL,     TK_JOIN,       TK_ORDER,      TK_REPLACE,    
-    TK_JOIN_KW,    TK_RESTRICT,   TK_PRIMARY,    TK_QUERY,      TK_JOIN_KW,    
-    TK_ROLLBACK,   TK_ROW,        TK_WHEN,       TK_UNION,      TK_UNIQUE,     
-    TK_USING,      TK_VACUUM,     TK_VALUES,     TK_VIEW,       TK_WHERE,      
+    TK_FROM,       TK_JOIN_KW,    TK_GROUP,      TK_UPDATE,     TK_IF,         
+    TK_IMMEDIATE,  TK_INSERT,     TK_INSTEAD,    TK_INTO,       TK_OFFSET,     
+    TK_OF,         TK_SET,        TK_ISNULL,     TK_JOIN,       TK_ORDER,      
+    TK_REPLACE,    TK_JOIN_KW,    TK_RESTRICT,   TK_PRIMARY,    TK_QUERY,      
+    TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        TK_WHEN,       TK_UNION,      
+    TK_UNIQUE,     TK_USING,      TK_VACUUM,     TK_VALUES,     TK_VIEW,       
+    TK_WHERE,      
   };
   int h, i;
   if( n<2 ) return TK_ID;
-  h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^
-      (sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^
+  h = ((charMap(z[0])*4) ^
+      (charMap(z[n-1])*3) ^
       n) % 127;
   for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
     if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
@@ -92,6 +93,6 @@
   }
   return TK_ID;
 }
-int sqlite3KeywordCode(const char *z, int n){
-  return keywordCode(z, n);
+int sqlite3KeywordCode(const unsigned char *z, int n){
+  return keywordCode((char*)z, n);
 }

Modified: packages/libdbd-sqlite3-perl/trunk/legacy.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/legacy.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/legacy.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: legacy.c,v 1.7 2004/09/06 17:34:13 drh Exp $
+** $Id: legacy.c,v 1.14 2006/03/06 20:55:46 drh Exp $
 */
 
 #include "sqliteInt.h"
@@ -54,8 +54,8 @@
 
     pStmt = 0;
     rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
+    assert( rc==SQLITE_OK || pStmt==0 );
     if( rc!=SQLITE_OK ){
-      if( pStmt ) sqlite3_finalize(pStmt);
       continue;
     }
     if( !pStmt ){
@@ -68,9 +68,8 @@
     nCallback = 0;
 
     nCol = sqlite3_column_count(pStmt);
-    azCols = sqliteMalloc(2*nCol*sizeof(const char *));
-    if( nCol && !azCols ){
-      rc = SQLITE_NOMEM;
+    azCols = sqliteMalloc(2*nCol*sizeof(const char *) + 1);
+    if( azCols==0 ){
       goto exec_out;
     }
 
@@ -122,9 +121,7 @@
   if( pStmt ) sqlite3_finalize(pStmt);
   if( azCols ) sqliteFree(azCols);
 
-  if( sqlite3_malloc_failed ){
-    rc = SQLITE_NOMEM;
-  }
+  rc = sqlite3ApiExit(0, rc);
   if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
     *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
     if( *pzErrMsg ){

Modified: packages/libdbd-sqlite3-perl/trunk/lib/DBD/SQLite.pm
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/lib/DBD/SQLite.pm	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/lib/DBD/SQLite.pm	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,11 +1,11 @@
-# $Id: SQLite.pm,v 1.51 2005/12/02 17:31:57 matt Exp $
+# $Id: SQLite.pm,v 1.52 2006/04/10 01:50:05 matt Exp $
 
 package DBD::SQLite;
 use strict;
 
 use DBI;
 use vars qw($err $errstr $state $drh $VERSION @ISA);
-$VERSION = '1.11';
+$VERSION = '1.12';
 
 use DynaLoader();
 @ISA = ('DynaLoader');

Modified: packages/libdbd-sqlite3-perl/trunk/main.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/main.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/main.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -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.302 2005/09/17 15:20:27 drh Exp $
+** $Id: main.c,v 1.339 2006/03/16 16:19:56 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -26,32 +26,9 @@
 */
 const int sqlite3one = 1;
 
-#ifndef SQLITE_OMIT_GLOBALRECOVER
 /*
-** Linked list of all open database handles. This is used by the 
-** sqlite3_global_recover() function. Entries are added to the list
-** by openDatabase() and removed by sqlite3_close().
-*/
-static sqlite3 *pDbList = 0;
-#endif
-
-#ifndef SQLITE_OMIT_UTF16
-/* 
-** Return the transient sqlite3_value object used for encoding conversions
-** during SQL compilation.
-*/
-sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
-  if( !db->pValue ){
-    db->pValue = sqlite3ValueNew();
-  }
-  return db->pValue;
-}
-#endif
-
-/*
 ** The version of the library
 */
-const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
 const char sqlite3_version[] = SQLITE_VERSION;
 const char *sqlite3_libversion(void){ return sqlite3_version; }
 int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
@@ -132,7 +109,10 @@
   }
 
 #ifdef SQLITE_SSE
-  sqlite3_finalize(db->pFetch);
+  {
+    extern void sqlite3SseCleanup(sqlite3*);
+    sqlite3SseCleanup(db);
+  }
 #endif 
 
   /* If there are any outstanding VMs, return SQLITE_BUSY. */
@@ -158,6 +138,9 @@
     if( pDb->pBt ){
       sqlite3BtreeClose(pDb->pBt);
       pDb->pBt = 0;
+      if( j!=1 ){
+        pDb->pSchema = 0;
+      }
     }
   }
   sqlite3ResetInternalSchema(db, 0);
@@ -179,33 +162,21 @@
 
   sqlite3HashClear(&db->aFunc);
   sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
-  if( db->pValue ){
-    sqlite3ValueFree(db->pValue);
-  }
   if( db->pErr ){
     sqlite3ValueFree(db->pErr);
   }
 
-#ifndef SQLITE_OMIT_GLOBALRECOVER
-  {
-    sqlite3 *pPrev;
-    sqlite3OsEnterMutex();
-    pPrev = pDbList;
-    while( pPrev && pPrev->pNext!=db ){
-      pPrev = pPrev->pNext;
-    }
-    if( pPrev ){
-      pPrev->pNext = db->pNext;
-    }else{
-      assert( pDbList==db );
-      pDbList = db->pNext;
-    }
-    sqlite3OsLeaveMutex();
-  }
-#endif
+  db->magic = SQLITE_MAGIC_ERROR;
 
-  db->magic = SQLITE_MAGIC_ERROR;
+  /* The temp-database schema is allocated differently from the other schema
+  ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
+  ** So it needs to be freed here. Todo: Why not roll the temp schema into
+  ** the same sqliteMalloc() as the one that allocates the database 
+  ** structure?
+  */
+  sqliteFree(db->aDb[1].pSchema);
   sqliteFree(db);
+  sqlite3ReleaseThreadData();
   return SQLITE_OK;
 }
 
@@ -214,13 +185,24 @@
 */
 void sqlite3RollbackAll(sqlite3 *db){
   int i;
+  int inTrans = 0;
   for(i=0; i<db->nDb; i++){
     if( db->aDb[i].pBt ){
+      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
+        inTrans = 1;
+      }
       sqlite3BtreeRollback(db->aDb[i].pBt);
       db->aDb[i].inTrans = 0;
     }
   }
-  sqlite3ResetInternalSchema(db, 0);
+  if( db->flags&SQLITE_InternChanges ){
+    sqlite3ResetInternalSchema(db, 0);
+  }
+
+  /* If one has been configured, invoke the rollback-hook callback */
+  if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
+    db->xRollbackCallback(db->pRollbackArg);
+  }
 }
 
 /*
@@ -271,7 +253,7 @@
  void *ptr,               /* Database connection */
  int count                /* Number of times table has been busy */
 ){
-#if SQLITE_MIN_SLEEP_MS==1
+#if OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
   static const u8 delays[] =
      { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50, 100 };
   static const u8 totals[] =
@@ -402,9 +384,12 @@
 void sqlite3_free(char *p){ free(p); }
 
 /*
-** Create new user functions.
+** This function is exactly the same as sqlite3_create_function(), except
+** that it is designed to be called by internal code. The difference is
+** that if a malloc() fails in sqlite3_create_function(), an error code
+** is returned and the mallocFailed flag cleared. 
 */
-int sqlite3_create_function(
+int sqlite3CreateFunc(
   sqlite3 *db,
   const char *zFunctionName,
   int nArg,
@@ -441,10 +426,10 @@
     enc = SQLITE_UTF16NATIVE;
   }else if( enc==SQLITE_ANY ){
     int rc;
-    rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF8,
+    rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
          pUserData, xFunc, xStep, xFinal);
     if( rc!=SQLITE_OK ) return rc;
-    rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF16LE,
+    rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
         pUserData, xFunc, xStep, xFinal);
     if( rc!=SQLITE_OK ) return rc;
     enc = SQLITE_UTF16BE;
@@ -463,6 +448,7 @@
     if( db->activeVdbeCnt ){
       sqlite3Error(db, SQLITE_BUSY, 
         "Unable to delete/modify user-function due to active statements");
+      assert( !sqlite3MallocFailed() );
       return SQLITE_BUSY;
     }else{
       sqlite3ExpirePreparedStatements(db);
@@ -470,42 +456,56 @@
   }
 
   p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
-  if( p==0 ) return SQLITE_NOMEM;
-  p->flags = 0;
-  p->xFunc = xFunc;
-  p->xStep = xStep;
-  p->xFinalize = xFinal;
-  p->pUserData = pUserData;
+  if( p ){
+    p->flags = 0;
+    p->xFunc = xFunc;
+    p->xStep = xStep;
+    p->xFinalize = xFinal;
+    p->pUserData = pUserData;
+  }
   return SQLITE_OK;
 }
+
+/*
+** Create new user functions.
+*/
+int sqlite3_create_function(
+  sqlite3 *db,
+  const char *zFunctionName,
+  int nArg,
+  int enc,
+  void *p,
+  void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
+  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+  void (*xFinal)(sqlite3_context*)
+){
+  int rc;
+  assert( !sqlite3MallocFailed() );
+  rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal);
+
+  return sqlite3ApiExit(db, rc);
+}
+
 #ifndef SQLITE_OMIT_UTF16
 int sqlite3_create_function16(
   sqlite3 *db,
   const void *zFunctionName,
   int nArg,
   int eTextRep,
-  void *pUserData,
+  void *p,
   void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
   void (*xFinal)(sqlite3_context*)
 ){
   int rc;
-  char const *zFunc8;
-  sqlite3_value *pTmp;
+  char *zFunc8;
+  assert( !sqlite3MallocFailed() );
 
-  if( sqlite3SafetyCheck(db) ){
-    return SQLITE_MISUSE;
-  }
-  pTmp = sqlite3GetTransientValue(db);
-  sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);
-  zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
+  zFunc8 = sqlite3utf16to8(zFunctionName, -1);
+  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
+  sqliteFree(zFunc8);
 
-  if( !zFunc8 ){
-    return SQLITE_NOMEM;
-  }
-  rc = sqlite3_create_function(db, zFunc8, nArg, eTextRep, 
-      pUserData, xFunc, xStep, xFinal);
-  return rc;
+  return sqlite3ApiExit(db, rc);
 }
 #endif
 
@@ -547,7 +547,7 @@
 /*** EXPERIMENTAL ***
 **
 ** Register a function to be invoked when a transaction comments.
-** If either function returns non-zero, then the commit becomes a
+** If the invoked function returns non-zero, then the commit becomes a
 ** rollback.
 */
 void *sqlite3_commit_hook(
@@ -561,8 +561,37 @@
   return pOld;
 }
 
+/*
+** Register a callback to be invoked each time a row is updated,
+** inserted or deleted using this database connection.
+*/
+void *sqlite3_update_hook(
+  sqlite3 *db,              /* Attach the hook to this database */
+  void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
+  void *pArg                /* Argument to the function */
+){
+  void *pRet = db->pUpdateArg;
+  db->xUpdateCallback = xCallback;
+  db->pUpdateArg = pArg;
+  return pRet;
+}
 
 /*
+** Register a callback to be invoked each time a transaction is rolled
+** back by this database connection.
+*/
+void *sqlite3_rollback_hook(
+  sqlite3 *db,              /* Attach the hook to this database */
+  void (*xCallback)(void*), /* Callback function */
+  void *pArg                /* Argument to the function */
+){
+  void *pRet = db->pRollbackArg;
+  db->xRollbackCallback = xCallback;
+  db->pRollbackArg = pArg;
+  return pRet;
+}
+
+/*
 ** This routine is called to create a connection to a database BTree
 ** driver.  If zFilename is the name of a file, then that file is
 ** opened and used.  If zFilename is the magic name ":memory:" then
@@ -621,7 +650,7 @@
 #endif /* SQLITE_OMIT_MEMORYDB */
   }
 
-  rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags);
+  rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btree_flags);
   if( rc==SQLITE_OK ){
     sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
     sqlite3BtreeSetCacheSize(*ppBtree, nCache);
@@ -635,13 +664,13 @@
 */
 const char *sqlite3_errmsg(sqlite3 *db){
   const char *z;
-  if( sqlite3_malloc_failed ){
+  if( !db || sqlite3MallocFailed() ){
     return sqlite3ErrStr(SQLITE_NOMEM);
   }
   if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
     return sqlite3ErrStr(SQLITE_MISUSE);
   }
-  z = sqlite3_value_text(db->pErr);
+  z = (char*)sqlite3_value_text(db->pErr);
   if( z==0 ){
     z = sqlite3ErrStr(db->errCode);
   }
@@ -674,7 +703,7 @@
   };
 
   const void *z;
-  if( sqlite3_malloc_failed ){
+  if( sqlite3MallocFailed() ){
     return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
   }
   if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
@@ -686,15 +715,17 @@
          SQLITE_UTF8, SQLITE_STATIC);
     z = sqlite3_value_text16(db->pErr);
   }
+  sqlite3ApiExit(0, 0);
   return z;
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
 /*
-** Return the most recent error code generated by an SQLite routine.
+** Return the most recent error code generated by an SQLite routine. If NULL is
+** passed to this function, we assume a malloc() failed during sqlite3_open().
 */
 int sqlite3_errcode(sqlite3 *db){
-  if( sqlite3_malloc_failed ){
+  if( !db || sqlite3MallocFailed() ){
     return SQLITE_NOMEM;
   }
   if( sqlite3SafetyCheck(db) ){
@@ -704,6 +735,63 @@
 }
 
 /*
+** Create a new collating function for database "db".  The name is zName
+** and the encoding is enc.
+*/
+static int createCollation(
+  sqlite3* db, 
+  const char *zName, 
+  int enc, 
+  void* pCtx,
+  int(*xCompare)(void*,int,const void*,int,const void*)
+){
+  CollSeq *pColl;
+  int enc2;
+  
+  if( sqlite3SafetyCheck(db) ){
+    return SQLITE_MISUSE;
+  }
+
+  /* If SQLITE_UTF16 is specified as the encoding type, transform this
+  ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
+  ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
+  */
+  enc2 = enc & ~SQLITE_UTF16_ALIGNED;
+  if( enc2==SQLITE_UTF16 ){
+    enc2 = SQLITE_UTF16NATIVE;
+  }
+
+  if( (enc2&~3)!=0 ){
+    sqlite3Error(db, SQLITE_ERROR, "unknown encoding");
+    return SQLITE_ERROR;
+  }
+
+  /* Check if this call is removing or replacing an existing collation 
+  ** sequence. If so, and there are active VMs, return busy. If there
+  ** are no active VMs, invalidate any pre-compiled statements.
+  */
+  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 0);
+  if( pColl && pColl->xCmp ){
+    if( db->activeVdbeCnt ){
+      sqlite3Error(db, SQLITE_BUSY, 
+        "Unable to delete/modify collation sequence due to active statements");
+      return SQLITE_BUSY;
+    }
+    sqlite3ExpirePreparedStatements(db);
+  }
+
+  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1);
+  if( pColl ){
+    pColl->xCmp = xCompare;
+    pColl->pUser = pCtx;
+    pColl->enc = enc2 | (enc & SQLITE_UTF16_ALIGNED);
+  }
+  sqlite3Error(db, SQLITE_OK, 0);
+  return SQLITE_OK;
+}
+
+
+/*
 ** This routine does the work of opening a database on behalf of
 ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
 ** is UTF-8 encoded.
@@ -713,9 +801,11 @@
   sqlite3 **ppDb         /* OUT: Returned database handle */
 ){
   sqlite3 *db;
-  int rc, i;
+  int rc;
   CollSeq *pColl;
 
+  assert( !sqlite3MallocFailed() );
+
   /* Allocate the sqlite data structure */
   db = sqliteMalloc( sizeof(sqlite3) );
   if( db==0 ) goto opendb_out;
@@ -723,33 +813,27 @@
   db->magic = SQLITE_MAGIC_BUSY;
   db->nDb = 2;
   db->aDb = db->aDbStatic;
-  db->enc = SQLITE_UTF8;
   db->autoCommit = 1;
   db->flags |= SQLITE_ShortColNames;
   sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
   sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
-  for(i=0; i<db->nDb; i++){
-    sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
-    sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
-    sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
-    sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
-  }
-  
+
   /* Add the default collation sequence BINARY. BINARY works for both UTF-8
   ** and UTF-16, so add a version for each to avoid any unnecessary
   ** conversions. The only error that can occur here is a malloc() failure.
   */
-  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
-      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
-      !(db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0)) ){
-    rc = db->errCode;
-    assert( rc!=SQLITE_OK );
+  if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc) ||
+      createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc) ||
+      createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc) ||
+      (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 
+  ){
+    assert( sqlite3MallocFailed() );
     db->magic = SQLITE_MAGIC_CLOSED;
     goto opendb_out;
   }
 
   /* Also add a UTF-8 case-insensitive collation sequence. */
-  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
+  createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
 
   /* Set flags on the built-in collating sequences */
   db->pDfltColl->type = SQLITE_COLL_BINARY;
@@ -765,7 +849,13 @@
     db->magic = SQLITE_MAGIC_CLOSED;
     goto opendb_out;
   }
+  db->aDb[0].pSchema = sqlite3SchemaGet(db->aDb[0].pBt);
+  db->aDb[1].pSchema = sqlite3SchemaGet(0);
+  if( db->aDb[0].pSchema ){
+    ENC(db) = SQLITE_UTF8;
+  }
 
+
   /* The default safety_level for the main database is 'full'; for the temp
   ** database it is 'NONE'. This matches the pager layer defaults.  
   */
@@ -776,29 +866,23 @@
   db->aDb[1].safety_level = 1;
 #endif
 
-
   /* Register all built-in functions, but do not attempt to read the
   ** database schema yet. This is delayed until the first time the database
   ** is accessed.
   */
-  sqlite3RegisterBuiltinFunctions(db);
-  sqlite3Error(db, SQLITE_OK, 0);
+  if( !sqlite3MallocFailed() ){
+    sqlite3RegisterBuiltinFunctions(db);
+    sqlite3Error(db, SQLITE_OK, 0);
+  }
   db->magic = SQLITE_MAGIC_OPEN;
 
 opendb_out:
-  if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){
-    sqlite3Error(db, SQLITE_NOMEM, 0);
+  if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
+    sqlite3_close(db);
+    db = 0;
   }
   *ppDb = db;
-#ifndef SQLITE_OMIT_GLOBALRECOVER
-  if( db ){
-    sqlite3OsEnterMutex();
-    db->pNext = pDbList;
-    pDbList = db;
-    sqlite3OsLeaveMutex();
-  }
-#endif
-  return sqlite3_errcode(db);
+  return sqlite3ApiExit(0, rc);
 }
 
 /*
@@ -820,9 +904,10 @@
   sqlite3 **ppDb
 ){
   char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
-  int rc = SQLITE_NOMEM;
+  int rc = SQLITE_OK;
   sqlite3_value *pVal;
 
+  assert( zFilename );
   assert( ppDb );
   *ppDb = 0;
   pVal = sqlite3ValueNew();
@@ -831,14 +916,16 @@
   if( zFilename8 ){
     rc = openDatabase(zFilename8, ppDb);
     if( rc==SQLITE_OK && *ppDb ){
-      sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
+      rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
+      if( rc!=SQLITE_OK ){
+        sqlite3_close(*ppDb);
+        *ppDb = 0;
+      }
     }
   }
-  if( pVal ){
-    sqlite3ValueFree(pVal);
-  }
+  sqlite3ValueFree(pVal);
 
-  return rc;
+  return sqlite3ApiExit(0, rc);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -890,53 +977,10 @@
   void* pCtx,
   int(*xCompare)(void*,int,const void*,int,const void*)
 ){
-  CollSeq *pColl;
-  int rc = SQLITE_OK;
-  
-  if( sqlite3SafetyCheck(db) ){
-    return SQLITE_MISUSE;
-  }
-
-  /* If SQLITE_UTF16 is specified as the encoding type, transform this
-  ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
-  ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
-  */
-  if( enc==SQLITE_UTF16 ){
-    enc = SQLITE_UTF16NATIVE;
-  }
-
-  if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16LE && enc!=SQLITE_UTF16BE ){
-    sqlite3Error(db, SQLITE_ERROR, 
-        "Param 3 to sqlite3_create_collation() must be one of "
-        "SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
-    );
-    return SQLITE_ERROR;
-  }
-
-  /* Check if this call is removing or replacing an existing collation 
-  ** sequence. If so, and there are active VMs, return busy. If there
-  ** are no active VMs, invalidate any pre-compiled statements.
-  */
-  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0);
-  if( pColl && pColl->xCmp ){
-    if( db->activeVdbeCnt ){
-      sqlite3Error(db, SQLITE_BUSY, 
-        "Unable to delete/modify collation sequence due to active statements");
-      return SQLITE_BUSY;
-    }
-    sqlite3ExpirePreparedStatements(db);
-  }
-
-  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
-  if( 0==pColl ){
-    rc = SQLITE_NOMEM;
-  }else{
-    pColl->xCmp = xCompare;
-    pColl->pUser = pCtx;
-    pColl->enc = enc;
-  }
-  sqlite3Error(db, rc, 0);
-  return rc;
+  int rc;
+  assert( !sqlite3MallocFailed() );
+  rc = createCollation(db, zName, enc, pCtx, xCompare);
+  return sqlite3ApiExit(db, rc);
 }
 
 #ifndef SQLITE_OMIT_UTF16
@@ -950,15 +994,15 @@
   void* pCtx,
   int(*xCompare)(void*,int,const void*,int,const void*)
 ){
-  char const *zName8;
-  sqlite3_value *pTmp;
-  if( sqlite3SafetyCheck(db) ){
-    return SQLITE_MISUSE;
+  int rc = SQLITE_OK;
+  char *zName8; 
+  assert( !sqlite3MallocFailed() );
+  zName8 = sqlite3utf16to8(zName, -1);
+  if( zName8 ){
+    rc = createCollation(db, zName8, enc, pCtx, xCompare);
+    sqliteFree(zName8);
   }
-  pTmp = sqlite3GetTransientValue(db);
-  sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF16NATIVE, SQLITE_STATIC);
-  zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
-  return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
+  return sqlite3ApiExit(db, rc);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -1002,37 +1046,11 @@
 
 #ifndef SQLITE_OMIT_GLOBALRECOVER
 /*
-** This function is called to recover from a malloc failure that occured
-** within SQLite. 
-**
-** This function is *not* threadsafe. Calling this from within a threaded
-** application when threads other than the caller have used SQLite is 
-** dangerous and will almost certainly result in malfunctions.
+** This function is now an anachronism. It used to be used to recover from a
+** malloc() failure, but SQLite now does this automatically.
 */
 int sqlite3_global_recover(){
-  int rc = SQLITE_OK;
-
-  if( sqlite3_malloc_failed ){
-    sqlite3 *db;
-    int i;
-    sqlite3_malloc_failed = 0;
-    for(db=pDbList; db; db=db->pNext ){
-      sqlite3ExpirePreparedStatements(db);
-      for(i=0; i<db->nDb; i++){
-        Btree *pBt = db->aDb[i].pBt;
-        if( pBt && (rc=sqlite3BtreeReset(pBt)) ){
-          goto recover_out;
-        }
-      } 
-      db->autoCommit = 1;
-    }
-  }
-
-recover_out:
-  if( rc!=SQLITE_OK ){
-    sqlite3_malloc_failed = 1;
-  }
-  return rc;
+  return SQLITE_OK;
 }
 #endif
 
@@ -1058,3 +1076,157 @@
   return SQLITE_CORRUPT;
 }
 #endif
+
+
+#ifndef SQLITE_OMIT_SHARED_CACHE
+/*
+** Enable or disable the shared pager and schema features for the
+** current thread.
+**
+** This routine should only be called when there are no open
+** database connections.
+*/
+int sqlite3_enable_shared_cache(int enable){
+  ThreadData *pTd = sqlite3ThreadData();
+  if( pTd ){
+    /* It is only legal to call sqlite3_enable_shared_cache() when there
+    ** are no currently open b-trees that were opened by the calling thread.
+    ** This condition is only easy to detect if the shared-cache were 
+    ** previously enabled (and is being disabled). 
+    */
+    if( pTd->pBtree && !enable ){
+      assert( pTd->useSharedData );
+      return SQLITE_MISUSE;
+    }
+
+    pTd->useSharedData = enable;
+    sqlite3ReleaseThreadData();
+  }
+  return sqlite3ApiExit(0, SQLITE_OK);
+}
+#endif
+
+/*
+** This is a convenience routine that makes sure that all thread-specific
+** data for this thread has been deallocated.
+*/
+void sqlite3_thread_cleanup(void){
+  ThreadData *pTd = sqlite3OsThreadSpecificData(0);
+  if( pTd ){
+    memset(pTd, 0, sizeof(*pTd));
+    sqlite3OsThreadSpecificData(-1);
+  }
+}
+
+/*
+** Return meta information about a specific column of a database table.
+** See comment in sqlite3.h (sqlite.h.in) for details.
+*/
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+int sqlite3_table_column_metadata(
+  sqlite3 *db,                /* Connection handle */
+  const char *zDbName,        /* Database name or NULL */
+  const char *zTableName,     /* Table name */
+  const char *zColumnName,    /* Column name */
+  char const **pzDataType,    /* OUTPUT: Declared data type */
+  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
+  int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
+  int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
+  int *pAutoinc               /* OUTPUT: True if colums is auto-increment */
+){
+  int rc;
+  char *zErrMsg = 0;
+  Table *pTab = 0;
+  Column *pCol = 0;
+  int iCol;
+
+  char const *zDataType = 0;
+  char const *zCollSeq = 0;
+  int notnull = 0;
+  int primarykey = 0;
+  int autoinc = 0;
+
+  /* Ensure the database schema has been loaded */
+  if( sqlite3SafetyOn(db) ){
+    return SQLITE_MISUSE;
+  }
+  rc = sqlite3Init(db, &zErrMsg);
+  if( SQLITE_OK!=rc ){
+    goto error_out;
+  }
+
+  /* Locate the table in question */
+  pTab = sqlite3FindTable(db, zTableName, zDbName);
+  if( !pTab || pTab->pSelect ){
+    pTab = 0;
+    goto error_out;
+  }
+
+  /* Find the column for which info is requested */
+  if( sqlite3IsRowid(zColumnName) ){
+    iCol = pTab->iPKey;
+    if( iCol>=0 ){
+      pCol = &pTab->aCol[iCol];
+    }
+  }else{
+    for(iCol=0; iCol<pTab->nCol; iCol++){
+      pCol = &pTab->aCol[iCol];
+      if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
+        break;
+      }
+    }
+    if( iCol==pTab->nCol ){
+      pTab = 0;
+      goto error_out;
+    }
+  }
+
+  /* The following block stores the meta information that will be returned
+  ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
+  ** and autoinc. At this point there are two possibilities:
+  ** 
+  **     1. The specified column name was rowid", "oid" or "_rowid_" 
+  **        and there is no explicitly declared IPK column. 
+  **
+  **     2. The table is not a view and the column name identified an 
+  **        explicitly declared column. Copy meta information from *pCol.
+  */ 
+  if( pCol ){
+    zDataType = pCol->zType;
+    zCollSeq = pCol->zColl;
+    notnull = (pCol->notNull?1:0);
+    primarykey  = (pCol->isPrimKey?1:0);
+    autoinc = ((pTab->iPKey==iCol && pTab->autoInc)?1:0);
+  }else{
+    zDataType = "INTEGER";
+    primarykey = 1;
+  }
+  if( !zCollSeq ){
+    zCollSeq = "BINARY";
+  }
+
+error_out:
+  if( sqlite3SafetyOff(db) ){
+    rc = SQLITE_MISUSE;
+  }
+
+  /* Whether the function call succeeded or failed, set the output parameters
+  ** to whatever their local counterparts contain. If an error did occur,
+  ** this has the effect of zeroing all output parameters.
+  */
+  if( pzDataType ) *pzDataType = zDataType;
+  if( pzCollSeq ) *pzCollSeq = zCollSeq;
+  if( pNotNull ) *pNotNull = notnull;
+  if( pPrimaryKey ) *pPrimaryKey = primarykey;
+  if( pAutoinc ) *pAutoinc = autoinc;
+
+  if( SQLITE_OK==rc && !pTab ){
+    sqlite3SetString(&zErrMsg, "no such table column: ", zTableName, ".", 
+        zColumnName, 0);
+    rc = SQLITE_ERROR;
+  }
+  sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
+  sqliteFree(zErrMsg);
+  return sqlite3ApiExit(db, rc);
+}
+#endif

Modified: packages/libdbd-sqlite3-perl/trunk/opcodes.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/opcodes.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/opcodes.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -9,27 +9,27 @@
  /*   5 */ "MoveLe",
  /*   6 */ "Variable",
  /*   7 */ "Pull",
- /*   8 */ "Sort",
- /*   9 */ "IfNot",
- /*  10 */ "Gosub",
- /*  11 */ "NotFound",
- /*  12 */ "MoveLt",
- /*  13 */ "Rowid",
- /*  14 */ "CreateIndex",
- /*  15 */ "Push",
- /*  16 */ "Explain",
- /*  17 */ "Statement",
- /*  18 */ "Callback",
- /*  19 */ "MemLoad",
- /*  20 */ "DropIndex",
- /*  21 */ "Null",
- /*  22 */ "ToInt",
- /*  23 */ "Int64",
- /*  24 */ "LoadAnalysis",
- /*  25 */ "IdxInsert",
- /*  26 */ "Next",
- /*  27 */ "SetNumColumns",
- /*  28 */ "ToNumeric",
+ /*   8 */ "RealAffinity",
+ /*   9 */ "Sort",
+ /*  10 */ "IfNot",
+ /*  11 */ "Gosub",
+ /*  12 */ "NotFound",
+ /*  13 */ "MoveLt",
+ /*  14 */ "Rowid",
+ /*  15 */ "CreateIndex",
+ /*  16 */ "Not",
+ /*  17 */ "Push",
+ /*  18 */ "Explain",
+ /*  19 */ "Statement",
+ /*  20 */ "Callback",
+ /*  21 */ "MemLoad",
+ /*  22 */ "DropIndex",
+ /*  23 */ "Null",
+ /*  24 */ "Int64",
+ /*  25 */ "LoadAnalysis",
+ /*  26 */ "IdxInsert",
+ /*  27 */ "Next",
+ /*  28 */ "SetNumColumns",
  /*  29 */ "MemInt",
  /*  30 */ "Dup",
  /*  31 */ "Rewind",
@@ -60,81 +60,88 @@
  /*  56 */ "Vacuum",
  /*  57 */ "If",
  /*  58 */ "Destroy",
- /*  59 */ "AggStep",
- /*  60 */ "Clear",
- /*  61 */ "Insert",
- /*  62 */ "IdxGE",
- /*  63 */ "MakeRecord",
- /*  64 */ "SetCookie",
- /*  65 */ "Prev",
- /*  66 */ "ContextPush",
- /*  67 */ "Or",
- /*  68 */ "And",
- /*  69 */ "Not",
- /*  70 */ "DropTrigger",
- /*  71 */ "IdxGT",
- /*  72 */ "MemNull",
- /*  73 */ "IsNull",
- /*  74 */ "NotNull",
- /*  75 */ "Ne",
- /*  76 */ "Eq",
- /*  77 */ "Gt",
- /*  78 */ "Le",
- /*  79 */ "Lt",
- /*  80 */ "Ge",
- /*  81 */ "Return",
- /*  82 */ "BitAnd",
- /*  83 */ "BitOr",
- /*  84 */ "ShiftLeft",
- /*  85 */ "ShiftRight",
- /*  86 */ "Add",
- /*  87 */ "Subtract",
- /*  88 */ "Multiply",
- /*  89 */ "Divide",
- /*  90 */ "Remainder",
- /*  91 */ "Concat",
- /*  92 */ "Negative",
- /*  93 */ "OpenWrite",
- /*  94 */ "BitNot",
- /*  95 */ "String8",
- /*  96 */ "Integer",
- /*  97 */ "Transaction",
- /*  98 */ "OpenVirtual",
- /*  99 */ "CollSeq",
- /* 100 */ "ToBlob",
+ /*  59 */ "Or",
+ /*  60 */ "And",
+ /*  61 */ "AggStep",
+ /*  62 */ "Clear",
+ /*  63 */ "Insert",
+ /*  64 */ "IsNull",
+ /*  65 */ "NotNull",
+ /*  66 */ "Ne",
+ /*  67 */ "Eq",
+ /*  68 */ "Gt",
+ /*  69 */ "Le",
+ /*  70 */ "Lt",
+ /*  71 */ "Ge",
+ /*  72 */ "IdxGE",
+ /*  73 */ "BitAnd",
+ /*  74 */ "BitOr",
+ /*  75 */ "ShiftLeft",
+ /*  76 */ "ShiftRight",
+ /*  77 */ "Add",
+ /*  78 */ "Subtract",
+ /*  79 */ "Multiply",
+ /*  80 */ "Divide",
+ /*  81 */ "Remainder",
+ /*  82 */ "Concat",
+ /*  83 */ "Negative",
+ /*  84 */ "IfMemZero",
+ /*  85 */ "BitNot",
+ /*  86 */ "String8",
+ /*  87 */ "MakeRecord",
+ /*  88 */ "SetCookie",
+ /*  89 */ "Prev",
+ /*  90 */ "ContextPush",
+ /*  91 */ "DropTrigger",
+ /*  92 */ "IdxGT",
+ /*  93 */ "MemNull",
+ /*  94 */ "IfMemNeg",
+ /*  95 */ "Return",
+ /*  96 */ "OpenWrite",
+ /*  97 */ "Integer",
+ /*  98 */ "Transaction",
+ /*  99 */ "OpenVirtual",
+ /* 100 */ "CollSeq",
  /* 101 */ "Sequence",
  /* 102 */ "ContextPop",
  /* 103 */ "CreateTable",
  /* 104 */ "AddImm",
- /* 105 */ "ToText",
- /* 106 */ "IdxIsNull",
- /* 107 */ "DropTable",
- /* 108 */ "IsUnique",
- /* 109 */ "Noop",
- /* 110 */ "RowKey",
- /* 111 */ "Expire",
- /* 112 */ "FifoRead",
- /* 113 */ "Delete",
- /* 114 */ "IfMemPos",
- /* 115 */ "MemIncr",
- /* 116 */ "Blob",
- /* 117 */ "MakeIdxRec",
- /* 118 */ "Goto",
- /* 119 */ "ParseSchema",
- /* 120 */ "Pop",
+ /* 105 */ "IdxIsNull",
+ /* 106 */ "DropTable",
+ /* 107 */ "IsUnique",
+ /* 108 */ "Noop",
+ /* 109 */ "RowKey",
+ /* 110 */ "Expire",
+ /* 111 */ "FifoRead",
+ /* 112 */ "Delete",
+ /* 113 */ "IfMemPos",
+ /* 114 */ "MemIncr",
+ /* 115 */ "Blob",
+ /* 116 */ "MakeIdxRec",
+ /* 117 */ "Goto",
+ /* 118 */ "ParseSchema",
+ /* 119 */ "Pop",
+ /* 120 */ "TableLock",
  /* 121 */ "VerifyCookie",
  /* 122 */ "Column",
  /* 123 */ "OpenRead",
- /* 124 */ "ResetCount",
- /* 125 */ "NotUsed_125",
- /* 126 */ "NotUsed_126",
+ /* 124 */ "Real",
+ /* 125 */ "HexBlob",
+ /* 126 */ "ResetCount",
  /* 127 */ "NotUsed_127",
  /* 128 */ "NotUsed_128",
  /* 129 */ "NotUsed_129",
  /* 130 */ "NotUsed_130",
  /* 131 */ "NotUsed_131",
  /* 132 */ "NotUsed_132",
- /* 133 */ "Real",
- /* 134 */ "HexBlob",
+ /* 133 */ "NotUsed_133",
+ /* 134 */ "NotUsed_134",
+ /* 135 */ "NotUsed_135",
+ /* 136 */ "NotUsed_136",
+ /* 137 */ "ToText",
+ /* 138 */ "ToBlob",
+ /* 139 */ "ToNumeric",
+ /* 140 */ "ToInt",
+ /* 141 */ "ToReal",
 };
 #endif

Modified: packages/libdbd-sqlite3-perl/trunk/opcodes.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/opcodes.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/opcodes.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -4,43 +4,45 @@
 #define OP_AutoCommit                           2
 #define OP_Found                                3
 #define OP_NullRow                              4
-#define OP_Lt                                  79   /* same as TK_LT       */
+#define OP_Lt                                  70   /* same as TK_LT       */
 #define OP_MoveLe                               5
 #define OP_Variable                             6
 #define OP_Pull                                 7
-#define OP_Sort                                 8
-#define OP_IfNot                                9
-#define OP_Gosub                               10
-#define OP_Add                                 86   /* same as TK_PLUS     */
-#define OP_NotFound                            11
-#define OP_IsNull                              73   /* same as TK_ISNULL   */
-#define OP_MoveLt                              12
-#define OP_Rowid                               13
-#define OP_CreateIndex                         14
-#define OP_Push                                15
-#define OP_Explain                             16
-#define OP_Statement                           17
-#define OP_Callback                            18
-#define OP_MemLoad                             19
-#define OP_DropIndex                           20
-#define OP_Null                                21
-#define OP_ToInt                               22
-#define OP_Int64                               23
-#define OP_LoadAnalysis                        24
-#define OP_IdxInsert                           25
-#define OP_Next                                26
-#define OP_SetNumColumns                       27
-#define OP_ToNumeric                           28
-#define OP_Ge                                  80   /* same as TK_GE       */
-#define OP_BitNot                              94   /* same as TK_BITNOT   */
+#define OP_RealAffinity                         8
+#define OP_Sort                                 9
+#define OP_IfNot                               10
+#define OP_Gosub                               11
+#define OP_Add                                 77   /* same as TK_PLUS     */
+#define OP_NotFound                            12
+#define OP_IsNull                              64   /* same as TK_ISNULL   */
+#define OP_MoveLt                              13
+#define OP_Rowid                               14
+#define OP_CreateIndex                         15
+#define OP_Push                                17
+#define OP_Explain                             18
+#define OP_Statement                           19
+#define OP_Callback                            20
+#define OP_MemLoad                             21
+#define OP_DropIndex                           22
+#define OP_Null                                23
+#define OP_ToInt                              140   /* same as TK_TO_INT   */
+#define OP_Int64                               24
+#define OP_LoadAnalysis                        25
+#define OP_IdxInsert                           26
+#define OP_Next                                27
+#define OP_SetNumColumns                       28
+#define OP_ToNumeric                          139   /* same as TK_TO_NUMERIC*/
+#define OP_Ge                                  71   /* same as TK_GE       */
+#define OP_BitNot                              85   /* same as TK_BITNOT   */
 #define OP_MemInt                              29
 #define OP_Dup                                 30
 #define OP_Rewind                              31
-#define OP_Multiply                            88   /* same as TK_STAR     */
-#define OP_Gt                                  77   /* same as TK_GT       */
+#define OP_Multiply                            79   /* same as TK_STAR     */
+#define OP_ToReal                             141   /* same as TK_TO_REAL  */
+#define OP_Gt                                  68   /* same as TK_GT       */
 #define OP_Last                                32
 #define OP_MustBeInt                           33
-#define OP_Ne                                  75   /* same as TK_NE       */
+#define OP_Ne                                  66   /* same as TK_NE       */
 #define OP_MoveGe                              34
 #define OP_String                              35
 #define OP_ForceInt                            36
@@ -49,101 +51,109 @@
 #define OP_AbsValue                            39
 #define OP_RowData                             40
 #define OP_IdxRowid                            41
-#define OP_BitOr                               83   /* same as TK_BITOR    */
-#define OP_NotNull                             74   /* same as TK_NOTNULL  */
+#define OP_BitOr                               74   /* same as TK_BITOR    */
+#define OP_NotNull                             65   /* same as TK_NOTNULL  */
 #define OP_MoveGt                              42
-#define OP_Not                                 69   /* same as TK_NOT      */
+#define OP_Not                                 16   /* same as TK_NOT      */
 #define OP_OpenPseudo                          43
 #define OP_Halt                                44
 #define OP_MemMove                             45
 #define OP_NewRowid                            46
-#define OP_Real                               133   /* same as TK_FLOAT    */
+#define OP_Real                               124   /* same as TK_FLOAT    */
 #define OP_IdxLT                               47
 #define OP_Distinct                            48
 #define OP_MemMax                              49
 #define OP_Function                            50
 #define OP_IntegrityCk                         51
-#define OP_Remainder                           90   /* same as TK_REM      */
-#define OP_HexBlob                            134   /* same as TK_BLOB     */
-#define OP_ShiftLeft                           84   /* same as TK_LSHIFT   */
+#define OP_Remainder                           81   /* same as TK_REM      */
+#define OP_HexBlob                            125   /* same as TK_BLOB     */
+#define OP_ShiftLeft                           75   /* same as TK_LSHIFT   */
 #define OP_FifoWrite                           52
-#define OP_BitAnd                              82   /* same as TK_BITAND   */
-#define OP_Or                                  67   /* same as TK_OR       */
+#define OP_BitAnd                              73   /* same as TK_BITAND   */
+#define OP_Or                                  59   /* same as TK_OR       */
 #define OP_NotExists                           53
 #define OP_MemStore                            54
 #define OP_IdxDelete                           55
 #define OP_Vacuum                              56
 #define OP_If                                  57
 #define OP_Destroy                             58
-#define OP_AggStep                             59
-#define OP_Clear                               60
-#define OP_Insert                              61
-#define OP_IdxGE                               62
-#define OP_Divide                              89   /* same as TK_SLASH    */
-#define OP_String8                             95   /* same as TK_STRING   */
-#define OP_Concat                              91   /* same as TK_CONCAT   */
-#define OP_MakeRecord                          63
-#define OP_SetCookie                           64
-#define OP_Prev                                65
-#define OP_ContextPush                         66
-#define OP_DropTrigger                         70
-#define OP_IdxGT                               71
-#define OP_MemNull                             72
-#define OP_And                                 68   /* same as TK_AND      */
-#define OP_Return                              81
-#define OP_OpenWrite                           93
-#define OP_Integer                             96
-#define OP_Transaction                         97
-#define OP_OpenVirtual                         98
-#define OP_CollSeq                             99
-#define OP_ToBlob                             100
+#define OP_AggStep                             61
+#define OP_Clear                               62
+#define OP_Insert                              63
+#define OP_IdxGE                               72
+#define OP_Divide                              80   /* same as TK_SLASH    */
+#define OP_String8                             86   /* same as TK_STRING   */
+#define OP_IfMemZero                           84
+#define OP_Concat                              82   /* same as TK_CONCAT   */
+#define OP_MakeRecord                          87
+#define OP_SetCookie                           88
+#define OP_Prev                                89
+#define OP_ContextPush                         90
+#define OP_DropTrigger                         91
+#define OP_IdxGT                               92
+#define OP_MemNull                             93
+#define OP_IfMemNeg                            94
+#define OP_And                                 60   /* same as TK_AND      */
+#define OP_Return                              95
+#define OP_OpenWrite                           96
+#define OP_Integer                             97
+#define OP_Transaction                         98
+#define OP_OpenVirtual                         99
+#define OP_CollSeq                            100
+#define OP_ToBlob                             138   /* same as TK_TO_BLOB  */
 #define OP_Sequence                           101
 #define OP_ContextPop                         102
-#define OP_ShiftRight                          85   /* same as TK_RSHIFT   */
+#define OP_ShiftRight                          76   /* same as TK_RSHIFT   */
 #define OP_CreateTable                        103
 #define OP_AddImm                             104
-#define OP_ToText                             105
-#define OP_IdxIsNull                          106
-#define OP_DropTable                          107
-#define OP_IsUnique                           108
-#define OP_Noop                               109
-#define OP_RowKey                             110
-#define OP_Expire                             111
-#define OP_FifoRead                           112
-#define OP_Delete                             113
-#define OP_IfMemPos                           114
-#define OP_Subtract                            87   /* same as TK_MINUS    */
-#define OP_MemIncr                            115
-#define OP_Blob                               116
-#define OP_MakeIdxRec                         117
-#define OP_Goto                               118
-#define OP_Negative                            92   /* same as TK_UMINUS   */
-#define OP_ParseSchema                        119
-#define OP_Eq                                  76   /* same as TK_EQ       */
-#define OP_Pop                                120
-#define OP_Le                                  78   /* same as TK_LE       */
+#define OP_ToText                             137   /* same as TK_TO_TEXT  */
+#define OP_IdxIsNull                          105
+#define OP_DropTable                          106
+#define OP_IsUnique                           107
+#define OP_Noop                               108
+#define OP_RowKey                             109
+#define OP_Expire                             110
+#define OP_FifoRead                           111
+#define OP_Delete                             112
+#define OP_IfMemPos                           113
+#define OP_Subtract                            78   /* same as TK_MINUS    */
+#define OP_MemIncr                            114
+#define OP_Blob                               115
+#define OP_MakeIdxRec                         116
+#define OP_Goto                               117
+#define OP_Negative                            83   /* same as TK_UMINUS   */
+#define OP_ParseSchema                        118
+#define OP_Eq                                  67   /* same as TK_EQ       */
+#define OP_Pop                                119
+#define OP_Le                                  69   /* same as TK_LE       */
+#define OP_TableLock                          120
 #define OP_VerifyCookie                       121
 #define OP_Column                             122
 #define OP_OpenRead                           123
-#define OP_ResetCount                         124
+#define OP_ResetCount                         126
 
 /* The following opcode values are never used */
-#define OP_NotUsed_125                        125
-#define OP_NotUsed_126                        126
 #define OP_NotUsed_127                        127
 #define OP_NotUsed_128                        128
 #define OP_NotUsed_129                        129
 #define OP_NotUsed_130                        130
 #define OP_NotUsed_131                        131
 #define OP_NotUsed_132                        132
+#define OP_NotUsed_133                        133
+#define OP_NotUsed_134                        134
+#define OP_NotUsed_135                        135
+#define OP_NotUsed_136                        136
 
-#define NOPUSH_MASK_0 40892
-#define NOPUSH_MASK_1 40790
-#define NOPUSH_MASK_2 40055
-#define NOPUSH_MASK_3 31731
-#define NOPUSH_MASK_4 65279
-#define NOPUSH_MASK_5 30719
-#define NOPUSH_MASK_6 48990
-#define NOPUSH_MASK_7 7118
-#define NOPUSH_MASK_8 0
-#define NOPUSH_MASK_9 0
+/* Opcodes that are guaranteed to never push a value onto the stack
+** contain a 1 their corresponding position of the following mask
+** set.  See the opcodeNoPush() function in vdbeaux.c  */
+#define NOPUSH_MASK_0 0x3fbc
+#define NOPUSH_MASK_1 0x9e5b
+#define NOPUSH_MASK_2 0x9c77
+#define NOPUSH_MASK_3 0xfbf3
+#define NOPUSH_MASK_4 0xffff
+#define NOPUSH_MASK_5 0xdf3b
+#define NOPUSH_MASK_6 0x5f5d
+#define NOPUSH_MASK_7 0x4be7
+#define NOPUSH_MASK_8 0x3e00
+#define NOPUSH_MASK_9 0x0000

Copied: packages/libdbd-sqlite3-perl/trunk/os.c (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/os.c)

Modified: packages/libdbd-sqlite3-perl/trunk/os.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/os.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/os.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -18,12 +18,10 @@
 #define _SQLITE_OS_H_
 
 /*
-** Figure out if we are dealing with Unix, Windows or MacOS.
-**
-** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix.
-**      The MacOS build is designed to use CodeWarrior (tested with v8)
+** Figure out if we are dealing with Unix, Windows, or some other
+** operating system.
 */
-#if !defined(OS_UNIX) && !defined(OS_TEST) && !defined(OS_OTHER)
+#if !defined(OS_UNIX) && !defined(OS_OTHER)
 # define OS_OTHER 0
 # ifndef OS_WIN
 #   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
@@ -42,27 +40,17 @@
 # endif
 #endif
 
+
 /*
-** Invoke the appropriate operating-system specific header file.
+** Define the maximum size of a temporary filename
 */
-#if OS_TEST
-# include "os_test.h"
-#endif
-#if OS_UNIX
-# include "os_unix.h"
-#endif
 #if OS_WIN
-# include "os_win.h"
+# include <windows.h>
+# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
+#else
+# define SQLITE_TEMPNAME_SIZE 200
 #endif
 
-/* os_other.c and os_other.h are not delivered with SQLite.  These files
-** are place-holders that can be filled in by third-party developers to
-** implement backends to their on proprietary operating systems.
-*/
-#if OS_OTHER
-# include "os_other.h"
-#endif
-
 /* If the SET_FULLSYNC macro is not defined above, then make it
 ** a no-op
 */
@@ -84,6 +72,104 @@
 #endif
 
 /*
+** Define the interfaces for Unix and for Windows.
+*/
+#if OS_UNIX
+#define sqlite3OsOpenReadWrite      sqlite3UnixOpenReadWrite
+#define sqlite3OsOpenExclusive      sqlite3UnixOpenExclusive
+#define sqlite3OsOpenReadOnly       sqlite3UnixOpenReadOnly
+#define sqlite3OsDelete             sqlite3UnixDelete
+#define sqlite3OsFileExists         sqlite3UnixFileExists
+#define sqlite3OsFullPathname       sqlite3UnixFullPathname
+#define sqlite3OsIsDirWritable      sqlite3UnixIsDirWritable
+#define sqlite3OsSyncDirectory      sqlite3UnixSyncDirectory
+#define sqlite3OsTempFileName       sqlite3UnixTempFileName
+#define sqlite3OsRandomSeed         sqlite3UnixRandomSeed
+#define sqlite3OsSleep              sqlite3UnixSleep
+#define sqlite3OsCurrentTime        sqlite3UnixCurrentTime
+#define sqlite3OsEnterMutex         sqlite3UnixEnterMutex
+#define sqlite3OsLeaveMutex         sqlite3UnixLeaveMutex
+#define sqlite3OsInMutex            sqlite3UnixInMutex
+#define sqlite3OsThreadSpecificData sqlite3UnixThreadSpecificData
+#define sqlite3OsMalloc             sqlite3GenericMalloc
+#define sqlite3OsRealloc            sqlite3GenericRealloc
+#define sqlite3OsFree               sqlite3GenericFree
+#define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#endif
+#if OS_WIN
+#define sqlite3OsOpenReadWrite      sqlite3WinOpenReadWrite
+#define sqlite3OsOpenExclusive      sqlite3WinOpenExclusive
+#define sqlite3OsOpenReadOnly       sqlite3WinOpenReadOnly
+#define sqlite3OsDelete             sqlite3WinDelete
+#define sqlite3OsFileExists         sqlite3WinFileExists
+#define sqlite3OsFullPathname       sqlite3WinFullPathname
+#define sqlite3OsIsDirWritable      sqlite3WinIsDirWritable
+#define sqlite3OsSyncDirectory      sqlite3WinSyncDirectory
+#define sqlite3OsTempFileName       sqlite3WinTempFileName
+#define sqlite3OsRandomSeed         sqlite3WinRandomSeed
+#define sqlite3OsSleep              sqlite3WinSleep
+#define sqlite3OsCurrentTime        sqlite3WinCurrentTime
+#define sqlite3OsEnterMutex         sqlite3WinEnterMutex
+#define sqlite3OsLeaveMutex         sqlite3WinLeaveMutex
+#define sqlite3OsInMutex            sqlite3WinInMutex
+#define sqlite3OsThreadSpecificData sqlite3WinThreadSpecificData
+#define sqlite3OsMalloc             sqlite3GenericMalloc
+#define sqlite3OsRealloc            sqlite3GenericRealloc
+#define sqlite3OsFree               sqlite3GenericFree
+#define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#endif
+
+/*
+** If using an alternative OS interface, then we must have an "os_other.h"
+** header file available for that interface.  Presumably the "os_other.h"
+** header file contains #defines similar to those above.
+*/
+#if OS_OTHER
+# include "os_other.h"
+#endif
+
+
+
+/*
+** Forward declarations
+*/
+typedef struct OsFile OsFile;
+typedef struct IoMethod IoMethod;
+
+/*
+** An instance of the following structure contains pointers to all
+** methods on an OsFile object.
+*/
+struct IoMethod {
+  int (*xClose)(OsFile**);
+  int (*xOpenDirectory)(OsFile*, const char*);
+  int (*xRead)(OsFile*, void*, int amt);
+  int (*xWrite)(OsFile*, const void*, int amt);
+  int (*xSeek)(OsFile*, i64 offset);
+  int (*xTruncate)(OsFile*, i64 size);
+  int (*xSync)(OsFile*, int);
+  void (*xSetFullSync)(OsFile *id, int setting);
+  int (*xFileHandle)(OsFile *id);
+  int (*xFileSize)(OsFile*, i64 *pSize);
+  int (*xLock)(OsFile*, int);
+  int (*xUnlock)(OsFile*, int);
+  int (*xLockState)(OsFile *id);
+  int (*xCheckReservedLock)(OsFile *id);
+};
+
+/*
+** The OsFile object describes an open disk file in an OS-dependent way.
+** The version of OsFile defined here is a generic version.  Each OS
+** implementation defines its own subclass of this structure that contains
+** additional information needed to handle file I/O.  But the pMethod
+** entry (pointing to the virtual function table) always occurs first
+** so that we can always find the appropriate methods.
+*/
+struct OsFile {
+  IoMethod const *pMethod;
+};
+
+/*
 ** The following values may be passed as the second argument to
 ** sqlite3OsLock(). The various locks exhibit the following semantics:
 **
@@ -137,8 +223,10 @@
 ** a random byte is selected for a shared lock.  The pool of bytes for
 ** shared locks begins at SHARED_FIRST. 
 **
-** These #defines are available in os.h so that Unix can use the same
-** byte ranges for locking.  This leaves open the possiblity of having
+** These #defines are available in sqlite_aux.h so that adaptors for
+** connecting SQLite to other operating systems can use the same byte
+** ranges for locking.  In particular, the same locking strategy and
+** byte ranges are used for Unix.  This leaves open the possiblity of having
 ** clients on win95, winNT, and unix all talking to the same shared file
 ** and all locking correctly.  To do so would require that samba (or whatever
 ** tool is being used for file sharing) implements locks correctly between
@@ -172,36 +260,181 @@
 #define SHARED_FIRST      (PENDING_BYTE+2)
 #define SHARED_SIZE       510
 
-
-int sqlite3OsDelete(const char*);
-int sqlite3OsFileExists(const char*);
-int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
-int sqlite3OsOpenExclusive(const char*, OsFile*, int);
-int sqlite3OsOpenReadOnly(const char*, OsFile*);
-int sqlite3OsOpenDirectory(const char*, OsFile*);
-int sqlite3OsSyncDirectory(const char*);
-int sqlite3OsTempFileName(char*);
-int sqlite3OsIsDirWritable(char*);
-int sqlite3OsClose(OsFile*);
+/*
+** Prototypes for operating system interface routines.
+*/
+int sqlite3OsClose(OsFile**);
+int sqlite3OsOpenDirectory(OsFile*, const char*);
 int sqlite3OsRead(OsFile*, void*, int amt);
 int sqlite3OsWrite(OsFile*, const void*, int amt);
 int sqlite3OsSeek(OsFile*, i64 offset);
+int sqlite3OsTruncate(OsFile*, i64 size);
 int sqlite3OsSync(OsFile*, int);
-int sqlite3OsTruncate(OsFile*, i64 size);
+void sqlite3OsSetFullSync(OsFile *id, int setting);
+int sqlite3OsFileHandle(OsFile *id);
 int sqlite3OsFileSize(OsFile*, i64 *pSize);
-char *sqlite3OsFullPathname(const char*);
 int sqlite3OsLock(OsFile*, int);
 int sqlite3OsUnlock(OsFile*, int);
+int sqlite3OsLockState(OsFile *id);
 int sqlite3OsCheckReservedLock(OsFile *id);
-
-
-/* The interface for file I/O is above.  Other miscellaneous functions
-** are below */
-
+int sqlite3OsOpenReadWrite(const char*, OsFile**, int*);
+int sqlite3OsOpenExclusive(const char*, OsFile**, int);
+int sqlite3OsOpenReadOnly(const char*, OsFile**);
+int sqlite3OsDelete(const char*);
+int sqlite3OsFileExists(const char*);
+char *sqlite3OsFullPathname(const char*);
+int sqlite3OsIsDirWritable(char*);
+int sqlite3OsSyncDirectory(const char*);
+int sqlite3OsTempFileName(char*);
 int sqlite3OsRandomSeed(char*);
 int sqlite3OsSleep(int ms);
 int sqlite3OsCurrentTime(double*);
 void sqlite3OsEnterMutex(void);
 void sqlite3OsLeaveMutex(void);
+int sqlite3OsInMutex(int);
+ThreadData *sqlite3OsThreadSpecificData(int);
+void *sqlite3OsMalloc(int);
+void *sqlite3OsRealloc(void *, int);
+void sqlite3OsFree(void *);
+int sqlite3OsAllocationSize(void *);
 
+/*
+** If the SQLITE_ENABLE_REDEF_IO macro is defined, then the OS-layer
+** interface routines are not called directly but are invoked using
+** pointers to functions.  This allows the implementation of various
+** OS-layer interface routines to be modified at run-time.  There are
+** obscure but legitimate reasons for wanting to do this.  But for
+** most users, a direct call to the underlying interface is preferable
+** so the the redefinable I/O interface is turned off by default.
+*/
+#ifdef SQLITE_ENABLE_REDEF_IO
+
+/*
+** When redefinable I/O is enabled, a single global instance of the
+** following structure holds pointers to the routines that SQLite 
+** uses to talk with the underlying operating system.  Modify this
+** structure (before using any SQLite API!) to accomodate perculiar
+** operating system interfaces or behaviors.
+*/
+struct sqlite3OsVtbl {
+  int (*xOpenReadWrite)(const char*, OsFile**, int*);
+  int (*xOpenExclusive)(const char*, OsFile**, int);
+  int (*xOpenReadOnly)(const char*, OsFile**);
+
+  int (*xDelete)(const char*);
+  int (*xFileExists)(const char*);
+  char *(*xFullPathname)(const char*);
+  int (*xIsDirWritable)(char*);
+  int (*xSyncDirectory)(const char*);
+  int (*xTempFileName)(char*);
+
+  int (*xRandomSeed)(char*);
+  int (*xSleep)(int ms);
+  int (*xCurrentTime)(double*);
+
+  void (*xEnterMutex)(void);
+  void (*xLeaveMutex)(void);
+  int (*xInMutex)(int);
+  ThreadData *(*xThreadSpecificData)(int);
+
+  void *(*xMalloc)(int);
+  void *(*xRealloc)(void *, int);
+  void (*xFree)(void *);
+  int (*xAllocationSize)(void *);
+};
+
+/* Macro used to comment out routines that do not exists when there is
+** no disk I/O 
+*/
+#ifdef SQLITE_OMIT_DISKIO
+# define IF_DISKIO(X)  0
+#else
+# define IF_DISKIO(X)  X
+#endif
+
+#ifdef _SQLITE_OS_C_
+  /*
+  ** The os.c file implements the global virtual function table.
+  */
+  struct sqlite3OsVtbl sqlite3Os = {
+    IF_DISKIO( sqlite3OsOpenReadWrite ),
+    IF_DISKIO( sqlite3OsOpenExclusive ),
+    IF_DISKIO( sqlite3OsOpenReadOnly ),
+    IF_DISKIO( sqlite3OsDelete ),
+    IF_DISKIO( sqlite3OsFileExists ),
+    IF_DISKIO( sqlite3OsFullPathname ),
+    IF_DISKIO( sqlite3OsIsDirWritable ),
+    IF_DISKIO( sqlite3OsSyncDirectory ),
+    IF_DISKIO( sqlite3OsTempFileName ),
+    sqlite3OsRandomSeed,
+    sqlite3OsSleep,
+    sqlite3OsCurrentTime,
+    sqlite3OsEnterMutex,
+    sqlite3OsLeaveMutex,
+    sqlite3OsInMutex,
+    sqlite3OsThreadSpecificData,
+    sqlite3OsMalloc,
+    sqlite3OsRealloc,
+    sqlite3OsFree,
+    sqlite3OsAllocationSize
+  };
+#else
+  /*
+  ** Files other than os.c just reference the global virtual function table. 
+  */
+  extern struct sqlite3OsVtbl sqlite3Os;
+#endif /* _SQLITE_OS_C_ */
+
+
+/* This additional API routine is available with redefinable I/O */
+struct sqlite3OsVtbl *sqlite3_os_switch(void);
+
+
+/*
+** Redefine the OS interface to go through the virtual function table
+** rather than calling routines directly.
+*/
+#undef sqlite3OsOpenReadWrite
+#undef sqlite3OsOpenExclusive
+#undef sqlite3OsOpenReadOnly
+#undef sqlite3OsDelete
+#undef sqlite3OsFileExists
+#undef sqlite3OsFullPathname
+#undef sqlite3OsIsDirWritable
+#undef sqlite3OsSyncDirectory
+#undef sqlite3OsTempFileName
+#undef sqlite3OsRandomSeed
+#undef sqlite3OsSleep
+#undef sqlite3OsCurrentTime
+#undef sqlite3OsEnterMutex
+#undef sqlite3OsLeaveMutex
+#undef sqlite3OsInMutex
+#undef sqlite3OsThreadSpecificData
+#undef sqlite3OsMalloc
+#undef sqlite3OsRealloc
+#undef sqlite3OsFree
+#undef sqlite3OsAllocationSize
+#define sqlite3OsOpenReadWrite      sqlite3Os.xOpenReadWrite
+#define sqlite3OsOpenExclusive      sqlite3Os.xOpenExclusive
+#define sqlite3OsOpenReadOnly       sqlite3Os.xOpenReadOnly
+#define sqlite3OsDelete             sqlite3Os.xDelete
+#define sqlite3OsFileExists         sqlite3Os.xFileExists
+#define sqlite3OsFullPathname       sqlite3Os.xFullPathname
+#define sqlite3OsIsDirWritable      sqlite3Os.xIsDirWritable
+#define sqlite3OsSyncDirectory      sqlite3Os.xSyncDirectory
+#define sqlite3OsTempFileName       sqlite3Os.xTempFileName
+#define sqlite3OsRandomSeed         sqlite3Os.xRandomSeed
+#define sqlite3OsSleep              sqlite3Os.xSleep
+#define sqlite3OsCurrentTime        sqlite3Os.xCurrentTime
+#define sqlite3OsEnterMutex         sqlite3Os.xEnterMutex
+#define sqlite3OsLeaveMutex         sqlite3Os.xLeaveMutex
+#define sqlite3OsInMutex            sqlite3Os.xInMutex
+#define sqlite3OsThreadSpecificData sqlite3Os.xThreadSpecificData
+#define sqlite3OsMalloc             sqlite3Os.xMalloc
+#define sqlite3OsRealloc            sqlite3Os.xRealloc
+#define sqlite3OsFree               sqlite3Os.xFree
+#define sqlite3OsAllocationSize     sqlite3Os.xAllocationSize
+
+#endif /* SQLITE_ENABLE_REDEF_IO */
+
 #endif /* _SQLITE_OS_H_ */

Modified: packages/libdbd-sqlite3-perl/trunk/os_common.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/os_common.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/os_common.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -88,6 +88,7 @@
 ** is used for testing the I/O recovery logic.
 */
 #ifdef SQLITE_TEST
+int sqlite3_io_error_hit = 0;
 int sqlite3_io_error_pending = 0;
 int sqlite3_diskfull_pending = 0;
 int sqlite3_diskfull = 0;
@@ -95,7 +96,7 @@
    if( sqlite3_io_error_pending ) \
      if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
 static void local_ioerr(){
-  sqlite3_io_error_pending = 0;  /* Really just a place to set a breakpoint */
+  sqlite3_io_error_hit = 1;  /* Really just a place to set a breakpoint */
 }
 #define SimulateDiskfullError \
    if( sqlite3_diskfull_pending ){ \
@@ -121,3 +122,67 @@
 #else
 #define OpenCounter(X)
 #endif
+
+/*
+** sqlite3GenericMalloc
+** sqlite3GenericRealloc
+** sqlite3GenericOsFree
+** sqlite3GenericAllocationSize
+**
+** Implementation of the os level dynamic memory allocation interface in terms
+** of the standard malloc(), realloc() and free() found in many operating
+** systems. No rocket science here.
+**
+** There are two versions of these four functions here. The version
+** implemented here is only used if memory-management or memory-debugging is
+** enabled. This version allocates an extra 8-bytes at the beginning of each
+** block and stores the size of the allocation there.
+**
+** If neither memory-management or debugging is enabled, the second
+** set of implementations is used instead.
+*/
+#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || defined (SQLITE_MEMDEBUG)
+void *sqlite3GenericMalloc(int n){
+  char *p = (char *)malloc(n+8);
+  assert(n>0);
+  assert(sizeof(int)<=8);
+  if( p ){
+    *(int *)p = n;
+    p += 8;
+  }
+  return (void *)p;
+}
+void *sqlite3GenericRealloc(void *p, int n){
+  char *p2 = ((char *)p - 8);
+  assert(n>0);
+  p2 = (char*)realloc(p2, n+8);
+  if( p2 ){
+    *(int *)p2 = n;
+    p2 += 8;
+  }
+  return (void *)p2;
+}
+void sqlite3GenericFree(void *p){
+  assert(p);
+  free((void *)((char *)p - 8));
+}
+int sqlite3GenericAllocationSize(void *p){
+  return p ? *(int *)((char *)p - 8) : 0;
+}
+#else
+void *sqlite3GenericMalloc(int n){
+  char *p = (char *)malloc(n);
+  return (void *)p;
+}
+void *sqlite3GenericRealloc(void *p, int n){
+  assert(n>0);
+  p = realloc(p, n);
+  return p;
+}
+void sqlite3GenericFree(void *p){
+  assert(p);
+  free(p);
+}
+/* Never actually used, but needed for the linker */
+int sqlite3GenericAllocationSize(void *p){ return 0; }
+#endif

Modified: packages/libdbd-sqlite3-perl/trunk/os_unix.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/os_unix.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/os_unix.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -16,15 +16,101 @@
 #include "os.h"
 #if OS_UNIX              /* This file is used on unix only */
 
+/*
+** These #defines should enable >2GB file support on Posix if the
+** underlying operating system supports it.  If the OS lacks
+** large file support, these should be no-ops.
+**
+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
+** on the compiler command line.  This is necessary if you are compiling
+** on a recent machine (ex: RedHat 7.2) but you want your code to work
+** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
+** without this option, LFS is enable.  But LFS does not exist in the kernel
+** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
+** portability you should omit LFS.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE       1
+# ifndef _FILE_OFFSET_BITS
+#   define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
 
+/*
+** standard include files.
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include <time.h>
 #include <sys/time.h>
 #include <errno.h>
-#include <unistd.h>
 
 /*
+** If we are to be thread-safe, include the pthreads header and define
+** the SQLITE_UNIX_THREADS macro.
+*/
+#if defined(THREADSAFE) && THREADSAFE
+# include <pthread.h>
+# define SQLITE_UNIX_THREADS 1
+#endif
+
+/*
+** Default permissions when creating a new file
+*/
+#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
+# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
+#endif
+
+
+
+/*
+** The unixFile structure is subclass of OsFile specific for the unix
+** protability layer.
+*/
+typedef struct unixFile unixFile;
+struct unixFile {
+  IoMethod const *pMethod;  /* Always the first entry */
+  struct openCnt *pOpen;    /* Info about all open fd's on this inode */
+  struct lockInfo *pLock;   /* Info about locks on this inode */
+  int h;                    /* The file descriptor */
+  unsigned char locktype;   /* The type of lock held on this fd */
+  unsigned char isOpen;     /* True if needs to be closed */
+  unsigned char fullSync;   /* Use F_FULLSYNC if available */
+  int dirfd;                /* File descriptor for the directory */
+  i64 offset;               /* Seek offset */
+#ifdef SQLITE_UNIX_THREADS
+  pthread_t tid;            /* The thread that "owns" this OsFile */
+#endif
+};
+
+/*
+** Provide the ability to override some OS-layer functions during
+** testing.  This is used to simulate OS crashes to verify that 
+** commits are atomic even in the event of an OS crash.
+*/
+#ifdef SQLITE_CRASH_TEST
+  extern int sqlite3CrashTestEnable;
+  extern int sqlite3CrashOpenReadWrite(const char*, OsFile**, int*);
+  extern int sqlite3CrashOpenExclusive(const char*, OsFile**, int);
+  extern int sqlite3CrashOpenReadOnly(const char*, OsFile**, int);
+# define CRASH_TEST_OVERRIDE(X,A,B,C) \
+    if(sqlite3CrashTestEnable){ return X(A,B,C); }
+#else
+# define CRASH_TEST_OVERRIDE(X,A,B,C)  /* no-op */
+#endif
+
+
+/*
+** Include code that is common to all os_*.c files
+*/
+#include "os_common.h"
+
+/*
 ** Do not include any of the File I/O interface procedures if the
-** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
+** SQLITE_OMIT_DISKIO macro is defined (indicating that the database
 ** will be in-memory only)
 */
 #ifndef SQLITE_OMIT_DISKIO
@@ -51,18 +137,13 @@
 ** The DJGPP compiler environment looks mostly like Unix, but it
 ** lacks the fcntl() system call.  So redefine fcntl() to be something
 ** that always succeeds.  This means that locking does not occur under
-** DJGPP.  But its DOS - what did you expect?
+** DJGPP.  But it's DOS - what did you expect?
 */
 #ifdef __DJGPP__
 # define fcntl(A,B,C) 0
 #endif
 
 /*
-** Include code that is common to all os_*.c files
-*/
-#include "os_common.h"
-
-/*
 ** The threadid macro resolves to the thread-id or to 0.  Used for
 ** testing and debugging only.
 */
@@ -80,10 +161,18 @@
 ** means that sqlite3* database handles cannot be moved from one thread
 ** to another.  This logic makes sure a user does not try to do that
 ** by mistake.
+**
+** Version 3.3.1 (2006-01-15):  OsFiles can be moved from one thread to
+** another as long as we are running on a system that supports threads
+** overriding each others locks (which now the most common behavior)
+** or if no locks are held.  But the OsFile.pLock field needs to be
+** recomputed because its key includes the thread-id.  See the 
+** transferOwnership() function below for additional information
 */
-#ifdef SQLITE_UNIX_THREADS
-# define SET_THREADID(X)   X->tid = pthread_self()
-# define CHECK_THREADID(X) (!pthread_equal(X->tid, pthread_self()))
+#if defined(SQLITE_UNIX_THREADS)
+# define SET_THREADID(X)   (X)->tid = pthread_self()
+# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \
+                            !pthread_equal((X)->tid, pthread_self()))
 #else
 # define SET_THREADID(X)
 # define CHECK_THREADID(X) 0
@@ -195,14 +284,14 @@
 **
 ** If threads cannot override each others locks, then we set the
 ** lockKey.tid field to the thread ID.  If threads can override
-** each others locks then tid is always set to zero.  tid is also
-** set to zero if we compile without threading support.
+** each others locks then tid is always set to zero.  tid is omitted
+** if we compile without threading support.
 */
 struct lockKey {
   dev_t dev;       /* Device number */
   ino_t ino;       /* Inode number */
 #ifdef SQLITE_UNIX_THREADS
-  pthread_t tid;   /* Thread ID or zero if threads cannot override each other */
+  pthread_t tid;   /* Thread ID or zero if threads can override each other */
 #endif
 };
 
@@ -248,13 +337,15 @@
 };
 
 /* 
-** These hash table maps inodes and process IDs into lockInfo and openCnt
-** structures.  Access to these hash tables must be protected by a mutex.
+** These hash tables map inodes and file descriptors (really, lockKey and
+** openKey structures) into lockInfo and openCnt structures.  Access to 
+** these hash tables must be protected by a mutex.
 */
-static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
-static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
+static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, 
+    sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0};
+static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 
+    sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0};
 
-
 #ifdef SQLITE_UNIX_THREADS
 /*
 ** This variable records whether or not threads can override each others
@@ -263,8 +354,25 @@
 **    0:  No.  Threads cannot override each others locks.
 **    1:  Yes.  Threads can override each others locks.
 **   -1:  We don't know yet.
+**
+** On some systems, we know at compile-time if threads can override each
+** others locks.  On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro
+** will be set appropriately.  On other systems, we have to check at
+** runtime.  On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is
+** undefined.
+**
+** This variable normally has file scope only.  But during testing, we make
+** it a global so that the test code can change its value in order to verify
+** that the right stuff happens in either case.
 */
-static int threadsOverrideEachOthersLocks = -1;
+#ifndef SQLITE_THREAD_OVERRIDE_LOCK
+# define SQLITE_THREAD_OVERRIDE_LOCK -1
+#endif
+#ifdef SQLITE_TEST
+int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
+#else
+static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
+#endif
 
 /*
 ** This structure holds information passed into individual test
@@ -283,7 +391,7 @@
 ** This routine is used for troubleshooting locks on multithreaded
 ** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE
 ** command-line option on the compiler.  This code is normally
-** turnned off.
+** turned off.
 */
 static int lockTrace(int fd, int op, struct flock *p){
   char *zOpName, *zType;
@@ -353,7 +461,7 @@
 ** can override each others locks then sets the 
 ** threadsOverrideEachOthersLocks variable appropriately.
 */
-static void testThreadLockingBehavior(fd_orig){
+static void testThreadLockingBehavior(int fd_orig){
   int fd;
   struct threadTestData d[2];
   pthread_t t[2];
@@ -381,10 +489,11 @@
 ** Release a lockInfo structure previously allocated by findLockInfo().
 */
 static void releaseLockInfo(struct lockInfo *pLock){
+  assert( sqlite3OsInMutex(1) );
   pLock->nRef--;
   if( pLock->nRef==0 ){
     sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
-    sqliteFree(pLock);
+    sqlite3ThreadSafeFree(pLock);
   }
 }
 
@@ -392,18 +501,19 @@
 ** Release a openCnt structure previously allocated by findLockInfo().
 */
 static void releaseOpenCnt(struct openCnt *pOpen){
+  assert( sqlite3OsInMutex(1) );
   pOpen->nRef--;
   if( pOpen->nRef==0 ){
     sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
-    sqliteFree(pOpen->aPending);
-    sqliteFree(pOpen);
+    free(pOpen->aPending);
+    sqlite3ThreadSafeFree(pOpen);
   }
 }
 
 /*
 ** Given a file descriptor, locate lockInfo and openCnt structures that
-** describes that file descriptor.  Create a new ones if necessary.  The
-** return values might be unset if an error occurs.
+** describes that file descriptor.  Create new ones if necessary.  The
+** return values might be uninitialized if an error occurs.
 **
 ** Return the number of errors.
 */
@@ -420,6 +530,8 @@
   struct openCnt *pOpen;
   rc = fstat(fd, &statbuf);
   if( rc!=0 ) return 1;
+
+  assert( sqlite3OsInMutex(1) );
   memset(&key1, 0, sizeof(key1));
   key1.dev = statbuf.st_dev;
   key1.ino = statbuf.st_ino;
@@ -435,8 +547,11 @@
   pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
   if( pLock==0 ){
     struct lockInfo *pOld;
-    pLock = sqliteMallocRaw( sizeof(*pLock) );
-    if( pLock==0 ) return 1;
+    pLock = sqlite3ThreadSafeMalloc( sizeof(*pLock) );
+    if( pLock==0 ){
+      rc = 1;
+      goto exit_findlockinfo;
+    }
     pLock->key = key1;
     pLock->nRef = 1;
     pLock->cnt = 0;
@@ -444,44 +559,114 @@
     pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
     if( pOld!=0 ){
       assert( pOld==pLock );
-      sqliteFree(pLock);
-      return 1;
+      sqlite3ThreadSafeFree(pLock);
+      rc = 1;
+      goto exit_findlockinfo;
     }
   }else{
     pLock->nRef++;
   }
   *ppLock = pLock;
-  pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
-  if( pOpen==0 ){
-    struct openCnt *pOld;
-    pOpen = sqliteMallocRaw( sizeof(*pOpen) );
+  if( ppOpen!=0 ){
+    pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
     if( pOpen==0 ){
-      releaseLockInfo(pLock);
-      return 1;
+      struct openCnt *pOld;
+      pOpen = sqlite3ThreadSafeMalloc( sizeof(*pOpen) );
+      if( pOpen==0 ){
+        releaseLockInfo(pLock);
+        rc = 1;
+        goto exit_findlockinfo;
+      }
+      pOpen->key = key2;
+      pOpen->nRef = 1;
+      pOpen->nLock = 0;
+      pOpen->nPending = 0;
+      pOpen->aPending = 0;
+      pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
+      if( pOld!=0 ){
+        assert( pOld==pOpen );
+        sqlite3ThreadSafeFree(pOpen);
+        releaseLockInfo(pLock);
+        rc = 1;
+        goto exit_findlockinfo;
+      }
+    }else{
+      pOpen->nRef++;
     }
-    pOpen->key = key2;
-    pOpen->nRef = 1;
-    pOpen->nLock = 0;
-    pOpen->nPending = 0;
-    pOpen->aPending = 0;
-    pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
-    if( pOld!=0 ){
-      assert( pOld==pOpen );
-      sqliteFree(pOpen);
-      releaseLockInfo(pLock);
-      return 1;
-    }
-  }else{
-    pOpen->nRef++;
+    *ppOpen = pOpen;
   }
-  *ppOpen = pOpen;
-  return 0;
+
+exit_findlockinfo:
+  return rc;
 }
 
+#ifdef SQLITE_DEBUG
 /*
+** Helper function for printing out trace information from debugging
+** binaries. This returns the string represetation of the supplied
+** integer lock-type.
+*/
+static const char *locktypeName(int locktype){
+  switch( locktype ){
+  case NO_LOCK: return "NONE";
+  case SHARED_LOCK: return "SHARED";
+  case RESERVED_LOCK: return "RESERVED";
+  case PENDING_LOCK: return "PENDING";
+  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
+  }
+  return "ERROR";
+}
+#endif
+
+/*
+** If we are currently in a different thread than the thread that the
+** unixFile argument belongs to, then transfer ownership of the unixFile
+** over to the current thread.
+**
+** A unixFile is only owned by a thread on systems where one thread is
+** unable to override locks created by a different thread.  RedHat9 is
+** an example of such a system.
+**
+** Ownership transfer is only allowed if the unixFile is currently unlocked.
+** If the unixFile is locked and an ownership is wrong, then return
+** SQLITE_MISUSE.  SQLITE_OK is returned if everything works.
+*/
+#ifdef SQLITE_UNIX_THREADS
+static int transferOwnership(unixFile *pFile){
+  int rc;
+  pthread_t hSelf;
+  if( threadsOverrideEachOthersLocks ){
+    /* Ownership transfers not needed on this system */
+    return SQLITE_OK;
+  }
+  hSelf = pthread_self();
+  if( pthread_equal(pFile->tid, hSelf) ){
+    /* We are still in the same thread */
+    TRACE1("No-transfer, same thread\n");
+    return SQLITE_OK;
+  }
+  if( pFile->locktype!=NO_LOCK ){
+    /* We cannot change ownership while we are holding a lock! */
+    return SQLITE_MISUSE;
+  }
+  TRACE4("Transfer ownership of %d from %d to %d\n", pFile->h,pFile->tid,hSelf);
+  pFile->tid = hSelf;
+  releaseLockInfo(pFile->pLock);
+  rc = findLockInfo(pFile->h, &pFile->pLock, 0);
+  TRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
+     locktypeName(pFile->locktype),
+     locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
+  return rc;
+}
+#else
+  /* On single-threaded builds, ownership transfer is a no-op */
+# define transferOwnership(X) SQLITE_OK
+#endif
+
+/*
 ** Delete the named file
 */
-int sqlite3OsDelete(const char *zFilename){
+int sqlite3UnixDelete(const char *zFilename){
   unlink(zFilename);
   return SQLITE_OK;
 }
@@ -489,10 +674,13 @@
 /*
 ** Return TRUE if the named file exists.
 */
-int sqlite3OsFileExists(const char *zFilename){
+int sqlite3UnixFileExists(const char *zFilename){
   return access(zFilename, 0)==0;
 }
 
+/* Forward declaration */
+static int allocateUnixFile(unixFile *pInit, OsFile **pId);
+
 /*
 ** Attempt to open a file for both reading and writing.  If that
 ** fails, try opening it read-only.  If the file does not exist,
@@ -506,25 +694,26 @@
 ** On failure, the function returns SQLITE_CANTOPEN and leaves
 ** *id and *pReadonly unchanged.
 */
-int sqlite3OsOpenReadWrite(
+int sqlite3UnixOpenReadWrite(
   const char *zFilename,
-  OsFile *id,
+  OsFile **pId,
   int *pReadonly
 ){
   int rc;
-  assert( !id->isOpen );
-  id->dirfd = -1;
-  SET_THREADID(id);
-  id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
+  unixFile f;
+
+  CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly);
+  assert( 0==*pId );
+  f.h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
                           SQLITE_DEFAULT_FILE_PERMISSIONS);
-  if( id->h<0 ){
+  if( f.h<0 ){
 #ifdef EISDIR
     if( errno==EISDIR ){
       return SQLITE_CANTOPEN;
     }
 #endif
-    id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
-    if( id->h<0 ){
+    f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+    if( f.h<0 ){
       return SQLITE_CANTOPEN; 
     }
     *pReadonly = 1;
@@ -532,17 +721,14 @@
     *pReadonly = 0;
   }
   sqlite3OsEnterMutex();
-  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
+  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
   sqlite3OsLeaveMutex();
   if( rc ){
-    close(id->h);
+    close(f.h);
     return SQLITE_NOMEM;
   }
-  id->locktype = 0;
-  id->isOpen = 1;
-  TRACE3("OPEN    %-3d %s\n", id->h, zFilename);
-  OpenCounter(+1);
-  return SQLITE_OK;
+  TRACE3("OPEN    %-3d %s\n", f.h, zFilename);
+  return allocateUnixFile(&f, pId);
 }
 
 
@@ -560,36 +746,34 @@
 **
 ** On failure, return SQLITE_CANTOPEN.
 */
-int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
+int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
   int rc;
-  assert( !id->isOpen );
+  unixFile f;
+
+  CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag);
+  assert( 0==*pId );
   if( access(zFilename, 0)==0 ){
     return SQLITE_CANTOPEN;
   }
-  SET_THREADID(id);
-  id->dirfd = -1;
-  id->h = open(zFilename,
+  f.h = open(zFilename,
                 O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY,
                 SQLITE_DEFAULT_FILE_PERMISSIONS);
-  if( id->h<0 ){
+  if( f.h<0 ){
     return SQLITE_CANTOPEN;
   }
   sqlite3OsEnterMutex();
-  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
+  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
   sqlite3OsLeaveMutex();
   if( rc ){
-    close(id->h);
+    close(f.h);
     unlink(zFilename);
     return SQLITE_NOMEM;
   }
-  id->locktype = 0;
-  id->isOpen = 1;
   if( delFlag ){
     unlink(zFilename);
   }
-  TRACE3("OPEN-EX %-3d %s\n", id->h, zFilename);
-  OpenCounter(+1);
-  return SQLITE_OK;
+  TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename);
+  return allocateUnixFile(&f, pId);
 }
 
 /*
@@ -599,27 +783,25 @@
 **
 ** On failure, return SQLITE_CANTOPEN.
 */
-int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
+int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){
   int rc;
-  assert( !id->isOpen );
-  SET_THREADID(id);
-  id->dirfd = -1;
-  id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
-  if( id->h<0 ){
+  unixFile f;
+
+  CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0);
+  assert( 0==*pId );
+  f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+  if( f.h<0 ){
     return SQLITE_CANTOPEN;
   }
   sqlite3OsEnterMutex();
-  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
+  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
   sqlite3OsLeaveMutex();
   if( rc ){
-    close(id->h);
+    close(f.h);
     return SQLITE_NOMEM;
   }
-  id->locktype = 0;
-  id->isOpen = 1;
-  TRACE3("OPEN-RO %-3d %s\n", id->h, zFilename);
-  OpenCounter(+1);
-  return SQLITE_OK;
+  TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename);
+  return allocateUnixFile(&f, pId);
 }
 
 /*
@@ -631,29 +813,30 @@
 ** This routine is only meaningful for Unix.  It is a no-op under
 ** windows since windows does not support hard links.
 **
-** On success, a handle for a previously open file is at *id is
+** On success, a handle for a previously open file at *id is
 ** updated with the new directory file descriptor and SQLITE_OK is
 ** returned.
 **
 ** On failure, the function returns SQLITE_CANTOPEN and leaves
 ** *id unchanged.
 */
-int sqlite3OsOpenDirectory(
-  const char *zDirname,
-  OsFile *id
+static int unixOpenDirectory(
+  OsFile *id,
+  const char *zDirname
 ){
-  if( !id->isOpen ){
+  unixFile *pFile = (unixFile*)id;
+  if( pFile==0 ){
     /* Do not open the directory if the corresponding file is not already
     ** open. */
     return SQLITE_CANTOPEN;
   }
-  SET_THREADID(id);
-  assert( id->dirfd<0 );
-  id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0);
-  if( id->dirfd<0 ){
+  SET_THREADID(pFile);
+  assert( pFile->dirfd<0 );
+  pFile->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0);
+  if( pFile->dirfd<0 ){
     return SQLITE_CANTOPEN; 
   }
-  TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
+  TRACE3("OPENDIR %-3d %s\n", pFile->dirfd, zDirname);
   return SQLITE_OK;
 }
 
@@ -661,6 +844,8 @@
 ** If the following global variable points to a string which is the
 ** name of a directory, then that directory will be used to store
 ** temporary files.
+**
+** See also the "PRAGMA temp_store_directory" SQL command.
 */
 char *sqlite3_temp_directory = 0;
 
@@ -668,7 +853,7 @@
 ** Create a temporary file name in zBuf.  zBuf must be big enough to
 ** hold at least SQLITE_TEMPNAME_SIZE characters.
 */
-int sqlite3OsTempFileName(char *zBuf){
+int sqlite3UnixTempFileName(char *zBuf){
   static const char *azDirs[] = {
      0,
      "/var/tmp",
@@ -704,35 +889,54 @@
   return SQLITE_OK; 
 }
 
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
 /*
 ** Check that a given pathname is a directory and is writable 
 **
 */
-int sqlite3OsIsDirWritable(char *zBuf){
+int sqlite3UnixIsDirWritable(char *zBuf){
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
   struct stat buf;
   if( zBuf==0 ) return 0;
   if( zBuf[0]==0 ) return 0;
   if( stat(zBuf, &buf) ) return 0;
   if( !S_ISDIR(buf.st_mode) ) return 0;
   if( access(zBuf, 07) ) return 0;
+#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
   return 1;
 }
-#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
 
 /*
+** Seek to the offset in id->offset then read cnt bytes into pBuf.
+** Return the number of bytes actually read.  Update the offset.
+*/
+static int seekAndRead(unixFile *id, void *pBuf, int cnt){
+  int got;
+#ifdef USE_PREAD
+  got = pread(id->h, pBuf, cnt, id->offset);
+#else
+  lseek(id->h, id->offset, SEEK_SET);
+  got = read(id->h, pBuf, cnt);
+#endif
+  if( got>0 ){
+    id->offset += got;
+  }
+  return got;
+}
+
+/*
 ** Read data from a file into a buffer.  Return SQLITE_OK if all
 ** bytes were read successfully and SQLITE_IOERR if anything goes
 ** wrong.
 */
-int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
+static int unixRead(OsFile *id, void *pBuf, int amt){
   int got;
-  assert( id->isOpen );
+  assert( id );
   SimulateIOError(SQLITE_IOERR);
   TIMER_START;
-  got = read(id->h, pBuf, amt);
+  got = seekAndRead((unixFile*)id, pBuf, amt);
   TIMER_END;
-  TRACE5("READ    %-3d %5d %7d %d\n", id->h, got, last_page, TIMER_ELAPSED);
+  TRACE5("READ    %-3d %5d %7d %d\n", ((unixFile*)id)->h, got,
+          last_page, TIMER_ELAPSED);
   SEEK(0);
   /* if( got<0 ) got = 0; */
   if( got==amt ){
@@ -743,22 +947,42 @@
 }
 
 /*
+** Seek to the offset in id->offset then read cnt bytes into pBuf.
+** Return the number of bytes actually read.  Update the offset.
+*/
+static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){
+  int got;
+#ifdef USE_PREAD
+  got = pwrite(id->h, pBuf, cnt, id->offset);
+#else
+  lseek(id->h, id->offset, SEEK_SET);
+  got = write(id->h, pBuf, cnt);
+#endif
+  if( got>0 ){
+    id->offset += got;
+  }
+  return got;
+}
+
+
+/*
 ** Write data from a buffer into a file.  Return SQLITE_OK on success
 ** or some other error code on failure.
 */
-int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
+static int unixWrite(OsFile *id, const void *pBuf, int amt){
   int wrote = 0;
-  assert( id->isOpen );
+  assert( id );
   assert( amt>0 );
   SimulateIOError(SQLITE_IOERR);
   SimulateDiskfullError;
   TIMER_START;
-  while( amt>0 && (wrote = write(id->h, pBuf, amt))>0 ){
+  while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){
     amt -= wrote;
     pBuf = &((char*)pBuf)[wrote];
   }
   TIMER_END;
-  TRACE5("WRITE   %-3d %5d %7d %d\n", id->h, wrote, last_page, TIMER_ELAPSED);
+  TRACE5("WRITE   %-3d %5d %7d %d\n", ((unixFile*)id)->h, wrote,
+          last_page, TIMER_ELAPSED);
   SEEK(0);
   if( amt>0 ){
     return SQLITE_FULL;
@@ -769,13 +993,13 @@
 /*
 ** Move the read/write pointer in a file.
 */
-int sqlite3OsSeek(OsFile *id, i64 offset){
-  assert( id->isOpen );
+static int unixSeek(OsFile *id, i64 offset){
+  assert( id );
   SEEK(offset/1024 + 1);
 #ifdef SQLITE_TEST
   if( offset ) SimulateDiskfullError
 #endif
-  lseek(id->h, offset, SEEK_SET);
+  ((unixFile*)id)->offset = offset;
   return SQLITE_OK;
 }
 
@@ -788,8 +1012,27 @@
 int sqlite3_fullsync_count = 0;
 #endif
 
+/*
+** Use the fdatasync() API only if the HAVE_FDATASYNC macro is defined.
+** Otherwise use fsync() in its place.
+*/
+#ifndef HAVE_FDATASYNC
+# define fdatasync fsync
+#endif
 
 /*
+** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
+** the F_FULLFSYNC macro is defined.  F_FULLFSYNC is currently
+** only available on Mac OS X.  But that could change.
+*/
+#ifdef F_FULLFSYNC
+# define HAVE_FULLFSYNC 1
+#else
+# define HAVE_FULLFSYNC 0
+#endif
+
+
+/*
 ** The fsync() system call does not work as advertised on many
 ** unix systems.  The following procedure is an attempt to make
 ** it work better.
@@ -819,7 +1062,7 @@
   rc = SQLITE_OK;
 #else
 
-#ifdef F_FULLFSYNC
+#if HAVE_FULLFSYNC
   if( fullSync ){
     rc = fcntl(fd, F_FULLFSYNC, 0);
   }else{
@@ -829,12 +1072,9 @@
   if( rc ) rc = fsync(fd);
 
 #else /* if !defined(F_FULLSYNC) */
-#if  defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO>0
   if( dataOnly ){
     rc = fdatasync(fd);
-  }else
-#endif /* _POSIX_SYNCHRONIZED_IO > 0 */
-  {
+  }else{
     rc = fsync(fd);
   }
 #endif /* defined(F_FULLFSYNC) */
@@ -858,18 +1098,34 @@
 ** the directory entry for the journal was never created) and the transaction
 ** will not roll back - possibly leading to database corruption.
 */
-int sqlite3OsSync(OsFile *id, int dataOnly){
-  assert( id->isOpen );
+static int unixSync(OsFile *id, int dataOnly){
+  unixFile *pFile = (unixFile*)id;
+  assert( pFile );
   SimulateIOError(SQLITE_IOERR);
-  TRACE2("SYNC    %-3d\n", id->h);
-  if( full_fsync(id->h, id->fullSync, dataOnly) ){
+  TRACE2("SYNC    %-3d\n", pFile->h);
+  if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){
     return SQLITE_IOERR;
   }
-  if( id->dirfd>=0 ){
-    TRACE2("DIRSYNC %-3d\n", id->dirfd);
-    full_fsync(id->dirfd, id->fullSync, 0);
-    close(id->dirfd);  /* Only need to sync once, so close the directory */
-    id->dirfd = -1;    /* when we are done. */
+  if( pFile->dirfd>=0 ){
+    TRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
+            HAVE_FULLFSYNC, pFile->fullSync);
+#ifndef SQLITE_DISABLE_DIRSYNC
+    /* The directory sync is only attempted if full_fsync is
+    ** turned off or unavailable.  If a full_fsync occurred above,
+    ** then the directory sync is superfluous.
+    */
+    if( (!HAVE_FULLFSYNC || !pFile->fullSync) && full_fsync(pFile->dirfd,0,0) ){
+       /*
+       ** We have received multiple reports of fsync() returning
+       ** errors when applied to directories on certain file systems.
+       ** A failed directory sync is not a big deal.  So it seems
+       ** better to ignore the error.  Ticket #1657
+       */
+       /* return SQLITE_IOERR; */
+    }
+#endif
+    close(pFile->dirfd);  /* Only need to sync once, so close the directory */
+    pFile->dirfd = -1;    /* when we are done. */
   }
   return SQLITE_OK;
 }
@@ -882,7 +1138,10 @@
 ** before making changes to individual journals on a multi-database commit.
 ** The F_FULLFSYNC option is not needed here.
 */
-int sqlite3OsSyncDirectory(const char *zDirname){
+int sqlite3UnixSyncDirectory(const char *zDirname){
+#ifdef SQLITE_DISABLE_DIRSYNC
+  return SQLITE_OK;
+#else
   int fd;
   int r;
   SimulateIOError(SQLITE_IOERR);
@@ -894,25 +1153,26 @@
   r = fsync(fd);
   close(fd);
   return ((r==0)?SQLITE_OK:SQLITE_IOERR);
+#endif
 }
 
 /*
 ** Truncate an open file to a specified size
 */
-int sqlite3OsTruncate(OsFile *id, i64 nByte){
-  assert( id->isOpen );
+static int unixTruncate(OsFile *id, i64 nByte){
+  assert( id );
   SimulateIOError(SQLITE_IOERR);
-  return ftruncate(id->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
+  return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
 }
 
 /*
 ** Determine the current size of a file in bytes
 */
-int sqlite3OsFileSize(OsFile *id, i64 *pSize){
+static int unixFileSize(OsFile *id, i64 *pSize){
   struct stat buf;
-  assert( id->isOpen );
+  assert( id );
   SimulateIOError(SQLITE_IOERR);
-  if( fstat(id->h, &buf)!=0 ){
+  if( fstat(((unixFile*)id)->h, &buf)!=0 ){
     return SQLITE_IOERR;
   }
   *pSize = buf.st_size;
@@ -925,15 +1185,15 @@
 ** non-zero.  If the file is unlocked or holds only SHARED locks, then
 ** return zero.
 */
-int sqlite3OsCheckReservedLock(OsFile *id){
+static int unixCheckReservedLock(OsFile *id){
   int r = 0;
+  unixFile *pFile = (unixFile*)id;
 
-  assert( id->isOpen );
-  if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
-  sqlite3OsEnterMutex(); /* Needed because id->pLock is shared across threads */
+  assert( pFile );
+  sqlite3OsEnterMutex(); /* Because pFile->pLock is shared across threads */
 
   /* Check if a thread in this process holds such a lock */
-  if( id->pLock->locktype>SHARED_LOCK ){
+  if( pFile->pLock->locktype>SHARED_LOCK ){
     r = 1;
   }
 
@@ -945,37 +1205,19 @@
     lock.l_start = RESERVED_BYTE;
     lock.l_len = 1;
     lock.l_type = F_WRLCK;
-    fcntl(id->h, F_GETLK, &lock);
+    fcntl(pFile->h, F_GETLK, &lock);
     if( lock.l_type!=F_UNLCK ){
       r = 1;
     }
   }
   
   sqlite3OsLeaveMutex();
-  TRACE3("TEST WR-LOCK %d %d\n", id->h, r);
+  TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
 
   return r;
 }
 
-#ifdef SQLITE_DEBUG
 /*
-** Helper function for printing out trace information from debugging
-** binaries. This returns the string represetation of the supplied
-** integer lock-type.
-*/
-static const char * locktypeName(int locktype){
-  switch( locktype ){
-  case NO_LOCK: return "NONE";
-  case SHARED_LOCK: return "SHARED";
-  case RESERVED_LOCK: return "RESERVED";
-  case PENDING_LOCK: return "PENDING";
-  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
-  }
-  return "ERROR";
-}
-#endif
-
-/*
 ** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
@@ -999,7 +1241,7 @@
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 */
-int sqlite3OsLock(OsFile *id, int locktype){
+static int unixLock(OsFile *id, int locktype){
   /* The following describes the implementation of the various locks and
   ** lock transitions in terms of the POSIX advisory shared and exclusive
   ** lock primitives (called read-locks and write-locks below, to avoid
@@ -1039,39 +1281,49 @@
   ** even if the locking primitive used is always a write-lock.
   */
   int rc = SQLITE_OK;
-  struct lockInfo *pLock = id->pLock;
+  unixFile *pFile = (unixFile*)id;
+  struct lockInfo *pLock = pFile->pLock;
   struct flock lock;
   int s;
 
-  assert( id->isOpen );
-  TRACE7("LOCK    %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), 
-      locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt
-      ,getpid() );
-  if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
+  assert( pFile );
+  TRACE7("LOCK    %d %s was %s(%s,%d) pid=%d\n", pFile->h,
+      locktypeName(locktype), locktypeName(pFile->locktype),
+      locktypeName(pLock->locktype), pLock->cnt , getpid());
 
   /* If there is already a lock of this type or more restrictive on the
   ** OsFile, do nothing. Don't use the end_lock: exit path, as
   ** sqlite3OsEnterMutex() hasn't been called yet.
   */
-  if( id->locktype>=locktype ){
-    TRACE3("LOCK    %d %s ok (already held)\n", id->h, locktypeName(locktype));
+  if( pFile->locktype>=locktype ){
+    TRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
+            locktypeName(locktype));
     return SQLITE_OK;
   }
 
   /* Make sure the locking sequence is correct
   */
-  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
   assert( locktype!=PENDING_LOCK );
-  assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
+  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
 
-  /* This mutex is needed because id->pLock is shared across threads
+  /* This mutex is needed because pFile->pLock is shared across threads
   */
   sqlite3OsEnterMutex();
 
+  /* Make sure the current thread owns the pFile.
+  */
+  rc = transferOwnership(pFile);
+  if( rc!=SQLITE_OK ){
+    sqlite3OsLeaveMutex();
+    return rc;
+  }
+  pLock = pFile->pLock;
+
   /* If some thread using this PID has a lock via a different OsFile*
   ** handle that precludes the requested lock, return BUSY.
   */
-  if( (id->locktype!=pLock->locktype && 
+  if( (pFile->locktype!=pLock->locktype && 
           (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
   ){
     rc = SQLITE_BUSY;
@@ -1085,11 +1337,11 @@
   if( locktype==SHARED_LOCK && 
       (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
     assert( locktype==SHARED_LOCK );
-    assert( id->locktype==0 );
+    assert( pFile->locktype==0 );
     assert( pLock->cnt>0 );
-    id->locktype = SHARED_LOCK;
+    pFile->locktype = SHARED_LOCK;
     pLock->cnt++;
-    id->pOpen->nLock++;
+    pFile->pOpen->nLock++;
     goto end_lock;
   }
 
@@ -1102,11 +1354,11 @@
   ** be released.
   */
   if( locktype==SHARED_LOCK 
-      || (locktype==EXCLUSIVE_LOCK && id->locktype<PENDING_LOCK)
+      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
   ){
     lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
     lock.l_start = PENDING_BYTE;
-    s = fcntl(id->h, F_SETLK, &lock);
+    s = fcntl(pFile->h, F_SETLK, &lock);
     if( s ){
       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
       goto end_lock;
@@ -1124,21 +1376,21 @@
     /* Now get the read-lock */
     lock.l_start = SHARED_FIRST;
     lock.l_len = SHARED_SIZE;
-    s = fcntl(id->h, F_SETLK, &lock);
+    s = fcntl(pFile->h, F_SETLK, &lock);
 
     /* Drop the temporary PENDING lock */
     lock.l_start = PENDING_BYTE;
     lock.l_len = 1L;
     lock.l_type = F_UNLCK;
-    if( fcntl(id->h, F_SETLK, &lock)!=0 ){
+    if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
       rc = SQLITE_IOERR;  /* This should never happen */
       goto end_lock;
     }
     if( s ){
       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
     }else{
-      id->locktype = SHARED_LOCK;
-      id->pOpen->nLock++;
+      pFile->locktype = SHARED_LOCK;
+      pFile->pOpen->nLock++;
       pLock->cnt = 1;
     }
   }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
@@ -1150,7 +1402,7 @@
     ** assumed that there is a SHARED or greater lock on the file
     ** already.
     */
-    assert( 0!=id->locktype );
+    assert( 0!=pFile->locktype );
     lock.l_type = F_WRLCK;
     switch( locktype ){
       case RESERVED_LOCK:
@@ -1163,63 +1415,62 @@
       default:
         assert(0);
     }
-    s = fcntl(id->h, F_SETLK, &lock);
+    s = fcntl(pFile->h, F_SETLK, &lock);
     if( s ){
       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
     }
   }
   
   if( rc==SQLITE_OK ){
-    id->locktype = locktype;
+    pFile->locktype = locktype;
     pLock->locktype = locktype;
   }else if( locktype==EXCLUSIVE_LOCK ){
-    id->locktype = PENDING_LOCK;
+    pFile->locktype = PENDING_LOCK;
     pLock->locktype = PENDING_LOCK;
   }
 
 end_lock:
   sqlite3OsLeaveMutex();
-  TRACE4("LOCK    %d %s %s\n", id->h, locktypeName(locktype), 
+  TRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
       rc==SQLITE_OK ? "ok" : "failed");
   return rc;
 }
 
 /*
-** Lower the locking level on file descriptor id to locktype.  locktype
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
-**
-** It is not possible for this routine to fail if the second argument
-** is NO_LOCK.  If the second argument is SHARED_LOCK, this routine
-** might return SQLITE_IOERR instead of SQLITE_OK.
 */
-int sqlite3OsUnlock(OsFile *id, int locktype){
+static int unixUnlock(OsFile *id, int locktype){
   struct lockInfo *pLock;
   struct flock lock;
   int rc = SQLITE_OK;
+  unixFile *pFile = (unixFile*)id;
 
-  assert( id->isOpen );
-  TRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, 
-      id->pLock->locktype, id->pLock->cnt, getpid());
-  if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
+  assert( pFile );
+  TRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
+      pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid());
 
   assert( locktype<=SHARED_LOCK );
-  if( id->locktype<=locktype ){
+  if( pFile->locktype<=locktype ){
     return SQLITE_OK;
   }
+  if( CHECK_THREADID(pFile) ){
+    return SQLITE_MISUSE;
+  }
   sqlite3OsEnterMutex();
-  pLock = id->pLock;
+  pLock = pFile->pLock;
   assert( pLock->cnt!=0 );
-  if( id->locktype>SHARED_LOCK ){
-    assert( pLock->locktype==id->locktype );
+  if( pFile->locktype>SHARED_LOCK ){
+    assert( pLock->locktype==pFile->locktype );
     if( locktype==SHARED_LOCK ){
       lock.l_type = F_RDLCK;
       lock.l_whence = SEEK_SET;
       lock.l_start = SHARED_FIRST;
       lock.l_len = SHARED_SIZE;
-      if( fcntl(id->h, F_SETLK, &lock)!=0 ){
+      if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
         /* This should never happen */
         rc = SQLITE_IOERR;
       }
@@ -1228,7 +1479,7 @@
     lock.l_whence = SEEK_SET;
     lock.l_start = PENDING_BYTE;
     lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
-    if( fcntl(id->h, F_SETLK, &lock)==0 ){
+    if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
       pLock->locktype = SHARED_LOCK;
     }else{
       rc = SQLITE_IOERR;  /* This should never happen */
@@ -1246,7 +1497,7 @@
       lock.l_type = F_UNLCK;
       lock.l_whence = SEEK_SET;
       lock.l_start = lock.l_len = 0L;
-      if( fcntl(id->h, F_SETLK, &lock)==0 ){
+      if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
         pLock->locktype = NO_LOCK;
       }else{
         rc = SQLITE_IOERR;  /* This should never happen */
@@ -1257,7 +1508,7 @@
     ** count reaches zero, close any other file descriptors whose close
     ** was deferred because of outstanding locks.
     */
-    pOpen = id->pOpen;
+    pOpen = pFile->pOpen;
     pOpen->nLock--;
     assert( pOpen->nLock>=0 );
     if( pOpen->nLock==0 && pOpen->nPending>0 ){
@@ -1265,26 +1516,28 @@
       for(i=0; i<pOpen->nPending; i++){
         close(pOpen->aPending[i]);
       }
-      sqliteFree(pOpen->aPending);
+      free(pOpen->aPending);
       pOpen->nPending = 0;
       pOpen->aPending = 0;
     }
   }
   sqlite3OsLeaveMutex();
-  id->locktype = locktype;
+  pFile->locktype = locktype;
   return rc;
 }
 
 /*
 ** Close a file.
 */
-int sqlite3OsClose(OsFile *id){
-  if( !id->isOpen ) return SQLITE_OK;
-  if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
-  sqlite3OsUnlock(id, NO_LOCK);
+static int unixClose(OsFile **pId){
+  unixFile *id = (unixFile*)*pId;
+
+  if( !id ) return SQLITE_OK;
+  unixUnlock(*pId, NO_LOCK);
   if( id->dirfd>=0 ) close(id->dirfd);
   id->dirfd = -1;
   sqlite3OsEnterMutex();
+
   if( id->pOpen->nLock ){
     /* If there are outstanding locks, do not actually close the file just
     ** yet because that would clear those locks.  Instead, add the file
@@ -1293,7 +1546,7 @@
     */
     int *aNew;
     struct openCnt *pOpen = id->pOpen;
-    aNew = sqliteRealloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
+    aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
     if( aNew==0 ){
       /* If a malloc fails, just leak the file descriptor */
     }else{
@@ -1307,10 +1560,13 @@
   }
   releaseLockInfo(id->pLock);
   releaseOpenCnt(id->pOpen);
+
   sqlite3OsLeaveMutex();
   id->isOpen = 0;
   TRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
+  sqlite3ThreadSafeFree(id);
+  *pId = 0;
   return SQLITE_OK;
 }
 
@@ -1320,7 +1576,7 @@
 ** The calling function is responsible for freeing this space once it
 ** is no longer needed.
 */
-char *sqlite3OsFullPathname(const char *zRelative){
+char *sqlite3UnixFullPathname(const char *zRelative){
   char *zFull = 0;
   if( zRelative[0]=='/' ){
     sqlite3SetString(&zFull, zRelative, (char*)0);
@@ -1334,10 +1590,110 @@
                     (char*)0);
     sqliteFree(zBuf);
   }
+
+#if 0
+  /*
+  ** Remove "/./" path elements and convert "/A/./" path elements
+  ** to just "/".
+  */
+  if( zFull ){
+    int i, j;
+    for(i=j=0; zFull[i]; i++){
+      if( zFull[i]=='/' ){
+        if( zFull[i+1]=='/' ) continue;
+        if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
+          i += 1;
+          continue;
+        }
+        if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
+          while( j>0 && zFull[j-1]!='/' ){ j--; }
+          i += 3;
+          continue;
+        }
+      }
+      zFull[j++] = zFull[i];
+    }
+    zFull[j] = 0;
+  }
+#endif
+
   return zFull;
 }
 
+/*
+** Change the value of the fullsync flag in the given file descriptor.
+*/
+static void unixSetFullSync(OsFile *id, int v){
+  ((unixFile*)id)->fullSync = v;
+}
 
+/*
+** Return the underlying file handle for an OsFile
+*/
+static int unixFileHandle(OsFile *id){
+  return ((unixFile*)id)->h;
+}
+
+/*
+** Return an integer that indices the type of lock currently held
+** by this handle.  (Used for testing and analysis only.)
+*/
+static int unixLockState(OsFile *id){
+  return ((unixFile*)id)->locktype;
+}
+
+/*
+** This vector defines all the methods that can operate on an OsFile
+** for unix.
+*/
+static const IoMethod sqlite3UnixIoMethod = {
+  unixClose,
+  unixOpenDirectory,
+  unixRead,
+  unixWrite,
+  unixSeek,
+  unixTruncate,
+  unixSync,
+  unixSetFullSync,
+  unixFileHandle,
+  unixFileSize,
+  unixLock,
+  unixUnlock,
+  unixLockState,
+  unixCheckReservedLock,
+};
+
+/*
+** Allocate memory for a unixFile.  Initialize the new unixFile
+** to the value given in pInit and return a pointer to the new
+** OsFile.  If we run out of memory, close the file and return NULL.
+*/
+static int allocateUnixFile(unixFile *pInit, OsFile **pId){
+  unixFile *pNew;
+  pInit->dirfd = -1;
+  pInit->fullSync = 0;
+  pInit->locktype = 0;
+  pInit->offset = 0;
+  SET_THREADID(pInit);
+  pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) );
+  if( pNew==0 ){
+    close(pInit->h);
+    sqlite3OsEnterMutex();
+    releaseLockInfo(pInit->pLock);
+    releaseOpenCnt(pInit->pOpen);
+    sqlite3OsLeaveMutex();
+    *pId = 0;
+    return SQLITE_NOMEM;
+  }else{
+    *pNew = *pInit;
+    pNew->pMethod = &sqlite3UnixIoMethod;
+    *pId = (OsFile*)pNew;
+    OpenCounter(+1);
+    return SQLITE_OK;
+  }
+}
+
+
 #endif /* SQLITE_OMIT_DISKIO */
 /***************************************************************************
 ** Everything above deals with file I/O.  Everything that follows deals
@@ -1350,7 +1706,7 @@
 ** is written into the buffer zBuf[256].  The calling function must
 ** supply a sufficiently large buffer.
 */
-int sqlite3OsRandomSeed(char *zBuf){
+int sqlite3UnixRandomSeed(char *zBuf){
   /* We have to initialize zBuf to prevent valgrind from reporting
   ** errors.  The reports issued by valgrind are incorrect - we would
   ** prefer that the randomness be increased by making use of the
@@ -1360,7 +1716,7 @@
   ** in the random seed.
   **
   ** When testing, initializing zBuf[] to zero is all we do.  That means
-  ** that we always use the same random number sequence.* This makes the
+  ** that we always use the same random number sequence.  This makes the
   ** tests repeatable.
   */
   memset(zBuf, 0, 256);
@@ -1369,7 +1725,9 @@
     int pid, fd;
     fd = open("/dev/urandom", O_RDONLY);
     if( fd<0 ){
-      time((time_t*)zBuf);
+      time_t t;
+      time(&t);
+      memcpy(zBuf, &t, sizeof(t));
       pid = getpid();
       memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
     }else{
@@ -1383,8 +1741,9 @@
 
 /*
 ** Sleep for a little while.  Return the amount of time slept.
+** The argument is the number of milliseconds we want to sleep.
 */
-int sqlite3OsSleep(int ms){
+int sqlite3UnixSleep(int ms){
 #if defined(HAVE_USLEEP) && HAVE_USLEEP
   usleep(ms*1000);
   return ms;
@@ -1395,11 +1754,42 @@
 }
 
 /*
-** Static variables used for thread synchronization
+** Static variables used for thread synchronization.
+**
+** inMutex      the nesting depth of the recursive mutex.  The thread
+**              holding mutexMain can read this variable at any time.
+**              But is must hold mutexAux to change this variable.  Other
+**              threads must hold mutexAux to read the variable and can
+**              never write.
+**
+** mutexOwner   The thread id of the thread holding mutexMain.  Same
+**              access rules as for inMutex.
+**
+** mutexOwnerValid   True if the value in mutexOwner is valid.  The same
+**                   access rules apply as for inMutex.
+**
+** mutexMain    The main mutex.  Hold this mutex in order to get exclusive
+**              access to SQLite data structures.
+**
+** mutexAux     An auxiliary mutex needed to access variables defined above.
+**
+** Mutexes are always acquired in this order: mutexMain mutexAux.   It
+** is not necessary to acquire mutexMain in order to get mutexAux - just
+** do not attempt to acquire them in the reverse order: mutexAux mutexMain.
+** Either get the mutexes with mutexMain first or get mutexAux only.
+**
+** When running on a platform where the three variables inMutex, mutexOwner,
+** and mutexOwnerValid can be set atomically, the mutexAux is not required.
+** On many systems, all three are 32-bit integers and writing to a 32-bit
+** integer is atomic.  I think.  But there are no guarantees.  So it seems
+** safer to protect them using mutexAux.
 */
 static int inMutex = 0;
 #ifdef SQLITE_UNIX_THREADS
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t mutexOwner;          /* Thread holding mutexMain */
+static int mutexOwnerValid = 0;       /* True if mutexOwner is valid */
+static pthread_mutex_t mutexMain = PTHREAD_MUTEX_INITIALIZER; /* The mutex */
+static pthread_mutex_t mutexAux = PTHREAD_MUTEX_INITIALIZER;  /* Aux mutex */
 #endif
 
 /*
@@ -1409,23 +1799,168 @@
 **
 ** SQLite uses only a single Mutex.  There is not much critical
 ** code and what little there is executes quickly and without blocking.
+**
+** As of version 3.3.2, this mutex must be recursive.
 */
-void sqlite3OsEnterMutex(){
+void sqlite3UnixEnterMutex(){
 #ifdef SQLITE_UNIX_THREADS
-  pthread_mutex_lock(&mutex);
+  pthread_mutex_lock(&mutexAux);
+  if( !mutexOwnerValid || !pthread_equal(mutexOwner, pthread_self()) ){
+    pthread_mutex_unlock(&mutexAux);
+    pthread_mutex_lock(&mutexMain);
+    assert( inMutex==0 );
+    assert( !mutexOwnerValid );
+    pthread_mutex_lock(&mutexAux);
+    mutexOwner = pthread_self();
+    mutexOwnerValid = 1;
+  }
+  inMutex++;
+  pthread_mutex_unlock(&mutexAux);
+#else
+  inMutex++;
 #endif
-  assert( !inMutex );
-  inMutex = 1;
 }
-void sqlite3OsLeaveMutex(){
-  assert( inMutex );
-  inMutex = 0;
+void sqlite3UnixLeaveMutex(){
+  assert( inMutex>0 );
 #ifdef SQLITE_UNIX_THREADS
-  pthread_mutex_unlock(&mutex);
+  pthread_mutex_lock(&mutexAux);
+  inMutex--;
+  assert( pthread_equal(mutexOwner, pthread_self()) );
+  if( inMutex==0 ){
+    assert( mutexOwnerValid );
+    mutexOwnerValid = 0;
+    pthread_mutex_unlock(&mutexMain);
+  }
+  pthread_mutex_unlock(&mutexAux);
+#else
+  inMutex--;
 #endif
 }
 
 /*
+** Return TRUE if the mutex is currently held.
+**
+** If the thisThrd parameter is true, return true only if the
+** calling thread holds the mutex.  If the parameter is false, return
+** true if any thread holds the mutex.
+*/
+int sqlite3UnixInMutex(int thisThrd){
+#ifdef SQLITE_UNIX_THREADS
+  int rc;
+  pthread_mutex_lock(&mutexAux);
+  rc = inMutex>0 && (thisThrd==0 || pthread_equal(mutexOwner,pthread_self()));
+  pthread_mutex_unlock(&mutexAux);
+  return rc;
+#else
+  return inMutex>0;
+#endif
+}
+
+/*
+** Remember the number of thread-specific-data blocks allocated.
+** Use this to verify that we are not leaking thread-specific-data.
+** Ticket #1601
+*/
+#ifdef SQLITE_TEST
+int sqlite3_tsd_count = 0;
+# ifdef SQLITE_UNIX_THREADS
+    static pthread_mutex_t tsd_counter_mutex = PTHREAD_MUTEX_INITIALIZER;
+#   define TSD_COUNTER(N) \
+             pthread_mutex_lock(&tsd_counter_mutex); \
+             sqlite3_tsd_count += N; \
+             pthread_mutex_unlock(&tsd_counter_mutex);
+# else
+#   define TSD_COUNTER(N)  sqlite3_tsd_count += N
+# endif
+#else
+# define TSD_COUNTER(N)  /* no-op */
+#endif
+
+/*
+** If called with allocateFlag>0, then return a pointer to thread
+** specific data for the current thread.  Allocate and zero the
+** thread-specific data if it does not already exist.
+**
+** If called with allocateFlag==0, then check the current thread
+** specific data.  Return it if it exists.  If it does not exist,
+** then return NULL.
+**
+** If called with allocateFlag<0, check to see if the thread specific
+** data is allocated and is all zero.  If it is then deallocate it.
+** Return a pointer to the thread specific data or NULL if it is
+** unallocated or gets deallocated.
+*/
+ThreadData *sqlite3UnixThreadSpecificData(int allocateFlag){
+  static const ThreadData zeroData = {0};  /* Initializer to silence warnings
+                                           ** from broken compilers */
+#ifdef SQLITE_UNIX_THREADS
+  static pthread_key_t key;
+  static int keyInit = 0;
+  ThreadData *pTsd;
+
+  if( !keyInit ){
+    sqlite3OsEnterMutex();
+    if( !keyInit ){
+      int rc;
+      rc = pthread_key_create(&key, 0);
+      if( rc ){
+        sqlite3OsLeaveMutex();
+        return 0;
+      }
+      keyInit = 1;
+    }
+    sqlite3OsLeaveMutex();
+  }
+
+  pTsd = pthread_getspecific(key);
+  if( allocateFlag>0 ){
+    if( pTsd==0 ){
+      if( !sqlite3TestMallocFail() ){
+        pTsd = sqlite3OsMalloc(sizeof(zeroData));
+      }
+#ifdef SQLITE_MEMDEBUG
+      sqlite3_isFail = 0;
+#endif
+      if( pTsd ){
+        *pTsd = zeroData;
+        pthread_setspecific(key, pTsd);
+        TSD_COUNTER(+1);
+      }
+    }
+  }else if( pTsd!=0 && allocateFlag<0 
+            && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
+    sqlite3OsFree(pTsd);
+    pthread_setspecific(key, 0);
+    TSD_COUNTER(-1);
+    pTsd = 0;
+  }
+  return pTsd;
+#else
+  static ThreadData *pTsd = 0;
+  if( allocateFlag>0 ){
+    if( pTsd==0 ){
+      if( !sqlite3TestMallocFail() ){
+        pTsd = sqlite3OsMalloc( sizeof(zeroData) );
+      }
+#ifdef SQLITE_MEMDEBUG
+      sqlite3_isFail = 0;
+#endif
+      if( pTsd ){
+        *pTsd = zeroData;
+        TSD_COUNTER(+1);
+      }
+    }
+  }else if( pTsd!=0 && allocateFlag<0
+            && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
+    sqlite3OsFree(pTsd);
+    TSD_COUNTER(-1);
+    pTsd = 0;
+  }
+  return pTsd;
+#endif
+}
+
+/*
 ** The following variable, if set to a non-zero value, becomes the result
 ** returned from sqlite3OsCurrentTime().  This is used for testing.
 */
@@ -1438,7 +1973,7 @@
 ** current time and date as a Julian Day number into *prNow and
 ** return 0.  Return 1 if the time and date cannot be found.
 */
-int sqlite3OsCurrentTime(double *prNow){
+int sqlite3UnixCurrentTime(double *prNow){
 #ifdef NO_GETTOD
   time_t t;
   time(&t);

Modified: packages/libdbd-sqlite3-perl/trunk/os_win.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/os_win.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/os_win.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -35,6 +35,49 @@
 #include "os_common.h"
 
 /*
+** Determine if we are dealing with WindowsCE - which has a much
+** reduced API.
+*/
+#if defined(_WIN32_WCE)
+# define OS_WINCE 1
+#else
+# define OS_WINCE 0
+#endif
+
+/*
+** WinCE lacks native support for file locking so we have to fake it
+** with some code of our own.
+*/
+#if OS_WINCE
+typedef struct winceLock {
+  int nReaders;       /* Number of reader locks obtained */
+  BOOL bPending;      /* Indicates a pending lock has been obtained */
+  BOOL bReserved;     /* Indicates a reserved lock has been obtained */
+  BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
+} winceLock;
+#endif
+
+/*
+** The winFile structure is a subclass of OsFile specific to the win32
+** portability layer.
+*/
+typedef struct winFile winFile;
+struct winFile {
+  IoMethod const *pMethod;/* Must be first */
+  HANDLE h;               /* Handle for accessing the file */
+  unsigned char locktype; /* Type of lock currently held on this file */
+  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
+#if OS_WINCE
+  WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
+  HANDLE hMutex;          /* Mutex used to control access to shared lock */  
+  HANDLE hShared;         /* Shared memory segment used for locking */
+  winceLock local;        /* Locks obtained by this instance of winFile */
+  winceLock *shared;      /* Global shared lock memory for the file  */
+#endif
+};
+
+
+/*
 ** Do not include any of the File I/O interface procedures if the
 ** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
 ** will be in-memory only)
@@ -56,8 +99,8 @@
 int sqlite3_os_type = 0;
 
 /*
-** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
-** Return false (zero) for Win95, Win98, or WinME.
+** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
+** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
 **
 ** Here is an interesting observation:  Win95, Win98, and WinME lack
 ** the LockFileEx() API.  But we can still statically link against that
@@ -66,34 +109,38 @@
 ** WinNT/2K/XP so that we will know whether or not we can safely call
 ** the LockFileEx() API.
 */
-static int isNT(void){
-  if( sqlite3_os_type==0 ){
-    OSVERSIONINFO sInfo;
-    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-    GetVersionEx(&sInfo);
-    sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
+#if OS_WINCE
+# define isNT()  (1)
+#else
+  static int isNT(void){
+    if( sqlite3_os_type==0 ){
+      OSVERSIONINFO sInfo;
+      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+      GetVersionEx(&sInfo);
+      sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
+    }
+    return sqlite3_os_type==2;
   }
-  return sqlite3_os_type==2;
-}
+#endif /* OS_WINCE */
 
 /*
 ** Convert a UTF-8 string to UTF-32.  Space to hold the returned string
 ** is obtained from sqliteMalloc.
 */
 static WCHAR *utf8ToUnicode(const char *zFilename){
-  int nByte;
+  int nChar;
   WCHAR *zWideFilename;
 
   if( !isNT() ){
     return 0;
   }
-  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);
-  zWideFilename = sqliteMalloc( nByte*sizeof(zWideFilename[0]) );
+  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
+  zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
   if( zWideFilename==0 ){
     return 0;
   }
-  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);
-  if( nByte==0 ){
+  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
+  if( nChar==0 ){
     sqliteFree(zWideFilename);
     zWideFilename = 0;
   }
@@ -122,17 +169,326 @@
   return zFilename;
 }
 
+#if OS_WINCE
+/*************************************************************************
+** This section contains code for WinCE only.
+*/
+/*
+** WindowsCE does not have a localtime() function.  So create a
+** substitute.
+*/
+#include <time.h>
+struct tm *__cdecl localtime(const time_t *t)
+{
+  static struct tm y;
+  FILETIME uTm, lTm;
+  SYSTEMTIME pTm;
+  i64 t64;
+  t64 = *t;
+  t64 = (t64 + 11644473600)*10000000;
+  uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
+  uTm.dwHighDateTime= t64 >> 32;
+  FileTimeToLocalFileTime(&uTm,&lTm);
+  FileTimeToSystemTime(&lTm,&pTm);
+  y.tm_year = pTm.wYear - 1900;
+  y.tm_mon = pTm.wMonth - 1;
+  y.tm_wday = pTm.wDayOfWeek;
+  y.tm_mday = pTm.wDay;
+  y.tm_hour = pTm.wHour;
+  y.tm_min = pTm.wMinute;
+  y.tm_sec = pTm.wSecond;
+  return &y;
+}
 
+/* This will never be called, but defined to make the code compile */
+#define GetTempPathA(a,b)
+
+#define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
+#define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
+#define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)
+
+#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
+
 /*
+** Acquire a lock on the handle h
+*/
+static void winceMutexAcquire(HANDLE h){
+   DWORD dwErr;
+   do {
+     dwErr = WaitForSingleObject(h, INFINITE);
+   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
+}
+/*
+** Release a lock acquired by winceMutexAcquire()
+*/
+#define winceMutexRelease(h) ReleaseMutex(h)
+
+/*
+** Create the mutex and shared memory used for locking in the file
+** descriptor pFile
+*/
+static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
+  WCHAR *zTok;
+  WCHAR *zName = utf8ToUnicode(zFilename);
+  BOOL bInit = TRUE;
+
+  /* Initialize the local lockdata */
+  ZeroMemory(&pFile->local, sizeof(pFile->local));
+
+  /* Replace the backslashes from the filename and lowercase it
+  ** to derive a mutex name. */
+  zTok = CharLowerW(zName);
+  for (;*zTok;zTok++){
+    if (*zTok == '\\') *zTok = '_';
+  }
+
+  /* Create/open the named mutex */
+  pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
+  if (!pFile->hMutex){
+    sqliteFree(zName);
+    return FALSE;
+  }
+
+  /* Acquire the mutex before continuing */
+  winceMutexAcquire(pFile->hMutex);
+  
+  /* Since the names of named mutexes, semaphores, file mappings etc are 
+  ** case-sensitive, take advantage of that by uppercasing the mutex name
+  ** and using that as the shared filemapping name.
+  */
+  CharUpperW(zName);
+  pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
+                                       PAGE_READWRITE, 0, sizeof(winceLock),
+                                       zName);  
+
+  /* Set a flag that indicates we're the first to create the memory so it 
+  ** must be zero-initialized */
+  if (GetLastError() == ERROR_ALREADY_EXISTS){
+    bInit = FALSE;
+  }
+
+  sqliteFree(zName);
+
+  /* If we succeeded in making the shared memory handle, map it. */
+  if (pFile->hShared){
+    pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
+             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
+    /* If mapping failed, close the shared memory handle and erase it */
+    if (!pFile->shared){
+      CloseHandle(pFile->hShared);
+      pFile->hShared = NULL;
+    }
+  }
+
+  /* If shared memory could not be created, then close the mutex and fail */
+  if (pFile->hShared == NULL){
+    winceMutexRelease(pFile->hMutex);
+    CloseHandle(pFile->hMutex);
+    pFile->hMutex = NULL;
+    return FALSE;
+  }
+  
+  /* Initialize the shared memory if we're supposed to */
+  if (bInit) {
+    ZeroMemory(pFile->shared, sizeof(winceLock));
+  }
+
+  winceMutexRelease(pFile->hMutex);
+  return TRUE;
+}
+
+/*
+** Destroy the part of winFile that deals with wince locks
+*/
+static void winceDestroyLock(winFile *pFile){
+  if (pFile->hMutex){
+    /* Acquire the mutex */
+    winceMutexAcquire(pFile->hMutex);
+
+    /* The following blocks should probably assert in debug mode, but they
+       are to cleanup in case any locks remained open */
+    if (pFile->local.nReaders){
+      pFile->shared->nReaders --;
+    }
+    if (pFile->local.bReserved){
+      pFile->shared->bReserved = FALSE;
+    }
+    if (pFile->local.bPending){
+      pFile->shared->bPending = FALSE;
+    }
+    if (pFile->local.bExclusive){
+      pFile->shared->bExclusive = FALSE;
+    }
+
+    /* De-reference and close our copy of the shared memory handle */
+    UnmapViewOfFile(pFile->shared);
+    CloseHandle(pFile->hShared);
+
+    /* Done with the mutex */
+    winceMutexRelease(pFile->hMutex);    
+    CloseHandle(pFile->hMutex);
+    pFile->hMutex = NULL;
+  }
+}
+
+/* 
+** An implementation of the LockFile() API of windows for wince
+*/
+static BOOL winceLockFile(
+  HANDLE *phFile,
+  DWORD dwFileOffsetLow,
+  DWORD dwFileOffsetHigh,
+  DWORD nNumberOfBytesToLockLow,
+  DWORD nNumberOfBytesToLockHigh
+){
+  winFile *pFile = HANDLE_TO_WINFILE(phFile);
+  BOOL bReturn = FALSE;
+
+  if (!pFile->hMutex) return TRUE;
+  winceMutexAcquire(pFile->hMutex);
+
+  /* Wanting an exclusive lock? */
+  if (dwFileOffsetLow == SHARED_FIRST
+       && nNumberOfBytesToLockLow == SHARED_SIZE){
+    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
+       pFile->shared->bExclusive = TRUE;
+       pFile->local.bExclusive = TRUE;
+       bReturn = TRUE;
+    }
+  }
+
+  /* Want a read-only lock? */
+  else if ((dwFileOffsetLow >= SHARED_FIRST &&
+            dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
+            nNumberOfBytesToLockLow == 1){
+    if (pFile->shared->bExclusive == 0){
+      pFile->local.nReaders ++;
+      if (pFile->local.nReaders == 1){
+        pFile->shared->nReaders ++;
+      }
+      bReturn = TRUE;
+    }
+  }
+
+  /* Want a pending lock? */
+  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
+    /* If no pending lock has been acquired, then acquire it */
+    if (pFile->shared->bPending == 0) {
+      pFile->shared->bPending = TRUE;
+      pFile->local.bPending = TRUE;
+      bReturn = TRUE;
+    }
+  }
+  /* Want a reserved lock? */
+  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
+    if (pFile->shared->bReserved == 0) {
+      pFile->shared->bReserved = TRUE;
+      pFile->local.bReserved = TRUE;
+      bReturn = TRUE;
+    }
+  }
+
+  winceMutexRelease(pFile->hMutex);
+  return bReturn;
+}
+
+/*
+** An implementation of the UnlockFile API of windows for wince
+*/
+static BOOL winceUnlockFile(
+  HANDLE *phFile,
+  DWORD dwFileOffsetLow,
+  DWORD dwFileOffsetHigh,
+  DWORD nNumberOfBytesToUnlockLow,
+  DWORD nNumberOfBytesToUnlockHigh
+){
+  winFile *pFile = HANDLE_TO_WINFILE(phFile);
+  BOOL bReturn = FALSE;
+
+  if (!pFile->hMutex) return TRUE;
+  winceMutexAcquire(pFile->hMutex);
+
+  /* Releasing a reader lock or an exclusive lock */
+  if (dwFileOffsetLow >= SHARED_FIRST &&
+       dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
+    /* Did we have an exclusive lock? */
+    if (pFile->local.bExclusive){
+      pFile->local.bExclusive = FALSE;
+      pFile->shared->bExclusive = FALSE;
+      bReturn = TRUE;
+    }
+
+    /* Did we just have a reader lock? */
+    else if (pFile->local.nReaders){
+      pFile->local.nReaders --;
+      if (pFile->local.nReaders == 0)
+      {
+        pFile->shared->nReaders --;
+      }
+      bReturn = TRUE;
+    }
+  }
+
+  /* Releasing a pending lock */
+  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
+    if (pFile->local.bPending){
+      pFile->local.bPending = FALSE;
+      pFile->shared->bPending = FALSE;
+      bReturn = TRUE;
+    }
+  }
+  /* Releasing a reserved lock */
+  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
+    if (pFile->local.bReserved) {
+      pFile->local.bReserved = FALSE;
+      pFile->shared->bReserved = FALSE;
+      bReturn = TRUE;
+    }
+  }
+
+  winceMutexRelease(pFile->hMutex);
+  return bReturn;
+}
+
+/*
+** An implementation of the LockFileEx() API of windows for wince
+*/
+static BOOL winceLockFileEx(
+  HANDLE *phFile,
+  DWORD dwFlags,
+  DWORD dwReserved,
+  DWORD nNumberOfBytesToLockLow,
+  DWORD nNumberOfBytesToLockHigh,
+  LPOVERLAPPED lpOverlapped
+){
+  /* If the caller wants a shared read lock, forward this call
+  ** to winceLockFile */
+  if (lpOverlapped->Offset == SHARED_FIRST &&
+      dwFlags == 1 &&
+      nNumberOfBytesToLockLow == SHARED_SIZE){
+    return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
+  }
+  return FALSE;
+}
+/*
+** End of the special code for wince
+*****************************************************************************/
+#endif /* OS_WINCE */
+
+/*
 ** Delete the named file
 */
-int sqlite3OsDelete(const char *zFilename){
+int sqlite3WinDelete(const char *zFilename){
   WCHAR *zWide = utf8ToUnicode(zFilename);
   if( zWide ){
     DeleteFileW(zWide);
     sqliteFree(zWide);
   }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
     DeleteFileA(zFilename);
+#endif
   }
   TRACE2("DELETE \"%s\"\n", zFilename);
   return SQLITE_OK;
@@ -141,18 +497,25 @@
 /*
 ** Return TRUE if the named file exists.
 */
-int sqlite3OsFileExists(const char *zFilename){
+int sqlite3WinFileExists(const char *zFilename){
   int exists = 0;
   WCHAR *zWide = utf8ToUnicode(zFilename);
   if( zWide ){
     exists = GetFileAttributesW(zWide) != 0xffffffff;
     sqliteFree(zWide);
   }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
     exists = GetFileAttributesA(zFilename) != 0xffffffff;
+#endif
   }
   return exists;
 }
 
+/* Forward declaration */
+static int allocateWinFile(winFile *pInit, OsFile **pId);
+
 /*
 ** Attempt to open a file for both reading and writing.  If that
 ** fails, try opening it read-only.  If the file does not exist,
@@ -166,14 +529,15 @@
 ** On failure, the function returns SQLITE_CANTOPEN and leaves
 ** *id and *pReadonly unchanged.
 */
-int sqlite3OsOpenReadWrite(
+int sqlite3WinOpenReadWrite(
   const char *zFilename,
-  OsFile *id,
+  OsFile **pId,
   int *pReadonly
 ){
+  winFile f;
   HANDLE h;
   WCHAR *zWide = utf8ToUnicode(zFilename);
-  assert( !id->isOpen );
+  assert( *pId==0 );
   if( zWide ){
     h = CreateFileW(zWide,
        GENERIC_READ | GENERIC_WRITE,
@@ -200,8 +564,18 @@
     }else{
       *pReadonly = 0;
     }
+#if OS_WINCE
+    if (!winceCreateLock(zFilename, &f)){
+      CloseHandle(h);
+      sqliteFree(zWide);
+      return SQLITE_CANTOPEN;
+    }
+#endif
     sqliteFree(zWide);
   }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
     h = CreateFileA(zFilename,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -226,14 +600,14 @@
     }else{
       *pReadonly = 0;
     }
+#endif /* OS_WINCE */
   }
-  id->h = h;
-  id->locktype = NO_LOCK;
-  id->sharedLockByte = 0;
-  id->isOpen = 1;
-  OpenCounter(+1);
+  f.h = h;
+#if OS_WINCE
+  f.zDeleteOnClose = 0;
+#endif
   TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
-  return SQLITE_OK;
+  return allocateWinFile(&f, pId);
 }
 
 
@@ -251,17 +625,18 @@
 **
 ** On failure, return SQLITE_CANTOPEN.
 */
-int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
+int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
+  winFile f;
   HANDLE h;
   int fileflags;
   WCHAR *zWide = utf8ToUnicode(zFilename);
-  assert( !id->isOpen );
+  assert( *pId == 0 );
+  fileflags = FILE_FLAG_RANDOM_ACCESS;
+#if !OS_WINCE
   if( delFlag ){
-    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
-                     | FILE_FLAG_DELETE_ON_CLOSE;
-  }else{
-    fileflags = FILE_FLAG_RANDOM_ACCESS;
+    fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
   }
+#endif
   if( zWide ){
     h = CreateFileW(zWide,
        GENERIC_READ | GENERIC_WRITE,
@@ -273,6 +648,9 @@
     );
     sqliteFree(zWide);
   }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
     h = CreateFileA(zFilename,
        GENERIC_READ | GENERIC_WRITE,
        0,
@@ -281,17 +659,18 @@
        fileflags,
        NULL
     );
+#endif /* OS_WINCE */
   }
   if( h==INVALID_HANDLE_VALUE ){
     return SQLITE_CANTOPEN;
   }
-  id->h = h;
-  id->locktype = NO_LOCK;
-  id->sharedLockByte = 0;
-  id->isOpen = 1;
-  OpenCounter(+1);
+  f.h = h;
+#if OS_WINCE
+  f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0;
+  f.hMutex = NULL;
+#endif
   TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
-  return SQLITE_OK;
+  return allocateWinFile(&f, pId);
 }
 
 /*
@@ -301,10 +680,11 @@
 **
 ** On failure, return SQLITE_CANTOPEN.
 */
-int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
+int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
+  winFile f;
   HANDLE h;
   WCHAR *zWide = utf8ToUnicode(zFilename);
-  assert( !id->isOpen );
+  assert( *pId==0 );
   if( zWide ){
     h = CreateFileW(zWide,
        GENERIC_READ,
@@ -316,6 +696,9 @@
     );
     sqliteFree(zWide);
   }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
     h = CreateFileA(zFilename,
        GENERIC_READ,
        0,
@@ -324,17 +707,18 @@
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
        NULL
     );
+#endif
   }
   if( h==INVALID_HANDLE_VALUE ){
     return SQLITE_CANTOPEN;
   }
-  id->h = h;
-  id->locktype = NO_LOCK;
-  id->sharedLockByte = 0;
-  id->isOpen = 1;
-  OpenCounter(+1);
+  f.h = h;
+#if OS_WINCE
+  f.zDeleteOnClose = 0;
+  f.hMutex = NULL;
+#endif
   TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
-  return SQLITE_OK;
+  return allocateWinFile(&f, pId);
 }
 
 /*
@@ -353,9 +737,9 @@
 ** On failure, the function returns SQLITE_CANTOPEN and leaves
 ** *id unchanged.
 */
-int sqlite3OsOpenDirectory(
-  const char *zDirname,
-  OsFile *id
+static int winOpenDirectory(
+  OsFile *id,
+  const char *zDirname
 ){
   return SQLITE_OK;
 }
@@ -371,7 +755,7 @@
 ** Create a temporary file name in zBuf.  zBuf must be big enough to
 ** hold at least SQLITE_TEMPNAME_SIZE characters.
 */
-int sqlite3OsTempFileName(char *zBuf){
+int sqlite3WinTempFileName(char *zBuf){
   static char zChars[] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -413,12 +797,21 @@
 /*
 ** Close a file.
 */
-int sqlite3OsClose(OsFile *id){
-  if( id->isOpen ){
-    TRACE2("CLOSE %d\n", id->h);
-    CloseHandle(id->h);
+static int winClose(OsFile **pId){
+  winFile *pFile;
+  if( pId && (pFile = (winFile*)*pId)!=0 ){
+    TRACE2("CLOSE %d\n", pFile->h);
+    CloseHandle(pFile->h);
+#if OS_WINCE
+    winceDestroyLock(pFile);
+    if( pFile->zDeleteOnClose ){
+      DeleteFileW(pFile->zDeleteOnClose);
+      sqliteFree(pFile->zDeleteOnClose);
+    }
+#endif
     OpenCounter(-1);
-    id->isOpen = 0;
+    sqliteFree(pFile);
+    *pId = 0;
   }
   return SQLITE_OK;
 }
@@ -428,12 +821,12 @@
 ** bytes were read successfully and SQLITE_IOERR if anything goes
 ** wrong.
 */
-int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
+static int winRead(OsFile *id, void *pBuf, int amt){
   DWORD got;
-  assert( id->isOpen );
+  assert( id!=0 );
   SimulateIOError(SQLITE_IOERR);
-  TRACE3("READ %d lock=%d\n", id->h, id->locktype);
-  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
+  TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
+  if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
     got = 0;
   }
   if( got==(DWORD)amt ){
@@ -447,15 +840,16 @@
 ** Write data from a buffer into a file.  Return SQLITE_OK on success
 ** or some other error code on failure.
 */
-int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
+static int winWrite(OsFile *id, const void *pBuf, int amt){
   int rc = 0;
   DWORD wrote;
-  assert( id->isOpen );
+  assert( id!=0 );
   SimulateIOError(SQLITE_IOERR);
   SimulateDiskfullError;
-  TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);
+  TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
   assert( amt>0 );
-  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
+  while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
+         && wrote>0 ){
     amt -= wrote;
     pBuf = &((char*)pBuf)[wrote];
   }
@@ -475,17 +869,17 @@
 /*
 ** Move the read/write pointer in a file.
 */
-int sqlite3OsSeek(OsFile *id, i64 offset){
+static int winSeek(OsFile *id, i64 offset){
   LONG upperBits = offset>>32;
   LONG lowerBits = offset & 0xffffffff;
   DWORD rc;
-  assert( id->isOpen );
+  assert( id!=0 );
 #ifdef SQLITE_TEST
   if( offset ) SimulateDiskfullError
 #endif
   SEEK(offset/1024 + 1);
-  rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
-  TRACE3("SEEK %d %lld\n", id->h, offset);
+  rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
+  TRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
   if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
     return SQLITE_FULL;
   }
@@ -495,10 +889,10 @@
 /*
 ** Make sure all writes to a particular file are committed to disk.
 */
-int sqlite3OsSync(OsFile *id, int dataOnly){
-  assert( id->isOpen );
-  TRACE3("SYNC %d lock=%d\n", id->h, id->locktype);
-  if( FlushFileBuffers(id->h) ){
+static int winSync(OsFile *id, int dataOnly){
+  assert( id!=0 );
+  TRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
+  if( FlushFileBuffers(((winFile*)id)->h) ){
     return SQLITE_OK;
   }else{
     return SQLITE_IOERR;
@@ -509,7 +903,7 @@
 ** Sync the directory zDirname. This is a no-op on operating systems other
 ** than UNIX.
 */
-int sqlite3OsSyncDirectory(const char *zDirname){
+int sqlite3WinSyncDirectory(const char *zDirname){
   SimulateIOError(SQLITE_IOERR);
   return SQLITE_OK;
 }
@@ -517,34 +911,41 @@
 /*
 ** Truncate an open file to a specified size
 */
-int sqlite3OsTruncate(OsFile *id, i64 nByte){
+static int winTruncate(OsFile *id, i64 nByte){
   LONG upperBits = nByte>>32;
-  assert( id->isOpen );
-  TRACE3("TRUNCATE %d %lld\n", id->h, nByte);
+  assert( id!=0 );
+  TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
   SimulateIOError(SQLITE_IOERR);
-  SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
-  SetEndOfFile(id->h);
+  SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
+  SetEndOfFile(((winFile*)id)->h);
   return SQLITE_OK;
 }
 
 /*
 ** Determine the current size of a file in bytes
 */
-int sqlite3OsFileSize(OsFile *id, i64 *pSize){
+static int winFileSize(OsFile *id, i64 *pSize){
   DWORD upperBits, lowerBits;
-  assert( id->isOpen );
+  assert( id!=0 );
   SimulateIOError(SQLITE_IOERR);
-  lowerBits = GetFileSize(id->h, &upperBits);
+  lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
   *pSize = (((i64)upperBits)<<32) + lowerBits;
   return SQLITE_OK;
 }
 
 /*
+** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
+*/
+#ifndef LOCKFILE_FAIL_IMMEDIATELY
+# define LOCKFILE_FAIL_IMMEDIATELY 1
+#endif
+
+/*
 ** Acquire a reader lock.
 ** Different API routines are called depending on whether or not this
 ** is Win95 or WinNT.
 */
-static int getReadLock(OsFile *id){
+static int getReadLock(winFile *id){
   int res;
   if( isNT() ){
     OVERLAPPED ovlp;
@@ -564,12 +965,12 @@
 /*
 ** Undo a readlock
 */
-static int unlockReadLock(OsFile *id){
+static int unlockReadLock(winFile *pFile){
   int res;
   if( isNT() ){
-    res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+    res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
   }else{
-    res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
+    res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
   }
   return res;
 }
@@ -579,7 +980,7 @@
 ** Check that a given pathname is a directory and is writable 
 **
 */
-int sqlite3OsIsDirWritable(char *zDirname){
+int sqlite3WinIsDirWritable(char *zDirname){
   int fileAttr;
   WCHAR *zWide;
   if( zDirname==0 ) return 0;
@@ -589,7 +990,11 @@
     fileAttr = GetFileAttributesW(zWide);
     sqliteFree(zWide);
   }else{
+#if OS_WINCE
+    return 0;
+#else
     fileAttr = GetFileAttributesA(zDirname);
+#endif
   }
   if( fileAttr == 0xffffffff ) return 0;
   if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
@@ -620,45 +1025,46 @@
 **    RESERVED -> (PENDING) -> EXCLUSIVE
 **    PENDING -> EXCLUSIVE
 **
-** This routine will only increase a lock.  The sqlite3OsUnlock() routine
+** This routine will only increase a lock.  The winUnlock() routine
 ** erases all locks at once and returns us immediately to locking level 0.
 ** It is not possible to lower the locking level one step at a time.  You
 ** must go straight to locking level 0.
 */
-int sqlite3OsLock(OsFile *id, int locktype){
+static int winLock(OsFile *id, int locktype){
   int rc = SQLITE_OK;    /* Return code from subroutines */
   int res = 1;           /* Result of a windows lock call */
   int newLocktype;       /* Set id->locktype to this value before exiting */
   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
+  winFile *pFile = (winFile*)id;
 
-  assert( id->isOpen );
+  assert( pFile!=0 );
   TRACE5("LOCK %d %d was %d(%d)\n",
-          id->h, locktype, id->locktype, id->sharedLockByte);
+          pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
 
   /* If there is already a lock of this type or more restrictive on the
   ** OsFile, do nothing. Don't use the end_lock: exit path, as
   ** sqlite3OsEnterMutex() hasn't been called yet.
   */
-  if( id->locktype>=locktype ){
+  if( pFile->locktype>=locktype ){
     return SQLITE_OK;
   }
 
   /* Make sure the locking sequence is correct
   */
-  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
   assert( locktype!=PENDING_LOCK );
-  assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
+  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
 
   /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
   ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
   ** the PENDING_LOCK byte is temporary.
   */
-  newLocktype = id->locktype;
-  if( id->locktype==NO_LOCK
-   || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK)
+  newLocktype = pFile->locktype;
+  if( pFile->locktype==NO_LOCK
+   || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
   ){
     int cnt = 3;
-    while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){
+    while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
       /* Try 3 times to get the pending lock.  The pending lock might be
       ** held by another reader process who will release it momentarily.
       */
@@ -671,8 +1077,8 @@
   /* Acquire a shared lock
   */
   if( locktype==SHARED_LOCK && res ){
-    assert( id->locktype==NO_LOCK );
-    res = getReadLock(id);
+    assert( pFile->locktype==NO_LOCK );
+    res = getReadLock(pFile);
     if( res ){
       newLocktype = SHARED_LOCK;
     }
@@ -681,8 +1087,8 @@
   /* Acquire a RESERVED lock
   */
   if( locktype==RESERVED_LOCK && res ){
-    assert( id->locktype==SHARED_LOCK );
-    res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+    assert( pFile->locktype==SHARED_LOCK );
+    res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
     if( res ){
       newLocktype = RESERVED_LOCK;
     }
@@ -698,10 +1104,10 @@
   /* Acquire an EXCLUSIVE lock
   */
   if( locktype==EXCLUSIVE_LOCK && res ){
-    assert( id->locktype>=SHARED_LOCK );
-    res = unlockReadLock(id);
+    assert( pFile->locktype>=SHARED_LOCK );
+    res = unlockReadLock(pFile);
     TRACE2("unreadlock = %d\n", res);
-    res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+    res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
     if( res ){
       newLocktype = EXCLUSIVE_LOCK;
     }else{
@@ -713,7 +1119,7 @@
   ** release it now.
   */
   if( gotPendingLock && locktype==SHARED_LOCK ){
-    UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
+    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
   }
 
   /* Update the state of the lock has held in the file descriptor then
@@ -722,11 +1128,11 @@
   if( res ){
     rc = SQLITE_OK;
   }else{
-    TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h,
+    TRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
            locktype, newLocktype);
     rc = SQLITE_BUSY;
   }
-  id->locktype = newLocktype;
+  pFile->locktype = newLocktype;
   return rc;
 }
 
@@ -735,19 +1141,20 @@
 ** file by this or any other process. If such a lock is held, return
 ** non-zero, otherwise zero.
 */
-int sqlite3OsCheckReservedLock(OsFile *id){
+static int winCheckReservedLock(OsFile *id){
   int rc;
-  assert( id->isOpen );
-  if( id->locktype>=RESERVED_LOCK ){
+  winFile *pFile = (winFile*)id;
+  assert( pFile!=0 );
+  if( pFile->locktype>=RESERVED_LOCK ){
     rc = 1;
-    TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc);
+    TRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
   }else{
-    rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+    rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
     if( rc ){
-      UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+      UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
     }
     rc = !rc;
-    TRACE3("TEST WR-LOCK %d %d (remote)\n", id->h, rc);
+    TRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
   }
   return rc;
 }
@@ -763,32 +1170,33 @@
 ** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
 ** might return SQLITE_IOERR;
 */
-int sqlite3OsUnlock(OsFile *id, int locktype){
+static int winUnlock(OsFile *id, int locktype){
   int type;
   int rc = SQLITE_OK;
-  assert( id->isOpen );
+  winFile *pFile = (winFile*)id;
+  assert( pFile!=0 );
   assert( locktype<=SHARED_LOCK );
-  TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype,
-          id->locktype, id->sharedLockByte);
-  type = id->locktype;
+  TRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
+          pFile->locktype, pFile->sharedLockByte);
+  type = pFile->locktype;
   if( type>=EXCLUSIVE_LOCK ){
-    UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
-    if( locktype==SHARED_LOCK && !getReadLock(id) ){
+    UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+    if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
       /* This should never happen.  We should always be able to
       ** reacquire the read lock */
       rc = SQLITE_IOERR;
     }
   }
   if( type>=RESERVED_LOCK ){
-    UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+    UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
   }
   if( locktype==NO_LOCK && type>=SHARED_LOCK ){
-    unlockReadLock(id);
+    unlockReadLock(pFile);
   }
   if( type>=PENDING_LOCK ){
-    UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
+    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
   }
-  id->locktype = locktype;
+  pFile->locktype = locktype;
   return rc;
 }
 
@@ -798,17 +1206,21 @@
 ** The calling function is responsible for freeing this space once it
 ** is no longer needed.
 */
-char *sqlite3OsFullPathname(const char *zRelative){
-  char *zNotUsed;
+char *sqlite3WinFullPathname(const char *zRelative){
   char *zFull;
-  WCHAR *zWide;
+#if defined(__CYGWIN__)
   int nByte;
-#ifdef __CYGWIN__
   nByte = strlen(zRelative) + MAX_PATH + 1001;
   zFull = sqliteMalloc( nByte );
   if( zFull==0 ) return 0;
   if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
+#elif OS_WINCE
+  /* WinCE has no concept of a relative pathname, or so I am told. */
+  zFull = sqliteStrDup(zRelative);
 #else
+  char *zNotUsed;
+  WCHAR *zWide;
+  int nByte;
   zWide = utf8ToUnicode(zRelative);
   if( zWide ){
     WCHAR *zTemp, *zNotUsedW;
@@ -829,6 +1241,76 @@
   return zFull;
 }
 
+/*
+** The fullSync option is meaningless on windows.   This is a no-op.
+*/
+static void winSetFullSync(OsFile *id, int v){
+  return;
+}
+
+/*
+** Return the underlying file handle for an OsFile
+*/
+static int winFileHandle(OsFile *id){
+  return (int)((winFile*)id)->h;
+}
+
+/*
+** Return an integer that indices the type of lock currently held
+** by this handle.  (Used for testing and analysis only.)
+*/
+static int winLockState(OsFile *id){
+  return ((winFile*)id)->locktype;
+}
+
+/*
+** This vector defines all the methods that can operate on an OsFile
+** for win32.
+*/
+static const IoMethod sqlite3WinIoMethod = {
+  winClose,
+  winOpenDirectory,
+  winRead,
+  winWrite,
+  winSeek,
+  winTruncate,
+  winSync,
+  winSetFullSync,
+  winFileHandle,
+  winFileSize,
+  winLock,
+  winUnlock,
+  winLockState,
+  winCheckReservedLock,
+};
+
+/*
+** Allocate memory for an OsFile.  Initialize the new OsFile
+** to the value given in pInit and return a pointer to the new
+** OsFile.  If we run out of memory, close the file and return NULL.
+*/
+static int allocateWinFile(winFile *pInit, OsFile **pId){
+  winFile *pNew;
+  pNew = sqliteMalloc( sizeof(*pNew) );
+  if( pNew==0 ){
+    CloseHandle(pInit->h);
+#if OS_WINCE
+    sqliteFree(pInit->zDeleteOnClose);
+#endif
+    *pId = 0;
+    return SQLITE_NOMEM;
+  }else{
+    *pNew = *pInit;
+    pNew->pMethod = &sqlite3WinIoMethod;
+    pNew->locktype = NO_LOCK;
+    pNew->sharedLockByte = 0;
+    *pId = (OsFile*)pNew;
+    OpenCounter(+1);
+    return SQLITE_OK;
+  }
+}
+
+
 #endif /* SQLITE_OMIT_DISKIO */
 /***************************************************************************
 ** Everything above deals with file I/O.  Everything that follows deals
@@ -840,7 +1322,7 @@
 ** is written into the buffer zBuf[256].  The calling function must
 ** supply a sufficiently large buffer.
 */
-int sqlite3OsRandomSeed(char *zBuf){
+int sqlite3WinRandomSeed(char *zBuf){
   /* We have to initialize zBuf to prevent valgrind from reporting
   ** errors.  The reports issued by valgrind are incorrect - we would
   ** prefer that the randomness be increased by making use of the
@@ -861,7 +1343,7 @@
 /*
 ** Sleep for a little while.  Return the amount of time slept.
 */
-int sqlite3OsSleep(int ms){
+int sqlite3WinSleep(int ms){
   Sleep(ms);
   return ms;
 }
@@ -871,18 +1353,22 @@
 */
 static int inMutex = 0;
 #ifdef SQLITE_W32_THREADS
+  static DWORD mutexOwner;
   static CRITICAL_SECTION cs;
 #endif
 
 /*
-** The following pair of routine implement mutual exclusion for
+** The following pair of routines implement mutual exclusion for
 ** multi-threaded processes.  Only a single thread is allowed to
 ** executed code that is surrounded by EnterMutex() and LeaveMutex().
 **
 ** SQLite uses only a single Mutex.  There is not much critical
 ** code and what little there is executes quickly and without blocking.
+**
+** Version 3.3.1 and earlier used a simple mutex.  Beginning with
+** version 3.3.2, a recursive mutex is required.
 */
-void sqlite3OsEnterMutex(){
+void sqlite3WinEnterMutex(){
 #ifdef SQLITE_W32_THREADS
   static int isInit = 0;
   while( !isInit ){
@@ -895,19 +1381,36 @@
     }
   }
   EnterCriticalSection(&cs);
+  mutexOwner = GetCurrentThreadId();
 #endif
-  assert( !inMutex );
-  inMutex = 1;
+  inMutex++;
 }
-void sqlite3OsLeaveMutex(){
+void sqlite3WinLeaveMutex(){
   assert( inMutex );
-  inMutex = 0;
+  inMutex--;
 #ifdef SQLITE_W32_THREADS
+  assert( mutexOwner==GetCurrentThreadId() );
   LeaveCriticalSection(&cs);
 #endif
 }
 
 /*
+** Return TRUE if the mutex is currently held.
+**
+** If the thisThreadOnly parameter is true, return true if and only if the
+** calling thread holds the mutex.  If the parameter is false, return
+** true if any thread holds the mutex.
+*/
+int sqlite3WinInMutex(int thisThreadOnly){
+#ifdef SQLITE_W32_THREADS
+  return inMutex>0 && (thisThreadOnly==0 || mutexOwner==GetCurrentThreadId());
+#else
+  return inMutex>0;
+#endif
+}
+
+
+/*
 ** The following variable, if set to a non-zero value, becomes the result
 ** returned from sqlite3OsCurrentTime().  This is used for testing.
 */
@@ -920,13 +1423,19 @@
 ** current time and date as a Julian Day number into *prNow and
 ** return 0.  Return 1 if the time and date cannot be found.
 */
-int sqlite3OsCurrentTime(double *prNow){
+int sqlite3WinCurrentTime(double *prNow){
   FILETIME ft;
   /* FILETIME structure is a 64-bit value representing the number of 
      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
   */
   double now;
+#if OS_WINCE
+  SYSTEMTIME time;
+  GetSystemTime(&time);
+  SystemTimeToFileTime(&time,&ft);
+#else
   GetSystemTimeAsFileTime( &ft );
+#endif
   now = ((double)ft.dwHighDateTime) * 4294967296.0; 
   *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
 #ifdef SQLITE_TEST
@@ -937,4 +1446,71 @@
   return 0;
 }
 
+/*
+** Remember the number of thread-specific-data blocks allocated.
+** Use this to verify that we are not leaking thread-specific-data.
+** Ticket #1601
+*/
+#ifdef SQLITE_TEST
+int sqlite3_tsd_count = 0;
+# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
+# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
+#else
+# define TSD_COUNTER_INCR  /* no-op */
+# define TSD_COUNTER_DECR  /* no-op */
+#endif
+
+
+
+/*
+** If called with allocateFlag>1, then return a pointer to thread
+** specific data for the current thread.  Allocate and zero the
+** thread-specific data if it does not already exist necessary.
+**
+** If called with allocateFlag==0, then check the current thread
+** specific data.  Return it if it exists.  If it does not exist,
+** then return NULL.
+**
+** If called with allocateFlag<0, check to see if the thread specific
+** data is allocated and is all zero.  If it is then deallocate it.
+** Return a pointer to the thread specific data or NULL if it is
+** unallocated or gets deallocated.
+*/
+ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
+  static int key;
+  static int keyInit = 0;
+  static const ThreadData zeroData = {0};
+  ThreadData *pTsd;
+
+  if( !keyInit ){
+    sqlite3OsEnterMutex();
+    if( !keyInit ){
+      key = TlsAlloc();
+      if( key==0xffffffff ){
+        sqlite3OsLeaveMutex();
+        return 0;
+      }
+      keyInit = 1;
+    }
+    sqlite3OsLeaveMutex();
+  }
+  pTsd = TlsGetValue(key);
+  if( allocateFlag>0 ){
+    if( !pTsd ){
+      pTsd = sqlite3OsMalloc( sizeof(zeroData) );
+      if( pTsd ){
+        *pTsd = zeroData;
+        TlsSetValue(key, pTsd);
+        TSD_COUNTER_INCR;
+      }
+    }
+  }else if( pTsd!=0 && allocateFlag<0 
+              && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
+    sqlite3OsFree(pTsd);
+    TlsSetValue(key, 0);
+    TSD_COUNTER_DECR;
+    pTsd = 0;
+  }
+  return pTsd;
+}
 #endif /* OS_WIN */

Modified: packages/libdbd-sqlite3-perl/trunk/pager.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/pager.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/pager.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.215 2005/09/17 15:20:27 drh Exp $
+** @(#) $Id: pager.c,v 1.265 2006/03/26 20:49:18 drh Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -46,21 +46,14 @@
 
 /*
 ** The following two macros are used within the TRACEX() macros above
-** to print out file-descriptors. They are required so that tracing
-** can be turned on when using both the regular os_unix.c and os_test.c
-** backends.
+** to print out file-descriptors. 
 **
 ** PAGERID() takes a pointer to a Pager struct as it's argument. The
 ** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
 ** struct as it's argument.
 */
-#ifdef OS_TEST
-#define PAGERID(p) (p->fd->fd.h)
-#define FILEHANDLEID(fd) (fd->fd.h)
-#else
-#define PAGERID(p) (p->fd.h)
-#define FILEHANDLEID(fd) (fd.h)
-#endif
+#define PAGERID(p) ((int)(p->fd))
+#define FILEHANDLEID(fd) ((int)fd)
 
 /*
 ** The page cache as a whole is always in one of the following
@@ -197,9 +190,11 @@
 ** A macro used for invoking the codec if there is one
 */
 #ifdef SQLITE_HAS_CODEC
-# define CODEC(P,D,N,X) if( P->xCodec ){ P->xCodec(P->pCodecArg,D,N,X); }
+# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); }
+# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D))
 #else
-# define CODEC(P,D,N,X)
+# define CODEC1(P,D,N,X) /* NO-OP */
+# define CODEC2(P,D,N,X) ((char*)D)
 #endif
 
 /*
@@ -232,6 +227,14 @@
 
 /*
 ** A open page cache is an instance of the following structure.
+**
+** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, SQLITE_PROTOCOL
+** or SQLITE_FULL. Once one of the first three errors occurs, it persists
+** and is returned as the result of every major pager API call.  The
+** SQLITE_FULL return code is slightly different. It persists only until the
+** next successful rollback is performed on the pager cache. Also,
+** SQLITE_FULL does not affect the sqlite3pager_get() and sqlite3pager_lookup()
+** APIs, they may still be used successfully.
 */
 struct Pager {
   u8 journalOpen;             /* True if journal file descriptors is valid */
@@ -243,8 +246,9 @@
   u8 stmtAutoopen;            /* Open stmt journal when main journal is opened*/
   u8 noSync;                  /* Do not sync the journal if true */
   u8 fullSync;                /* Do extra syncs of the journal for robustness */
+  u8 full_fsync;              /* Use F_FULLFSYNC when available */
   u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
-  u8 errMask;                 /* One of several kinds of errors */
+  u8 errCode;                 /* One of several kinds of errors */
   u8 tempFile;                /* zFilename is a temporary file */
   u8 readOnly;                /* True for a read-only database */
   u8 needSync;                /* True if an fsync() is needed on the journal */
@@ -269,8 +273,8 @@
   char *zFilename;            /* Name of the database file */
   char *zJournal;             /* Name of the journal file */
   char *zDirectory;           /* Directory hold database and journal files */
-  OsFile fd, jfd;             /* File descriptors for database and journal */
-  OsFile stfd;                /* File descriptor for the statement subjournal*/
+  OsFile *fd, *jfd;           /* File descriptors for database and journal */
+  OsFile *stfd;               /* File descriptor for the statement subjournal*/
   BusyHandler *pBusyHandler;  /* Pointer to sqlite.busyHandler */
   PgHdr *pFirst, *pLast;      /* List of free pages */
   PgHdr *pFirstSynced;        /* First free page with PgHdr.needSync==0 */
@@ -288,9 +292,12 @@
 #endif
   void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
   void (*xReiniter)(void*,int);   /* Call this routine when reloading pages */
-  void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
+  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
   void *pCodecArg;            /* First argument to xCodec() */
   PgHdr *aHash[N_PG_HASH];    /* Hash table to map page number to PgHdr */
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  Pager *pNext;               /* Linked list of pagers in this thread */
+#endif
 };
 
 /*
@@ -304,15 +311,6 @@
 #endif
 
 /*
-** These are bits that can be set in Pager.errMask.
-*/
-#define PAGER_ERR_FULL     0x01  /* a write() failed */
-#define PAGER_ERR_MEM      0x02  /* malloc() failed */
-#define PAGER_ERR_LOCK     0x04  /* error in the locking protocol */
-#define PAGER_ERR_CORRUPT  0x08  /* database or journal corruption */
-#define PAGER_ERR_DISK     0x10  /* general disk I/O error - bad hard drive? */
-
-/*
 ** Journal files begin with the following magic string.  The data
 ** was obtained from /dev/random.  It is used only as a sanity check.
 **
@@ -411,42 +409,32 @@
 ** All values are stored on disk as big-endian.
 */
 static int read32bits(OsFile *fd, u32 *pRes){
-  u32 res;
-  int rc;
-  rc = sqlite3OsRead(fd, &res, sizeof(res));
+  unsigned char ac[4];
+  int rc = sqlite3OsRead(fd, ac, sizeof(ac));
   if( rc==SQLITE_OK ){
-    unsigned char ac[4];
-    memcpy(ac, &res, 4);
-    res = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
+    *pRes = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
   }
-  *pRes = res;
   return rc;
 }
 
 /*
-** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
-** on success or an error code is something goes wrong.
+** Write a 32-bit integer into a string buffer in big-endian byte order.
 */
-static int write32bits(OsFile *fd, u32 val){
-  unsigned char ac[4];
+static void put32bits(char *ac, u32 val){
   ac[0] = (val>>24) & 0xff;
   ac[1] = (val>>16) & 0xff;
   ac[2] = (val>>8) & 0xff;
   ac[3] = val & 0xff;
-  return sqlite3OsWrite(fd, ac, 4);
 }
 
 /*
-** Write the 32-bit integer 'val' into the page identified by page header
-** 'p' at offset 'offset'.
+** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
+** on success or an error code is something goes wrong.
 */
-static void store32bits(u32 val, PgHdr *p, int offset){
-  unsigned char *ac;
-  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
-  ac[0] = (val>>24) & 0xff;
-  ac[1] = (val>>16) & 0xff;
-  ac[2] = (val>>8) & 0xff;
-  ac[3] = val & 0xff;
+static int write32bits(OsFile *fd, u32 val){
+  char ac[4];
+  put32bits(ac, val);
+  return sqlite3OsWrite(fd, ac, 4);
 }
 
 /*
@@ -461,16 +449,25 @@
 
 
 /*
-** Convert the bits in the pPager->errMask into an approprate
-** return code.
+** This function should be called when an error occurs within the pager
+** code. The first argument is a pointer to the pager structure, the
+** second the error-code about to be returned by a pager API function. 
+** The value returned is a copy of the second argument to this function. 
+**
+** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_PROTOCOL,
+** the error becomes persistent. All subsequent API calls on this Pager
+** will immediately return the same error code.
 */
-static int pager_errcode(Pager *pPager){
-  int rc = SQLITE_OK;
-  if( pPager->errMask & PAGER_ERR_LOCK )    rc = SQLITE_PROTOCOL;
-  if( pPager->errMask & PAGER_ERR_DISK )    rc = SQLITE_IOERR;
-  if( pPager->errMask & PAGER_ERR_FULL )    rc = SQLITE_FULL;
-  if( pPager->errMask & PAGER_ERR_MEM )     rc = SQLITE_NOMEM;
-  if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
+static int pager_error(Pager *pPager, int rc){
+  assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK );
+  if( 
+    rc==SQLITE_FULL ||
+    rc==SQLITE_IOERR ||
+    rc==SQLITE_CORRUPT ||
+    rc==SQLITE_PROTOCOL
+  ){
+    pPager->errCode = rc;
+  }
   return rc;
 }
 
@@ -496,7 +493,7 @@
 #define CHECK_PAGE(x) checkPage(x)
 static void checkPage(PgHdr *pPg){
   Pager *pPager = pPg->pPager;
-  assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty || 
+  assert( !pPg->pageHash || pPager->errCode || MEMDB || pPg->dirty || 
       pPg->pageHash==pager_pagehash(pPg) );
 }
 
@@ -597,7 +594,7 @@
   assert( offset>=c );
   assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
   pPager->journalOff = offset;
-  return sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
+  return sqlite3OsSeek(pPager->jfd, pPager->journalOff);
 }
 
 /*
@@ -615,6 +612,7 @@
 ** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space.
 */
 static int writeJournalHdr(Pager *pPager){
+  char zHeader[sizeof(aJournalMagic)+16];
 
   int rc = seekJournalHdr(pPager);
   if( rc ) return rc;
@@ -633,33 +631,25 @@
   ** Actually maybe the whole journal header should be delayed until that
   ** point. Think about this.
   */
-  rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
+  memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
+  /* The nRec Field. 0xFFFFFFFF for no-sync journals. */
+  put32bits(&zHeader[sizeof(aJournalMagic)], pPager->noSync ? 0xffffffff : 0);
+  /* The random check-hash initialiser */ 
+  sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
+  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
+  /* The initial database size */
+  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize);
+  /* The assumed sector size for this process */
+  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
+  rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader));
 
-  if( rc==SQLITE_OK ){
-    /* The nRec Field. 0xFFFFFFFF for no-sync journals. */
-    rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
-  }
-  if( rc==SQLITE_OK ){
-    /* The random check-hash initialiser */ 
-    sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
-    rc = write32bits(&pPager->jfd, pPager->cksumInit);
-  }
-  if( rc==SQLITE_OK ){
-    /* The initial database size */
-    rc = write32bits(&pPager->jfd, pPager->dbSize);
-  }
-  if( rc==SQLITE_OK ){
-    /* The assumed sector size for this process */
-    rc = write32bits(&pPager->jfd, pPager->sectorSize);
-  }
-
   /* The journal header has been written successfully. Seek the journal
   ** file descriptor to the end of the journal header sector.
   */
   if( rc==SQLITE_OK ){
-    rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff-1);
+    rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff-1);
     if( rc==SQLITE_OK ){
-      rc = sqlite3OsWrite(&pPager->jfd, "\000", 1);
+      rc = sqlite3OsWrite(pPager->jfd, "\000", 1);
     }
   }
   return rc;
@@ -697,20 +687,20 @@
     return SQLITE_DONE;
   }
 
-  rc = sqlite3OsRead(&pPager->jfd, aMagic, sizeof(aMagic));
+  rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic));
   if( rc ) return rc;
 
   if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
     return SQLITE_DONE;
   }
 
-  rc = read32bits(&pPager->jfd, pNRec);
+  rc = read32bits(pPager->jfd, pNRec);
   if( rc ) return rc;
 
-  rc = read32bits(&pPager->jfd, &pPager->cksumInit);
+  rc = read32bits(pPager->jfd, &pPager->cksumInit);
   if( rc ) return rc;
 
-  rc = read32bits(&pPager->jfd, pDbSize);
+  rc = read32bits(pPager->jfd, pDbSize);
   if( rc ) return rc;
 
   /* Update the assumed sector-size to match the value used by 
@@ -719,11 +709,11 @@
   ** is being called from within pager_playback(). The local value
   ** of Pager.sectorSize is restored at the end of that routine.
   */
-  rc = read32bits(&pPager->jfd, (u32 *)&pPager->sectorSize);
+  rc = read32bits(pPager->jfd, (u32 *)&pPager->sectorSize);
   if( rc ) return rc;
 
   pPager->journalOff += JOURNAL_HDR_SZ(pPager);
-  rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
+  rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff);
   return rc;
 }
 
@@ -743,12 +733,16 @@
 **
 ** The master journal page checksum is the sum of the bytes in the master
 ** journal name.
+**
+** If zMaster is a NULL pointer (occurs for a single database transaction), 
+** this call is a no-op.
 */
 static int writeMasterJournal(Pager *pPager, const char *zMaster){
   int rc;
   int len; 
   int i; 
-  u32 cksum = 0; 
+  u32 cksum = 0;
+  char zBuf[sizeof(aJournalMagic)+2*4];
 
   if( !zMaster || pPager->setMaster) return SQLITE_OK;
   pPager->setMaster = 1;
@@ -768,19 +762,16 @@
   }
   pPager->journalOff += (len+20);
 
-  rc = write32bits(&pPager->jfd, PAGER_MJ_PGNO(pPager));
+  rc = write32bits(pPager->jfd, PAGER_MJ_PGNO(pPager));
   if( rc!=SQLITE_OK ) return rc;
 
-  rc = sqlite3OsWrite(&pPager->jfd, zMaster, len);
+  rc = sqlite3OsWrite(pPager->jfd, zMaster, len);
   if( rc!=SQLITE_OK ) return rc;
 
-  rc = write32bits(&pPager->jfd, len);
-  if( rc!=SQLITE_OK ) return rc;
-
-  rc = write32bits(&pPager->jfd, cksum);
-  if( rc!=SQLITE_OK ) return rc;
-
-  rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
+  put32bits(zBuf, len);
+  put32bits(&zBuf[4], cksum);
+  memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic));
+  rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic));
   pPager->needSync = !pPager->noSync;
   return rc;
 }
@@ -844,7 +835,7 @@
 */
 static void pager_reset(Pager *pPager){
   PgHdr *pPg, *pNext;
-  if( pPager->errMask ) return;
+  if( pPager->errCode ) return;
   for(pPg=pPager->pAll; pPg; pPg=pNext){
     pNext = pPg->pNextAll;
     sqliteFree(pPg);
@@ -858,7 +849,7 @@
   if( pPager->state>=PAGER_RESERVED ){
     sqlite3pager_rollback(pPager);
   }
-  sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+  sqlite3OsUnlock(pPager->fd, NO_LOCK);
   pPager->state = PAGER_UNLOCK;
   pPager->dbSize = -1;
   pPager->nRef = 0;
@@ -866,29 +857,6 @@
 }
 
 /*
-** This function is used to reset the pager after a malloc() failure. This
-** doesn't work with in-memory databases. If a malloc() fails when an 
-** in-memory database is in use it is not possible to recover.
-**
-** If a transaction or statement transaction is active, it is rolled back.
-**
-** It is an error to call this function if any pages are in use.
-*/
-#ifndef SQLITE_OMIT_GLOBALRECOVER
-int sqlite3pager_reset(Pager *pPager){
-  if( pPager ){
-    if( pPager->nRef || MEMDB ){
-      return SQLITE_ERROR;
-    }
-    pPager->errMask &= ~(PAGER_ERR_MEM);
-    pager_reset(pPager);
-  }
-  return SQLITE_OK;
-}
-#endif
-
-
-/*
 ** When this routine is called, the pager has the journal file open and
 ** a RESERVED or EXCLUSIVE lock on the database.  This routine releases
 ** the database lock and acquires a SHARED lock in its place.  The journal
@@ -930,10 +898,12 @@
     assert( pPager->aInJournal==0 );
     assert( pPager->dirtyCache==0 || pPager->useJournal==0 );
   }
-  rc = sqlite3OsUnlock(&pPager->fd, SHARED_LOCK);
+  rc = sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
   pPager->state = PAGER_SHARED;
   pPager->origDbSize = 0;
   pPager->setMaster = 0;
+  pPager->needSync = 0;
+  pPager->pFirstSynced = pPager->pFirst;
   return rc;
 }
 
@@ -957,7 +927,7 @@
 ** only the middle sector is corrupt, we will still have a reasonable
 ** chance of failing the checksum and thus detecting the problem.
 */
-static u32 pager_cksum(Pager *pPager, Pgno pgno, const char *aData){
+static u32 pager_cksum(Pager *pPager, const u8 *aData){
   u32 cksum = pPager->cksumInit;
   int i = pPager->pageSize-200;
   while( i>0 ){
@@ -985,7 +955,7 @@
   /* useCksum should be true for the main journal and false for
   ** statement journals.  Verify that this is always the case
   */
-  assert( jfd == (useCksum ? &pPager->jfd : &pPager->stfd) );
+  assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) );
 
 
   rc = read32bits(jfd, &pgno);
@@ -1009,7 +979,7 @@
     rc = read32bits(jfd, &cksum);
     if( rc ) return rc;
     pPager->journalOff += 4;
-    if( pager_cksum(pPager, pgno, aData)!=cksum ){
+    if( pager_cksum(pPager, aData)!=cksum ){
       return SQLITE_DONE;
     }
   }
@@ -1040,9 +1010,9 @@
   assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 );
   TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno);
   if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){
-    rc = sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);
+    rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
     if( rc==SQLITE_OK ){
-      rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);
+      rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize);
     }
     if( pPg ) pPg->dirty = 0;
   }
@@ -1063,7 +1033,7 @@
 #ifdef SQLITE_CHECK_PAGES
     pPg->pageHash = pager_pagehash(pPg);
 #endif
-    CODEC(pPager, pData, pPg->pgno, 3);
+    CODEC1(pPager, pData, pPg->pgno, 3);
   }
   return rc;
 }
@@ -1082,18 +1052,17 @@
 static int pager_delmaster(const char *zMaster){
   int rc;
   int master_open = 0;
-  OsFile master;
+  OsFile *master = 0;
   char *zMasterJournal = 0; /* Contents of master journal file */
   i64 nMasterJournal;       /* Size of master journal file */
 
   /* Open the master journal file exclusively in case some other process
   ** is running this routine also. Not that it makes too much difference.
   */
-  memset(&master, 0, sizeof(master));
   rc = sqlite3OsOpenReadOnly(zMaster, &master);
   if( rc!=SQLITE_OK ) goto delmaster_out;
   master_open = 1;
-  rc = sqlite3OsFileSize(&master, &nMasterJournal);
+  rc = sqlite3OsFileSize(master, &nMasterJournal);
   if( rc!=SQLITE_OK ) goto delmaster_out;
 
   if( nMasterJournal>0 ){
@@ -1108,7 +1077,7 @@
       rc = SQLITE_NOMEM;
       goto delmaster_out;
     }
-    rc = sqlite3OsRead(&master, zMasterJournal, nMasterJournal);
+    rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal);
     if( rc!=SQLITE_OK ) goto delmaster_out;
 
     zJournal = zMasterJournal;
@@ -1118,16 +1087,15 @@
         ** Open it and check if it points at the master journal. If
         ** so, return without deleting the master journal file.
         */
-        OsFile journal;
+        OsFile *journal = 0;
         int c;
 
-        memset(&journal, 0, sizeof(journal));
         rc = sqlite3OsOpenReadOnly(zJournal, &journal);
         if( rc!=SQLITE_OK ){
           goto delmaster_out;
         }
 
-        rc = readMasterJournal(&journal, &zMasterPtr);
+        rc = readMasterJournal(journal, &zMasterPtr);
         sqlite3OsClose(&journal);
         if( rc!=SQLITE_OK ){
           goto delmaster_out;
@@ -1172,13 +1140,13 @@
     char zBuf[SQLITE_MAX_PAGE_SIZE];
     if( !pPg->dirty ) continue;
     if( (int)pPg->pgno <= pPager->origDbSize ){
-      rc = sqlite3OsSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));
+      rc = sqlite3OsSeek(pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));
       if( rc==SQLITE_OK ){
-        rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
+        rc = sqlite3OsRead(pPager->fd, zBuf, pPager->pageSize);
       }
       TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
       if( rc ) break;
-      CODEC(pPager, zBuf, pPg->pgno, 2);
+      CODEC1(pPager, zBuf, pPg->pgno, 2);
     }else{
       memset(zBuf, 0, pPager->pageSize);
     }
@@ -1205,7 +1173,7 @@
 */
 static int pager_truncate(Pager *pPager, int nPage){
   assert( pPager->state>=PAGER_EXCLUSIVE );
-  return sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(i64)nPage);
+  return sqlite3OsTruncate(pPager->fd, pPager->pageSize*(i64)nPage);
 }
 
 /*
@@ -1273,7 +1241,7 @@
   ** the journal is empty.
   */
   assert( pPager->journalOpen );
-  rc = sqlite3OsFileSize(&pPager->jfd, &szJ);
+  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
   if( rc!=SQLITE_OK ){
     goto end_playback;
   }
@@ -1283,7 +1251,7 @@
   ** present on disk, then the journal is not hot and does not need to be
   ** played back.
   */
-  rc = readMasterJournal(&pPager->jfd, &zMaster);
+  rc = readMasterJournal(pPager->jfd, &zMaster);
   assert( rc!=SQLITE_DONE );
   if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){
     sqliteFree(zMaster);
@@ -1291,7 +1259,7 @@
     if( rc==SQLITE_DONE ) rc = SQLITE_OK;
     goto end_playback;
   }
-  sqlite3OsSeek(&pPager->jfd, 0);
+  sqlite3OsSeek(pPager->jfd, 0);
   pPager->journalOff = 0;
 
   /* This loop terminates either when the readJournalHdr() call returns
@@ -1334,13 +1302,10 @@
       pPager->dbSize = mxPg;
     }
 
-    /* rc = sqlite3OsSeek(&pPager->jfd, JOURNAL_HDR_SZ(pPager)); */
-    if( rc!=SQLITE_OK ) goto end_playback;
-  
     /* Copy original pages out of the journal and back into the database file.
     */
     for(i=0; i<nRec; i++){
-      rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
+      rc = pager_playback_one_page(pPager, pPager->jfd, 1);
       if( rc!=SQLITE_OK ){
         if( rc==SQLITE_DONE ){
           rc = SQLITE_OK;
@@ -1352,14 +1317,9 @@
       }
     }
   }
+  /*NOTREACHED*/
+  assert( 0 );
 
-  /* Pages that have been written to the journal but never synced
-  ** where not restored by the loop above.  We have to restore those
-  ** pages by reading them back from the original database.
-  */
-  assert( rc==SQLITE_OK );
-  pager_reload_cache(pPager);
-
 end_playback:
   if( rc==SQLITE_OK ){
     rc = pager_unwritelock(pPager);
@@ -1407,7 +1367,7 @@
 #ifndef NDEBUG 
   {
     i64 os_szJ;
-    rc = sqlite3OsFileSize(&pPager->jfd, &os_szJ);
+    rc = sqlite3OsFileSize(pPager->jfd, &os_szJ);
     if( rc!=SQLITE_OK ) return rc;
     assert( szJ==os_szJ );
   }
@@ -1433,7 +1393,7 @@
   /* Figure out how many records are in the statement journal.
   */
   assert( pPager->stmtInUse && pPager->journalOpen );
-  sqlite3OsSeek(&pPager->stfd, 0);
+  sqlite3OsSeek(pPager->stfd, 0);
   nRec = pPager->stmtNRec;
   
   /* Copy original pages out of the statement journal and back into the
@@ -1442,7 +1402,7 @@
   ** journals.
   */
   for(i=nRec-1; i>=0; i--){
-    rc = pager_playback_one_page(pPager, &pPager->stfd, 0);
+    rc = pager_playback_one_page(pPager, pPager->stfd, 0);
     assert( rc!=SQLITE_DONE );
     if( rc!=SQLITE_OK ) goto end_stmt_playback;
   }
@@ -1455,7 +1415,7 @@
   ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
   ** of the first journal header written during this statement transaction.
   */
-  rc = sqlite3OsSeek(&pPager->jfd, pPager->stmtJSize);
+  rc = sqlite3OsSeek(pPager->jfd, pPager->stmtJSize);
   if( rc!=SQLITE_OK ){
     goto end_stmt_playback;
   }
@@ -1463,24 +1423,24 @@
   pPager->cksumInit = pPager->stmtCksum;
   assert( JOURNAL_HDR_SZ(pPager)<(pPager->pageSize+8) );
   while( pPager->journalOff <= (hdrOff-(pPager->pageSize+8)) ){
-    rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
+    rc = pager_playback_one_page(pPager, pPager->jfd, 1);
     assert( rc!=SQLITE_DONE );
     if( rc!=SQLITE_OK ) goto end_stmt_playback;
   }
 
   while( pPager->journalOff < szJ ){
-    u32 nRec;
+    u32 nJRec;         /* Number of Journal Records */
     u32 dummy;
-    rc = readJournalHdr(pPager, szJ, &nRec, &dummy);
+    rc = readJournalHdr(pPager, szJ, &nJRec, &dummy);
     if( rc!=SQLITE_OK ){
       assert( rc!=SQLITE_DONE );
       goto end_stmt_playback;
     }
-    if( nRec==0 ){
-      nRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
+    if( nJRec==0 ){
+      nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
     }
-    for(i=nRec-1; i>=0 && pPager->journalOff < szJ; i--){
-      rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
+    for(i=nJRec-1; i>=0 && pPager->journalOff < szJ; i--){
+      rc = pager_playback_one_page(pPager, pPager->jfd, 1);
       assert( rc!=SQLITE_DONE );
       if( rc!=SQLITE_OK ) goto end_stmt_playback;
     }
@@ -1489,10 +1449,7 @@
   pPager->journalOff = szJ;
   
 end_stmt_playback:
-  if( rc!=SQLITE_OK ){
-    pPager->errMask |= PAGER_ERR_CORRUPT;
-    rc = SQLITE_CORRUPT;
-  }else{
+  if( rc==SQLITE_OK) {
     pPager->journalOff = szJ;
     /* pager_reload_cache(pPager); */
   }
@@ -1537,9 +1494,10 @@
 ** and FULL=3.
 */
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
-void sqlite3pager_set_safety_level(Pager *pPager, int level){
+void sqlite3pager_set_safety_level(Pager *pPager, int level, int full_fsync){
   pPager->noSync =  level==1 || pPager->tempFile;
   pPager->fullSync = level==3 && !pPager->tempFile;
+  pPager->full_fsync = full_fsync;
   if( pPager->noSync ) pPager->needSync = 0;
 }
 #endif
@@ -1560,14 +1518,14 @@
 ** The OS will automatically delete the temporary file when it is
 ** closed.
 */
-static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
+static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){
   int cnt = 8;
   int rc;
   sqlite3_opentemp_count++;  /* Used for testing and analysis only */
   do{
     cnt--;
     sqlite3OsTempFileName(zFile);
-    rc = sqlite3OsOpenExclusive(zFile, fd, 1);
+    rc = sqlite3OsOpenExclusive(zFile, pFd, 1);
   }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
   return rc;
 }
@@ -1592,10 +1550,10 @@
   int nExtra,              /* Extra bytes append to each in-memory page */
   int flags                /* flags controlling this file */
 ){
-  Pager *pPager;
+  Pager *pPager = 0;
   char *zFullPathname = 0;
-  int nameLen;
-  OsFile fd;
+  int nameLen;  /* Compiler is wrong. This is always initialized before use */
+  OsFile *fd;
   int rc = SQLITE_OK;
   int i;
   int tempFile = 0;
@@ -1604,18 +1562,36 @@
   int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
   int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
   char zTemp[SQLITE_TEMPNAME_SIZE];
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to 
+  ** malloc() must have already been made by this thread before it gets
+  ** to this point. This means the ThreadData must have been allocated already
+  ** so that ThreadData.nAlloc can be set. It would be nice to assert
+  ** that ThreadData.nAlloc is non-zero, but alas this breaks test cases 
+  ** written to invoke the pager directly.
+  */
+  ThreadData *pTsd = sqlite3ThreadData();
+  assert( pTsd );
+#endif
 
+  /* If malloc() has already failed return SQLITE_NOMEM. Before even
+  ** testing for this, set *ppPager to NULL so the caller knows the pager
+  ** structure was never allocated. 
+  */
   *ppPager = 0;
-  memset(&fd, 0, sizeof(fd));
-  if( sqlite3_malloc_failed ){
+  if( sqlite3MallocFailed() ){
     return SQLITE_NOMEM;
   }
+  memset(&fd, 0, sizeof(fd));
+
+  /* Open the pager file and set zFullPathname to point at malloc()ed 
+  ** memory containing the complete filename (i.e. including the directory).
+  */
   if( zFilename && zFilename[0] ){
 #ifndef SQLITE_OMIT_MEMORYDB
     if( strcmp(zFilename,":memory:")==0 ){
       memDb = 1;
       zFullPathname = sqliteStrDup("");
-      rc = SQLITE_OK;
     }else
 #endif
     {
@@ -1632,66 +1608,75 @@
       tempFile = 1;
     }
   }
-  if( !zFullPathname ){
-    sqlite3OsClose(&fd);
-    return SQLITE_NOMEM;
+
+  /* Allocate the Pager structure. As part of the same allocation, allocate
+  ** space for the full paths of the file, directory and journal 
+  ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal).
+  */
+  if( zFullPathname ){
+    nameLen = strlen(zFullPathname);
+    pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
   }
-  if( rc!=SQLITE_OK ){
+
+  /* If an error occured in either of the blocks above, free the memory 
+  ** pointed to by zFullPathname, free the Pager structure and close the 
+  ** file. Since the pager is not allocated there is no need to set 
+  ** any Pager.errMask variables.
+  */
+  if( !pPager || !zFullPathname || rc!=SQLITE_OK ){
     sqlite3OsClose(&fd);
     sqliteFree(zFullPathname);
-    return rc;
+    sqliteFree(pPager);
+    return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
   }
-  nameLen = strlen(zFullPathname);
-  pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
-  if( pPager==0 ){
-    sqlite3OsClose(&fd);
-    sqliteFree(zFullPathname);
-    return SQLITE_NOMEM;
-  }
+
   TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
   pPager->zFilename = (char*)&pPager[1];
   pPager->zDirectory = &pPager->zFilename[nameLen+1];
   pPager->zJournal = &pPager->zDirectory[nameLen+1];
   strcpy(pPager->zFilename, zFullPathname);
   strcpy(pPager->zDirectory, zFullPathname);
+
   for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
   if( i>0 ) pPager->zDirectory[i-1] = 0;
   strcpy(pPager->zJournal, zFullPathname);
   sqliteFree(zFullPathname);
   strcpy(&pPager->zJournal[nameLen], "-journal");
   pPager->fd = fd;
-#if OS_UNIX
-  pPager->fd.pPager = pPager;
-#endif
-  pPager->journalOpen = 0;
+  /* pPager->journalOpen = 0; */
   pPager->useJournal = useJournal && !memDb;
   pPager->noReadlock = noReadlock && readOnly;
-  pPager->stmtOpen = 0;
-  pPager->stmtInUse = 0;
-  pPager->nRef = 0;
+  /* pPager->stmtOpen = 0; */
+  /* pPager->stmtInUse = 0; */
+  /* pPager->nRef = 0; */
   pPager->dbSize = memDb-1;
   pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
-  pPager->stmtSize = 0;
-  pPager->stmtJSize = 0;
-  pPager->nPage = 0;
-  pPager->nMaxPage = 0;
+  /* pPager->stmtSize = 0; */
+  /* pPager->stmtJSize = 0; */
+  /* pPager->nPage = 0; */
+  /* pPager->nMaxPage = 0; */
   pPager->mxPage = 100;
-  pPager->state = PAGER_UNLOCK;
-  pPager->errMask = 0;
+  assert( PAGER_UNLOCK==0 );
+  /* pPager->state = PAGER_UNLOCK; */
+  /* pPager->errMask = 0; */
   pPager->tempFile = tempFile;
   pPager->memDb = memDb;
   pPager->readOnly = readOnly;
-  pPager->needSync = 0;
+  /* pPager->needSync = 0; */
   pPager->noSync = pPager->tempFile || !useJournal;
   pPager->fullSync = (pPager->noSync?0:1);
-  pPager->pFirst = 0;
-  pPager->pFirstSynced = 0;
-  pPager->pLast = 0;
+  /* pPager->pFirst = 0; */
+  /* pPager->pFirstSynced = 0; */
+  /* pPager->pLast = 0; */
   pPager->nExtra = FORCE_ALIGNMENT(nExtra);
   pPager->sectorSize = PAGER_SECTOR_SIZE;
-  pPager->pBusyHandler = 0;
-  memset(pPager->aHash, 0, sizeof(pPager->aHash));
+  /* pPager->pBusyHandler = 0; */
+  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
   *ppPager = pPager;
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  pPager->pNext = pTsd->pPager;
+  pTsd->pPager = pPager;
+#endif
   return SQLITE_OK;
 }
 
@@ -1739,14 +1724,50 @@
 }
 
 /*
+** The following set of routines are used to disable the simulated
+** I/O error mechanism.  These routines are used to avoid simulated
+** errors in places where we do not care about errors.
+**
+** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
+** and generate no code.
+*/
+#ifdef SQLITE_TEST
+extern int sqlite3_io_error_pending;
+extern int sqlite3_io_error_hit;
+static int saved_cnt;
+void clear_simulated_io_error(){
+  sqlite3_io_error_hit = 0;
+}
+void disable_simulated_io_errors(void){
+  saved_cnt = sqlite3_io_error_pending;
+  sqlite3_io_error_pending = -1;
+}
+void enable_simulated_io_errors(void){
+  sqlite3_io_error_pending = saved_cnt;
+}
+#else
+# define clear_simulated_io_error()
+# define disable_simulated_io_errors()
+# define enable_simulated_io_errors()
+#endif
+
+/*
 ** Read the first N bytes from the beginning of the file into memory
-** that pDest points to.  No error checking is done.
+** that pDest points to. 
+**
+** No error checking is done. The rational for this is that this function 
+** may be called even if the file does not exist or contain a header. In 
+** these cases sqlite3OsRead() will return an error, to which the correct 
+** response is to zero the memory at pDest and continue.  A real IO error 
+** will presumably recur and be picked up later (Todo: Think about this).
 */
 void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
   memset(pDest, 0, N);
   if( MEMDB==0 ){
-    sqlite3OsSeek(&pPager->fd, 0);
-    sqlite3OsRead(&pPager->fd, pDest, N);
+    disable_simulated_io_errors();
+    sqlite3OsSeek(pPager->fd, 0);
+    sqlite3OsRead(pPager->fd, pDest, N);
+    enable_simulated_io_errors();
   }
 }
 
@@ -1765,8 +1786,8 @@
   if( pPager->dbSize>=0 ){
     n = pPager->dbSize;
   } else {
-    if( sqlite3OsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
-      pPager->errMask |= PAGER_ERR_DISK;
+    if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){
+      pager_error(pPager, SQLITE_IOERR);
       return 0;
     }
     if( n>0 && n<pPager->pageSize ){
@@ -1788,6 +1809,7 @@
 ** Forward declaration
 */
 static int syncJournal(Pager*);
+static void clearHistory(PgHistory*);
 
 
 /*
@@ -1812,7 +1834,9 @@
     assert( pPager->aHash[h]==pPg );
     pPager->aHash[h] = pPg->pNextHash;
   }
-
+  if( MEMDB ){
+    clearHistory(PGHDR_TO_HIST(pPg, pPager));
+  }
   pPg->pgno = 0;
   pPg->pNextHash = pPg->pPrevHash = 0;
 }
@@ -1897,7 +1921,7 @@
     rc = SQLITE_OK;
   }else{
     do {
-      rc = sqlite3OsLock(&pPager->fd, locktype);
+      rc = sqlite3OsLock(pPager->fd, locktype);
     }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) );
     if( rc==SQLITE_OK ){
       pPager->state = locktype;
@@ -1912,8 +1936,8 @@
 int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
   int rc;
   sqlite3pager_pagecount(pPager);
-  if( pPager->errMask!=0 ){
-    rc = pager_errcode(pPager);
+  if( pPager->errCode ){
+    rc = pPager->errCode;
     return rc;
   }
   if( nPage>=(unsigned)pPager->dbSize ){
@@ -1950,9 +1974,25 @@
 ** and their memory is freed.  Any attempt to use a page associated
 ** with this page cache after this function returns will likely
 ** result in a coredump.
+**
+** This function always succeeds. If a transaction is active an attempt
+** is made to roll it back. If an error occurs during the rollback 
+** a hot journal may be left in the filesystem but no error is returned
+** to the caller.
 */
 int sqlite3pager_close(Pager *pPager){
   PgHdr *pPg, *pNext;
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to 
+  ** malloc() must have already been made by this thread before it gets
+  ** to this point. This means the ThreadData must have been allocated already
+  ** so that ThreadData.nAlloc can be set.
+  */
+  ThreadData *pTsd = sqlite3ThreadData();
+  assert( pPager );
+  assert( pTsd && pTsd->nAlloc );
+#endif
+
   switch( pPager->state ){
     case PAGER_RESERVED:
     case PAGER_SYNCED: 
@@ -1961,24 +2001,18 @@
       ** operation. So disable IO error simulation so that testing
       ** works more easily.
       */
-#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
-      extern int sqlite3_io_error_pending;
-      int ioerr_cnt = sqlite3_io_error_pending;
-      sqlite3_io_error_pending = -1;
-#endif
+      disable_simulated_io_errors();
       sqlite3pager_rollback(pPager);
-#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
-      sqlite3_io_error_pending = ioerr_cnt;
-#endif
+      enable_simulated_io_errors();
       if( !MEMDB ){
-        sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+        sqlite3OsUnlock(pPager->fd, NO_LOCK);
       }
-      assert( pPager->errMask || pPager->journalOpen==0 );
+      assert( pPager->errCode || pPager->journalOpen==0 );
       break;
     }
     case PAGER_SHARED: {
       if( !MEMDB ){
-        sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+        sqlite3OsUnlock(pPager->fd, NO_LOCK);
       }
       break;
     }
@@ -2000,7 +2034,7 @@
     sqliteFree(pPg);
   }
   TRACE2("CLOSE %d\n", PAGERID(pPager));
-  assert( pPager->errMask || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
+  assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
   if( pPager->journalOpen ){
     sqlite3OsClose(&pPager->jfd);
   }
@@ -2015,6 +2049,19 @@
   ** }
   */
 
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  /* Remove the pager from the linked list of pagers starting at 
+  ** ThreadData.pPager if memory-management is enabled.
+  */
+  if( pPager==pTsd->pPager ){
+    pTsd->pPager = pPager->pNext;
+  }else{
+    Pager *pTmp;
+    for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){}
+    pTmp->pNext = pPager->pNext;
+  }
+#endif
+
   sqliteFree(pPager);
   return SQLITE_OK;
 }
@@ -2120,7 +2167,7 @@
         ** with the nRec computed from the size of the journal file.
         */
         i64 jSz;
-        rc = sqlite3OsFileSize(&pPager->jfd, &jSz);
+        rc = sqlite3OsFileSize(pPager->jfd, &jSz);
         if( rc!=0 ) return rc;
         assert( pPager->journalOff==jSz );
       }
@@ -2133,20 +2180,20 @@
         */
         if( pPager->fullSync ){
           TRACE2("SYNC journal of %d\n", PAGERID(pPager));
-          rc = sqlite3OsSync(&pPager->jfd, 0);
+          rc = sqlite3OsSync(pPager->jfd, 0);
           if( rc!=0 ) return rc;
         }
-        rc = sqlite3OsSeek(&pPager->jfd,
+        rc = sqlite3OsSeek(pPager->jfd,
                            pPager->journalHdr + sizeof(aJournalMagic));
         if( rc ) return rc;
-        rc = write32bits(&pPager->jfd, pPager->nRec);
+        rc = write32bits(pPager->jfd, pPager->nRec);
         if( rc ) return rc;
 
-        rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
+        rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff);
         if( rc ) return rc;
       }
       TRACE2("SYNC journal of %d\n", PAGERID(pPager));
-      rc = sqlite3OsSync(&pPager->jfd, pPager->fullSync);
+      rc = sqlite3OsSync(pPager->jfd, pPager->full_fsync);
       if( rc!=0 ) return rc;
       pPager->journalStarted = 1;
     }
@@ -2211,7 +2258,7 @@
 
   while( pList ){
     assert( pList->dirty );
-    rc = sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);
+    rc = sqlite3OsSeek(pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);
     if( rc ) return rc;
     /* If there are dirty pages in the page cache with page numbers greater
     ** than Pager.dbSize, this means sqlite3pager_truncate() was called to
@@ -2219,10 +2266,9 @@
     ** any such pages to the file.
     */
     if( pList->pgno<=pPager->dbSize ){
-      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
+      char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
       TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
-      rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize);
-      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
+      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize);
       TEST_INCR(pPager->nWrite);
     }
 #ifndef NDEBUG
@@ -2268,7 +2314,7 @@
 static int hasHotJournal(Pager *pPager){
   if( !pPager->useJournal ) return 0;
   if( !sqlite3OsFileExists(pPager->zJournal) ) return 0;
-  if( sqlite3OsCheckReservedLock(&pPager->fd) ) return 0;
+  if( sqlite3OsCheckReservedLock(pPager->fd) ) return 0;
   if( sqlite3pager_pagecount(pPager)==0 ){
     sqlite3OsDelete(pPager->zJournal);
     return 0;
@@ -2278,6 +2324,170 @@
 }
 
 /*
+** Try to find a page in the cache that can be recycled. 
+**
+** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It 
+** does not set the pPager->errCode variable.
+*/
+static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
+  PgHdr *pPg;
+  *ppPg = 0;
+
+  /* Find a page to recycle.  Try to locate a page that does not
+  ** require us to do an fsync() on the journal.
+  */
+  pPg = pPager->pFirstSynced;
+
+  /* If we could not find a page that does not require an fsync()
+  ** on the journal file then fsync the journal file.  This is a
+  ** very slow operation, so we work hard to avoid it.  But sometimes
+  ** it can't be helped.
+  */
+  if( pPg==0 && pPager->pFirst && syncOk && !MEMDB){
+    int rc = syncJournal(pPager);
+    if( rc!=0 ){
+      return rc;
+    }
+    if( pPager->fullSync ){
+      /* If in full-sync mode, write a new journal header into the
+      ** journal file. This is done to avoid ever modifying a journal
+      ** header that is involved in the rollback of pages that have
+      ** already been written to the database (in case the header is
+      ** trashed when the nRec field is updated).
+      */
+      pPager->nRec = 0;
+      assert( pPager->journalOff > 0 );
+      rc = writeJournalHdr(pPager);
+      if( rc!=0 ){
+        return rc;
+      }
+    }
+    pPg = pPager->pFirst;
+  }
+  if( pPg==0 ){
+    return SQLITE_OK;
+  }
+
+  assert( pPg->nRef==0 );
+
+  /* Write the page to the database file if it is dirty.
+  */
+  if( pPg->dirty ){
+    int rc;
+    assert( pPg->needSync==0 );
+    pPg->pDirty = 0;
+    rc = pager_write_pagelist( pPg );
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+  }
+  assert( pPg->dirty==0 );
+
+  /* If the page we are recycling is marked as alwaysRollback, then
+  ** set the global alwaysRollback flag, thus disabling the
+  ** sqlite_dont_rollback() optimization for the rest of this transaction.
+  ** It is necessary to do this because the page marked alwaysRollback
+  ** might be reloaded at a later time but at that point we won't remember
+  ** that is was marked alwaysRollback.  This means that all pages must
+  ** be marked as alwaysRollback from here on out.
+  */
+  if( pPg->alwaysRollback ){
+    pPager->alwaysRollback = 1;
+  }
+
+  /* Unlink the old page from the free list and the hash table
+  */
+  unlinkPage(pPg);
+  TEST_INCR(pPager->nOvfl);
+
+  *ppPg = pPg;
+  return SQLITE_OK;
+}
+
+/*
+** This function is called to free superfluous dynamically allocated memory
+** held by the pager system. Memory in use by any SQLite pager allocated
+** by the current thread may be sqliteFree()ed.
+**
+** nReq is the number of bytes of memory required. Once this much has
+** been released, the function returns. A negative value for nReq means
+** free as much memory as possible. The return value is the total number 
+** of bytes of memory released.
+*/
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+int sqlite3pager_release_memory(int nReq){
+  const ThreadData *pTsdro = sqlite3ThreadDataReadOnly();
+  Pager *p;
+  int nReleased = 0;
+  int i;
+
+  /* If the the global mutex is held, this subroutine becomes a
+  ** o-op; zero bytes of memory are freed.  This is because
+  ** some of the code invoked by this function may also
+  ** try to obtain the mutex, resulting in a deadlock.
+  */
+  if( sqlite3OsInMutex(0) ){
+    return 0;
+  }
+
+  /* Outermost loop runs for at most two iterations. First iteration we
+  ** try to find memory that can be released without calling fsync(). Second
+  ** iteration (which only runs if the first failed to free nReq bytes of
+  ** memory) is permitted to call fsync(). This is of course much more 
+  ** expensive.
+  */
+  for(i=0; i<=1; i++){
+
+    /* Loop through all the SQLite pagers opened by the current thread. */
+    for(p=pTsdro->pPager; p && (nReq<0 || nReleased<nReq); p=p->pNext){
+      PgHdr *pPg;
+      int rc;
+
+      /* For each pager, try to free as many pages as possible (without 
+      ** calling fsync() if this is the first iteration of the outermost 
+      ** loop).
+      */
+      while( SQLITE_OK==(rc = pager_recycle(p, i, &pPg)) && pPg) {
+        /* We've found a page to free. At this point the page has been 
+        ** removed from the page hash-table, free-list and synced-list 
+        ** (pFirstSynced). It is still in the all pages (pAll) list. 
+        ** Remove it from this list before freeing.
+        **
+        ** Todo: Check the Pager.pStmt list to make sure this is Ok. It 
+        ** probably is though.
+        */
+        PgHdr *pTmp;
+        assert( pPg );
+        page_remove_from_stmt_list(pPg);
+        if( pPg==p->pAll ){
+           p->pAll = pPg->pNextAll;
+        }else{
+          for( pTmp=p->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
+          pTmp->pNextAll = pPg->pNextAll;
+        }
+        nReleased += sqliteAllocSize(pPg);
+        sqliteFree(pPg);
+      }
+
+      if( rc!=SQLITE_OK ){
+        /* An error occured whilst writing to the database file or 
+        ** journal in pager_recycle(). The error is not returned to the 
+        ** caller of this function. Instead, set the Pager.errCode variable.
+        ** The error will be returned to the user (or users, in the case 
+        ** of a shared pager cache) of the pager for which the error occured.
+        */
+        assert( rc==SQLITE_IOERR || rc==SQLITE_FULL );
+        assert( p->state>=PAGER_RESERVED );
+        pager_error(p, rc);
+      }
+    }
+  }
+
+  return nReleased;
+}
+#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
+
+/*
 ** Acquire a page.
 **
 ** A read lock on the disk file is obtained when the first page is acquired. 
@@ -2315,8 +2525,8 @@
   */ 
   assert( pPager!=0 );
   *ppPage = 0;
-  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
-    return pager_errcode(pPager);
+  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
+    return pPager->errCode;
   }
 
   /* If this is the first page accessed, then get a SHARED lock
@@ -2326,7 +2536,7 @@
     if( !pPager->noReadlock ){
       rc = pager_wait_on_lock(pPager, SHARED_LOCK);
       if( rc!=SQLITE_OK ){
-        return rc;
+        return pager_error(pPager, rc);
       }
     }
 
@@ -2334,8 +2544,6 @@
     ** database file, then it either needs to be played back or deleted.
     */
     if( hasHotJournal(pPager) ){
-       int rc;
-
        /* Get an EXCLUSIVE lock on the database file. At this point it is
        ** important that a RESERVED lock is not obtained on the way to the
        ** EXCLUSIVE lock. If it were, another process might open the
@@ -2347,11 +2555,11 @@
        ** second process will get to this point in the code and fail to
        ** obtain it's own EXCLUSIVE lock on the database file.
        */
-       rc = sqlite3OsLock(&pPager->fd, EXCLUSIVE_LOCK);
+       rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
        if( rc!=SQLITE_OK ){
-         sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+         sqlite3OsUnlock(pPager->fd, NO_LOCK);
          pPager->state = PAGER_UNLOCK;
-         return rc;
+         return pager_error(pPager, rc);
        }
        pPager->state = PAGER_EXCLUSIVE;
 
@@ -2365,7 +2573,7 @@
        */
        rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
        if( rc!=SQLITE_OK ){
-         sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+         sqlite3OsUnlock(pPager->fd, NO_LOCK);
          pPager->state = PAGER_UNLOCK;
          return SQLITE_BUSY;
        }
@@ -2380,7 +2588,7 @@
        */
        rc = pager_playback(pPager);
        if( rc!=SQLITE_OK ){
-         return rc;
+         return pager_error(pPager, rc);
        }
     }
     pPg = 0;
@@ -2401,7 +2609,6 @@
                               + sizeof(u32) + pPager->nExtra
                               + MEMDB*sizeof(PgHistory) );
       if( pPg==0 ){
-        pPager->errMask |= PAGER_ERR_MEM;
         return SQLITE_NOMEM;
       }
       memset(pPg, 0, sizeof(*pPg));
@@ -2417,70 +2624,11 @@
         pPager->nMaxPage++;
       }
     }else{
-      /* Find a page to recycle.  Try to locate a page that does not
-      ** require us to do an fsync() on the journal.
-      */
-      pPg = pPager->pFirstSynced;
-
-      /* If we could not find a page that does not require an fsync()
-      ** on the journal file then fsync the journal file.  This is a
-      ** very slow operation, so we work hard to avoid it.  But sometimes
-      ** it can't be helped.
-      */
-      if( pPg==0 ){
-        int rc = syncJournal(pPager);
-        if( rc!=0 ){
-          sqlite3pager_rollback(pPager);
-          return SQLITE_IOERR;
-        }
-        if( pPager->fullSync ){
-          /* If in full-sync mode, write a new journal header into the
-	  ** journal file. This is done to avoid ever modifying a journal
-	  ** header that is involved in the rollback of pages that have
-	  ** already been written to the database (in case the header is
-	  ** trashed when the nRec field is updated).
-          */
-          pPager->nRec = 0;
-          assert( pPager->journalOff > 0 );
-          rc = writeJournalHdr(pPager);
-          if( rc!=0 ){
-            sqlite3pager_rollback(pPager);
-            return SQLITE_IOERR;
-          }
-        }
-        pPg = pPager->pFirst;
+      rc = pager_recycle(pPager, 1, &pPg);
+      if( rc!=SQLITE_OK ){
+        return rc;
       }
-      assert( pPg->nRef==0 );
-
-      /* Write the page to the database file if it is dirty.
-      */
-      if( pPg->dirty ){
-        assert( pPg->needSync==0 );
-        pPg->pDirty = 0;
-        rc = pager_write_pagelist( pPg );
-        if( rc!=SQLITE_OK ){
-          sqlite3pager_rollback(pPager);
-          return SQLITE_IOERR;
-        }
-      }
-      assert( pPg->dirty==0 );
-
-      /* If the page we are recycling is marked as alwaysRollback, then
-      ** set the global alwaysRollback flag, thus disabling the
-      ** sqlite_dont_rollback() optimization for the rest of this transaction.
-      ** It is necessary to do this because the page marked alwaysRollback
-      ** might be reloaded at a later time but at that point we won't remember
-      ** that is was marked alwaysRollback.  This means that all pages must
-      ** be marked as alwaysRollback from here on out.
-      */
-      if( pPg->alwaysRollback ){
-        pPager->alwaysRollback = 1;
-      }
-
-      /* Unlink the old page from the free list and the hash table
-      */
-      unlinkPage(pPg);
-      TEST_INCR(pPager->nOvfl);
+      assert(pPg) ;
     }
     pPg->pgno = pgno;
     if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
@@ -2501,46 +2649,58 @@
     pPg->dirty = 0;
     pPg->nRef = 1;
     REFINFO(pPg);
+
     pPager->nRef++;
-    h = pager_hash(pgno);
-    pPg->pNextHash = pPager->aHash[h];
-    pPager->aHash[h] = pPg;
-    if( pPg->pNextHash ){
-      assert( pPg->pNextHash->pPrevHash==0 );
-      pPg->pNextHash->pPrevHash = pPg;
-    }
     if( pPager->nExtra>0 ){
       memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
     }
-    if( pPager->errMask!=0 ){
+    if( pPager->errCode ){
       sqlite3pager_unref(PGHDR_TO_DATA(pPg));
-      rc = pager_errcode(pPager);
+      rc = pPager->errCode;
       return rc;
     }
-    if( sqlite3pager_pagecount(pPager)<(int)pgno ){
+
+    /* Populate the page with data, either by reading from the database
+    ** file, or by setting the entire page to zero.
+    */
+    if( sqlite3pager_pagecount(pPager)<(int)pgno || MEMDB ){
       memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
     }else{
-      int rc;
       assert( MEMDB==0 );
-      rc = sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);
+      rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
       if( rc==SQLITE_OK ){
-        rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize);
+        rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg),
+                              pPager->pageSize);
       }
       TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
-      CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
+      CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
       if( rc!=SQLITE_OK ){
         i64 fileSize;
-        if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
-               || fileSize>=pgno*pPager->pageSize ){
+        int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
+        if( rc2!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){
+	  /* An IO error occured in one of the the sqlite3OsSeek() or
+          ** sqlite3OsRead() calls above. */
+          pPg->pgno = 0;
           sqlite3pager_unref(PGHDR_TO_DATA(pPg));
           return rc;
         }else{
+          clear_simulated_io_error();
           memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
         }
       }else{
         TEST_INCR(pPager->nRead);
       }
     }
+
+    /* Link the page into the page hash table */
+    h = pager_hash(pgno);
+    pPg->pNextHash = pPager->aHash[h];
+    pPager->aHash[h] = pPg;
+    if( pPg->pNextHash ){
+      assert( pPg->pNextHash->pPrevHash==0 );
+      pPg->pNextHash->pPrevHash = pPg;
+    }
+
 #ifdef SQLITE_CHECK_PAGES
     pPg->pageHash = pager_pagehash(pPg);
 #endif
@@ -2569,7 +2729,7 @@
 
   assert( pPager!=0 );
   assert( pgno!=0 );
-  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
+  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
     return 0;
   }
   pPg = pager_lookup(pPager, pgno);
@@ -2651,23 +2811,24 @@
     rc = SQLITE_NOMEM;
     goto failed_to_open_journal;
   }
-  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
+  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,
+                                 pPager->tempFile);
   pPager->journalOff = 0;
   pPager->setMaster = 0;
   pPager->journalHdr = 0;
   if( rc!=SQLITE_OK ){
     goto failed_to_open_journal;
   }
-  SET_FULLSYNC(pPager->jfd, pPager->fullSync);
-  SET_FULLSYNC(pPager->fd, pPager->fullSync);
-  sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd);
+  sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync);
+  sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync);
+  sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory);
   pPager->journalOpen = 1;
   pPager->journalStarted = 0;
   pPager->needSync = 0;
   pPager->alwaysRollback = 0;
   pPager->nRec = 0;
-  if( pPager->errMask!=0 ){
-    rc = pager_errcode(pPager);
+  if( pPager->errCode ){
+    rc = pPager->errCode;
     goto failed_to_open_journal;
   }
   pPager->origDbSize = pPager->dbSize;
@@ -2677,7 +2838,7 @@
   if( pPager->stmtAutoopen && rc==SQLITE_OK ){
     rc = sqlite3pager_stmt_begin(pPager);
   }
-  if( rc!=SQLITE_OK ){
+  if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
     rc = pager_unwritelock(pPager);
     if( rc==SQLITE_OK ){
       rc = SQLITE_FULL;
@@ -2688,8 +2849,17 @@
 failed_to_open_journal:
   sqliteFree(pPager->aInJournal);
   pPager->aInJournal = 0;
-  sqlite3OsUnlock(&pPager->fd, NO_LOCK);
-  pPager->state = PAGER_UNLOCK;
+  if( rc==SQLITE_NOMEM ){
+    /* If this was a malloc() failure, then we will not be closing the pager
+    ** file. So delete any journal file we may have just created. Otherwise,
+    ** the system will get confused, we have a read-lock on the file and a
+    ** mysterious journal has appeared in the filesystem.
+    */
+    sqlite3OsDelete(pPager->zJournal);
+  }else{
+    sqlite3OsUnlock(pPager->fd, NO_LOCK);
+    pPager->state = PAGER_UNLOCK;
+  }
   return rc;
 }
 
@@ -2732,7 +2902,7 @@
       pPager->state = PAGER_EXCLUSIVE;
       pPager->origDbSize = pPager->dbSize;
     }else{
-      rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK);
+      rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
       if( rc==SQLITE_OK ){
         pPager->state = PAGER_RESERVED;
         if( exFlag ){
@@ -2776,8 +2946,8 @@
 
   /* Check for errors
   */
-  if( pPager->errMask ){ 
-    return pager_errcode(pPager);
+  if( pPager->errCode ){ 
+    return pPager->errCode;
   }
   if( pPager->readOnly ){
     return SQLITE_PERM;
@@ -2822,7 +2992,6 @@
     if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
       if( (int)pPg->pgno <= pPager->origDbSize ){
         int szPg;
-        u32 saved;
         if( MEMDB ){
           PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
           TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
@@ -2832,28 +3001,33 @@
             memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
           }
         }else{
-          u32 cksum;
+          u32 cksum, saved;
+          char *pData2, *pEnd;
           /* We should never write to the journal file the page that
           ** contains the database locks.  The following assert verifies
           ** that we do not. */
           assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
-          CODEC(pPager, pData, pPg->pgno, 7);
-          cksum = pager_cksum(pPager, pPg->pgno, pData);
-          saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
-          store32bits(cksum, pPg, pPager->pageSize);
+          pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
+          cksum = pager_cksum(pPager, (u8*)pData2);
+          pEnd = pData2 + pPager->pageSize;
+          pData2 -= 4;
+          saved = *(u32*)pEnd;
+          put32bits(pEnd, cksum);
           szPg = pPager->pageSize+8;
-          store32bits(pPg->pgno, pPg, -4);
-          rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
+          put32bits(pData2, pPg->pgno);
+          rc = sqlite3OsWrite(pPager->jfd, pData2, szPg);
           pPager->journalOff += szPg;
           TRACE4("JOURNAL %d page %d needSync=%d\n",
                   PAGERID(pPager), pPg->pgno, pPg->needSync);
-          CODEC(pPager, pData, pPg->pgno, 0);
-          *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
+          *(u32*)pEnd = saved;
+
+	  /* An error has occured writing to the journal file. The 
+          ** transaction will be rolled back by the layer above.
+          */
           if( rc!=SQLITE_OK ){
-            sqlite3pager_rollback(pPager);
-            pPager->errMask |= PAGER_ERR_FULL;
             return rc;
           }
+
           pPager->nRec++;
           assert( pPager->aInJournal!=0 );
           pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
@@ -2890,14 +3064,11 @@
         }
         TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
       }else{
-        store32bits(pPg->pgno, pPg, -4);
-        CODEC(pPager, pData, pPg->pgno, 7);
-        rc = sqlite3OsWrite(&pPager->stfd,((char*)pData)-4, pPager->pageSize+4);
+        char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7)-4;
+        put32bits(pData2, pPg->pgno);
+        rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize+4);
         TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
-        CODEC(pPager, pData, pPg->pgno, 0);
         if( rc!=SQLITE_OK ){
-          sqlite3pager_rollback(pPager);
-          pPager->errMask |= PAGER_ERR_FULL;
           return rc;
         }
         pPager->stmtNRec++;
@@ -2924,10 +3095,12 @@
 ** to sqlite3pager_write().  In other words, return TRUE if it is ok
 ** to change the content of the page.
 */
+#ifndef NDEBUG
 int sqlite3pager_iswriteable(void *pData){
   PgHdr *pPg = DATA_TO_PGHDR(pData);
   return pPg->dirty;
 }
+#endif
 
 #ifndef SQLITE_OMIT_VACUUM
 /*
@@ -2980,8 +3153,9 @@
   if( MEMDB ) return;
 
   pPg = pager_lookup(pPager, pgno);
+  assert( pPg!=0 );  /* We never call _dont_write unless the page is in mem */
   pPg->alwaysRollback = 1;
-  if( pPg && pPg->dirty ){
+  if( pPg->dirty && !pPager->stmtInUse ){
     if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
       /* If this pages is the last page in the file and the file has grown
       ** during the current transaction, then do NOT mark the page as clean.
@@ -3057,17 +3231,9 @@
   int rc;
   PgHdr *pPg;
 
-  if( pPager->errMask==PAGER_ERR_FULL ){
-    rc = sqlite3pager_rollback(pPager);
-    if( rc==SQLITE_OK ){
-      rc = SQLITE_FULL;
-    }
-    return rc;
+  if( pPager->errCode ){
+    return pPager->errCode;
   }
-  if( pPager->errMask!=0 ){
-    rc = pager_errcode(pPager);
-    return rc;
-  }
   if( pPager->state<PAGER_RESERVED ){
     return SQLITE_ERROR;
   }
@@ -3079,6 +3245,7 @@
       pPg->dirty = 0;
       pPg->inJournal = 0;
       pPg->inStmt = 0;
+      pPg->needSync = 0;
       pPg->pPrevStmt = pPg->pNextStmt = 0;
       pPg = pPg->pDirty;
     }
@@ -3104,18 +3271,11 @@
   }
   assert( pPager->journalOpen );
   rc = sqlite3pager_sync(pPager, 0, 0);
-  if( rc!=SQLITE_OK ){
-    goto commit_abort;
+  if( rc==SQLITE_OK ){
+    rc = pager_unwritelock(pPager);
+    pPager->dbSize = -1;
   }
-  rc = pager_unwritelock(pPager);
-  pPager->dbSize = -1;
   return rc;
-
-  /* Jump here if anything goes wrong during the commit process.
-  */
-commit_abort:
-  sqlite3pager_rollback(pPager);
-  return rc;
 }
 
 /*
@@ -3176,11 +3336,11 @@
     return rc;
   }
 
-  if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
+  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
     if( pPager->state>=PAGER_EXCLUSIVE ){
       pager_playback(pPager);
     }
-    return pager_errcode(pPager);
+    return pPager->errCode;
   }
   if( pPager->state==PAGER_RESERVED ){
     int rc2;
@@ -3192,12 +3352,13 @@
   }else{
     rc = pager_playback(pPager);
   }
-  if( rc!=SQLITE_OK ){
-    rc = SQLITE_CORRUPT_BKPT;
-    pPager->errMask |= PAGER_ERR_CORRUPT;
-  }
   pPager->dbSize = -1;
-  return rc;
+
+  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
+  ** cache. So call pager_error() on the way out to make any error 
+  ** persistent.
+  */
+  return pager_error(pPager, rc);
 }
 
 /*
@@ -3218,7 +3379,7 @@
   a[2] = pPager->mxPage;
   a[3] = pPager->dbSize;
   a[4] = pPager->state;
-  a[5] = pPager->errMask;
+  a[5] = pPager->errCode;
 #ifdef SQLITE_TEST
   a[6] = pPager->nHit;
   a[7] = pPager->nMiss;
@@ -3254,11 +3415,11 @@
   assert( pPager->journalOpen );
   pPager->aInStmt = sqliteMalloc( pPager->dbSize/8 + 1 );
   if( pPager->aInStmt==0 ){
-    sqlite3OsLock(&pPager->fd, SHARED_LOCK);
+    /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */
     return SQLITE_NOMEM;
   }
 #ifndef NDEBUG
-  rc = sqlite3OsFileSize(&pPager->jfd, &pPager->stmtJSize);
+  rc = sqlite3OsFileSize(pPager->jfd, &pPager->stmtJSize);
   if( rc ) goto stmt_begin_failed;
   assert( pPager->stmtJSize == pPager->journalOff );
 #endif
@@ -3291,8 +3452,8 @@
     PgHdr *pPg, *pNext;
     TRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
     if( !MEMDB ){
-      sqlite3OsSeek(&pPager->stfd, 0);
-      /* sqlite3OsTruncate(&pPager->stfd, 0); */
+      sqlite3OsSeek(pPager->stfd, 0);
+      /* sqlite3OsTruncate(pPager->stfd, 0); */
       sqliteFree( pPager->aInStmt );
       pPager->aInStmt = 0;
     }
@@ -3380,7 +3541,7 @@
 */
 void sqlite3pager_set_codec(
   Pager *pPager,
-  void (*xCodec)(void*,void*,Pgno,int),
+  void *(*xCodec)(void*,void*,Pgno,int),
   void *pCodecArg
 ){
   pPager->xCodec = xCodec;
@@ -3409,7 +3570,7 @@
 
   /* Increment the value just read and write it back to byte 24. */
   change_counter++;
-  store32bits(change_counter, pPgHdr, 24);
+  put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
 
   /* Release the page reference. */
   sqlite3pager_unref(pPage);
@@ -3495,10 +3656,12 @@
 
     /* Sync the database file. */
     if( !pPager->noSync ){
-      rc = sqlite3OsSync(&pPager->fd, 0);
+      rc = sqlite3OsSync(pPager->fd, 0);
     }
 
     pPager->state = PAGER_SYNCED;
+  }else if( MEMDB && nTrunc!=0 ){
+    rc = sqlite3pager_truncate(pPager, nTrunc);
   }
 
 sync_exit:
@@ -3609,11 +3772,7 @@
 ** PENDING_LOCK, or EXCLUSIVE_LOCK.
 */
 int sqlite3pager_lockstate(Pager *pPager){
-#ifdef OS_TEST
-  return pPager->fd->fd.locktype;
-#else
-  return pPager->fd.locktype;
-#endif
+  return sqlite3OsLockState(pPager->fd);
 }
 #endif
 

Modified: packages/libdbd-sqlite3-perl/trunk/pager.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/pager.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/pager.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -13,9 +13,12 @@
 ** subsystem.  The page cache subsystem reads and writes a file a page
 ** at a time and provides a journal for rollback.
 **
-** @(#) $Id: pager.h,v 1.46 2005/09/19 19:05:21 drh Exp $
+** @(#) $Id: pager.h,v 1.50 2006/03/06 18:23:17 drh Exp $
 */
 
+#ifndef _PAGER_H_
+#define _PAGER_H_
+
 /*
 ** The default size of a database page.
 */
@@ -96,15 +99,16 @@
 void sqlite3pager_dont_rollback(void*);
 void sqlite3pager_dont_write(Pager*, Pgno);
 int *sqlite3pager_stats(Pager*);
-void sqlite3pager_set_safety_level(Pager*,int);
+void sqlite3pager_set_safety_level(Pager*,int,int);
 const char *sqlite3pager_filename(Pager*);
 const char *sqlite3pager_dirname(Pager*);
 const char *sqlite3pager_journalname(Pager*);
 int sqlite3pager_nosync(Pager*);
 int sqlite3pager_rename(Pager*, const char *zNewName);
-void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
+void sqlite3pager_set_codec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
 int sqlite3pager_movepage(Pager*,void*,Pgno);
 int sqlite3pager_reset(Pager*);
+int sqlite3pager_release_memory(int);
 
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
 int sqlite3pager_lockstate(Pager*);
@@ -114,3 +118,5 @@
 void sqlite3pager_refdump(Pager*);
 int pager3_refinfo_enable;
 #endif
+
+#endif /* _PAGER_H_ */

Modified: packages/libdbd-sqlite3-perl/trunk/parse.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/parse.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/parse.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -4,7 +4,7 @@
 /* First off, code is include which follows the "include" declaration
 ** in the input file. */
 #include <stdio.h>
-#line 51 "parse.y"
+#line 54 "parse.y"
 
 #include "sqliteInt.h"
 #include "parse.h"
@@ -23,7 +23,7 @@
 ** GLOB, NOT LIKE, and NOT GLOB operators.
 */
 struct LikeOp {
-  Token operator;  /* "like" or "glob" or "regexp" */
+  Token eOperator;  /* "like" or "glob" or "regexp" */
   int not;         /* True if the NOT keyword is present */
 };
 
@@ -93,35 +93,35 @@
 **                       defined, then do no error processing.
 */
 #define YYCODETYPE unsigned char
-#define YYNOCODE 247
+#define YYNOCODE 240
 #define YYACTIONTYPE unsigned short int
 #define sqlite3ParserTOKENTYPE Token
 typedef union {
   sqlite3ParserTOKENTYPE yy0;
-  struct TrigEvent yy30;
-  Expr* yy62;
-  SrcList* yy151;
-  Token yy198;
-  struct LimitVal yy220;
-  struct LikeOp yy222;
-  IdList* yy240;
-  int yy280;
-  struct {int value; int mask;} yy359;
-  TriggerStep* yy360;
-  struct AttachKey yy361;
-  Select* yy375;
-  ExprList* yy418;
-  int yy493;
+  struct {int value; int mask;} yy13;
+  struct TrigEvent yy132;
+  IdList* yy160;
+  Expr* yy178;
+  int yy230;
+  Select* yy239;
+  TriggerStep* yy247;
+  struct LimitVal yy270;
+  SrcList* yy285;
+  Expr * yy292;
+  Token yy384;
+  struct LikeOp yy440;
+  ExprList* yy462;
+  int yy479;
 } YYMINORTYPE;
 #define YYSTACKDEPTH 100
 #define sqlite3ParserARG_SDECL Parse *pParse;
 #define sqlite3ParserARG_PDECL ,Parse *pParse
 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 581
-#define YYNRULE 311
-#define YYERRORSYMBOL 146
-#define YYERRSYMDT yy493
+#define YYNSTATE 559
+#define YYNRULE 295
+#define YYERRORSYMBOL 137
+#define YYERRSYMDT yy479
 #define YYFALLBACK 1
 #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
 #define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
@@ -175,497 +175,399 @@
 **  yy_default[]       Default action for each state.
 */
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   286,  113,  113,  140,  142,  138,  144,  707,  150,  152,
- /*    10 */   154,  156,  158,  160,  162,  164,  166,  168,  120,  122,
- /*    20 */   123,  170,  178,  150,  152,  154,  156,  158,  160,  162,
- /*    30 */   164,  166,  168,  158,  160,  162,  164,  166,  168,  135,
- /*    40 */    97,  171,  181,  186,  191,  180,  185,  146,  148,  140,
- /*    50 */   142,  138,  144,   51,  150,  152,  154,  156,  158,  160,
- /*    60 */   162,  164,  166,  168,  861,   72,  114,  114,  565,  248,
- /*    70 */   150,  152,  154,  156,  158,  160,  162,  164,  166,  168,
- /*    80 */   124,   37,  362,   40,   59,   67,   69,  326,  357,  170,
- /*    90 */   374,  126,  127,   95,  195,  359,  197,  198,  575,   33,
- /*   100 */   288,  176,   51,  187,  192,  555,  302,  135,   97,  171,
- /*   110 */   181,  186,  191,  180,  185,  146,  148,  140,  142,  138,
- /*   120 */   144,  324,  150,  152,  154,  156,  158,  160,  162,  164,
- /*   130 */   166,  168,   40,   59,   67,   69,  326,  357,  311,   80,
- /*   140 */   250,  316,   34,  170,  359,  132,  373,  115,  661,  818,
- /*   150 */   376,  303,  283,  318,  411,  176,  304,  187,  192,  614,
- /*   160 */   680,  135,   97,  171,  181,  186,  191,  180,  185,  146,
- /*   170 */   148,  140,  142,  138,  144,  170,  150,  152,  154,  156,
- /*   180 */   158,  160,  162,  164,  166,  168,  862,   80,  433,  162,
- /*   190 */   164,  166,  168,  135,   97,  171,  181,  186,  191,  180,
- /*   200 */   185,  146,  148,  140,  142,  138,  144,  296,  150,  152,
- /*   210 */   154,  156,  158,  160,  162,  164,  166,  168,  378,  212,
- /*   220 */   170,  380,  387,  392,  817,  437,  438,  374,  195,   39,
- /*   230 */   197,  198,   28,  395,  136,  409,   33,  356,  135,   97,
- /*   240 */   171,  181,  186,  191,  180,  185,  146,  148,  140,  142,
- /*   250 */   138,  144,  170,  150,  152,  154,  156,  158,  160,  162,
- /*   260 */   164,  166,  168,  195,  369,  197,  198,  219,   98,  231,
- /*   270 */   135,   97,  171,  181,  186,  191,  180,  185,  146,  148,
- /*   280 */   140,  142,  138,  144,  857,  150,  152,  154,  156,  158,
- /*   290 */   160,  162,  164,  166,  168,  170,  176,  246,  187,  192,
- /*   300 */    74,  104,  105,  106,   73,   13,  195,  864,  197,  198,
- /*   310 */    16,   17,   18,  135,   97,  171,  181,  186,  191,  180,
- /*   320 */   185,  146,  148,  140,  142,  138,  144,  170,  150,  152,
- /*   330 */   154,  156,  158,  160,  162,  164,  166,  168,  893,    1,
- /*   340 */   580,  740,  467,    4,  567,  135,   97,  171,  181,  186,
- /*   350 */   191,  180,  185,  146,  148,  140,  142,  138,  144,  478,
- /*   360 */   150,  152,  154,  156,  158,  160,  162,  164,  166,  168,
- /*   370 */    14,   15,  378,  581,  374,  380,  387,  392,  506,  366,
- /*   380 */   540,   48,   32,   33,    3,  577,  235,  395,   13,   99,
- /*   390 */    49,   99,  193,  501,  473,  463,   13,  542,  543,  196,
- /*   400 */   372,  170,  685,   50,   84,   46,  375,  408,  428,  363,
- /*   410 */    78,  260,   78,  200,  512,   47,  508,   91,  221,  135,
- /*   420 */    97,  171,  181,  186,  191,  180,  185,  146,  148,  140,
- /*   430 */   142,  138,  144,  837,  150,  152,  154,  156,  158,  160,
- /*   440 */   162,  164,  166,  168,  130,  128,  390,  568,  348,  252,
- /*   450 */   261,  170,  378,   14,   15,  380,  387,  392,  124,  269,
- /*   460 */   428,   14,   15,  399,  541,  348,  240,  395,  569,  135,
- /*   470 */    97,  171,  181,  186,  191,  180,  185,  146,  148,  140,
- /*   480 */   142,  138,  144,   99,  150,  152,  154,  156,  158,  160,
- /*   490 */   162,  164,  166,  168,  834,   99,  510,  572,   13,  507,
- /*   500 */   413,  170,  406,  330,   78,  200,    6,    5,   42,  405,
- /*   510 */   836,  364,   25,   13,  394,  258,   78,  260,  514,  135,
- /*   520 */    97,  171,  181,  186,  191,  180,  185,  146,  148,  140,
- /*   530 */   142,  138,  144,  606,  150,  152,  154,  156,  158,  160,
- /*   540 */   162,  164,  166,  168,  428,   99,  268,  391,  889,  883,
- /*   550 */   136,   80,   81,  112,  421,  841,  254,  538,  241,  176,
- /*   560 */    99,  187,  192,   14,   15,  682,   78,  317,   13,  331,
- /*   570 */   544,  367,  370,  449,  170,  867,  525,  460,   14,   15,
- /*   580 */   369,   78,  200,  430,   98,   80,  570,   80,  404,  877,
- /*   590 */   278,  819,  135,   97,  171,  181,  186,  191,  180,  185,
- /*   600 */   146,  148,  140,  142,  138,  144,   99,  150,  152,  154,
- /*   610 */   156,  158,  160,  162,  164,  166,  168,  104,  105,  106,
- /*   620 */   539,   13,  442,  319,  170,  333,  709,   78,  500,  553,
- /*   630 */   359,   36,  361,   14,   15,  241,  195,  592,  197,  198,
- /*   640 */   356,  271,  135,   97,  171,  181,  186,  191,  180,  185,
- /*   650 */   146,  148,  140,  142,  138,  144,   13,  150,  152,  154,
- /*   660 */   156,  158,  160,  162,  164,  166,  168,   99,  195,   99,
- /*   670 */   197,  198,  746,  496,  170,   13,  856,  243,  195,  315,
- /*   680 */   197,  198,  537,  334,  341,  343,   14,   15,   78,  500,
- /*   690 */    78,  206,  135,  189,  171,  181,  186,  191,  180,  185,
- /*   700 */   146,  148,  140,  142,  138,  144,  172,  150,  152,  154,
- /*   710 */   156,  158,  160,  162,  164,  166,  168,   99,  243,  301,
- /*   720 */    13,   14,   15,   13,  170,  439,  441,  440,  174,  175,
- /*   730 */   117,  122,  123,  272,  532,  132,  133,  115,   78,  234,
- /*   740 */    14,   15,  183,   97,  171,  181,  186,  191,  180,  185,
- /*   750 */   146,  148,  140,  142,  138,  144,  173,  150,  152,  154,
- /*   760 */   156,  158,  160,  162,  164,  166,  168,  280,  869,  709,
- /*   770 */   448,  885,  182,  462,  170,  195,  298,  197,  198,  199,
- /*   780 */   464,  288,  708,  243,  275,   14,   15,  428,   14,   15,
- /*   790 */    13,  321,  124,  352,  171,  181,  186,  191,  180,  185,
- /*   800 */   146,  148,  140,  142,  138,  144,   80,  150,  152,  154,
- /*   810 */   156,  158,  160,  162,  164,  166,  168,   99,   74,  289,
- /*   820 */    99,   79,   73,   99,  194,   71,  509,  346,  462,  591,
- /*   830 */   643,  486,  348,  109,   11,  443,   79,   99,   78,  200,
- /*   840 */    71,   78,  232,  674,   78,  214,  459,  472,  109,  428,
- /*   850 */   223,  277,  470,  571,   48,   14,   15,   80,   78,  208,
- /*   860 */   136,   80,   99,   49,  201,  223,  195,  709,  197,  198,
- /*   870 */   353,  195,  428,  197,  198,  136,   50,  276,  225,  201,
- /*   880 */   237,  207,  205,   78,   94,  352,  486,  827,  511,  203,
- /*   890 */    76,   77,  241,   86,   98,  215,  207,  205,  312,   99,
- /*   900 */   309,   99,  468,   99,  203,   76,   77,  470,   64,   98,
- /*   910 */   457,  513,  348,   84,   99,  576,   99,  352,  352,  383,
- /*   920 */    78,  161,   78,  145,   78,  222,  483,  104,  105,  106,
- /*   930 */   107,  108,  209,  213,   99,   78,  220,   78,  163,  533,
- /*   940 */   339,  497,  104,  105,  106,  107,  108,  209,  213,   99,
- /*   950 */   672,  389,  398,   99,   79,   78,  143,   99,   71,  493,
- /*   960 */   340,  445,  353,   99,  428,  444,  109,   99,  740,   79,
- /*   970 */    78,  165,  352,   71,   78,  167,  243,  446,   78,  393,
- /*   980 */    99,  109,  116,  223,   78,  141,  113,  887,   78,  169,
- /*   990 */   477,  275,   80,  136,  353,  353,   99,  201,  223,  465,
- /*  1000 */    45,   78,  323,  517,   99,  414,  456,  491,  136,  296,
- /*  1010 */    99,   84,  201,  336,  207,  205,   52,   78,  139,  573,
- /*  1020 */    44,   45,  203,   76,   77,   78,  137,   98,   54,  207,
- /*  1030 */   205,   78,  177,   99,  286,   99,  113,  203,   76,   77,
- /*  1040 */   298,  422,   98,  417,  428,   42,  499,   99,  497,  353,
- /*  1050 */   313,  114,   99,  835,   78,  147,   78,  151,  277,  428,
- /*  1060 */   104,  105,  106,  107,  108,  209,  213,  820,   78,  149,
- /*  1070 */    99,   78,  310,   78,  179,  104,  105,  106,  107,  108,
- /*  1080 */   209,  213,    8,  521,  276,   99,  269,   19,   21,   23,
- /*  1090 */   412,   78,  434,   99,    3,  577,   99,   65,  527,  490,
- /*  1100 */   563,  114,  547,   99,   66,   99,   78,  300,  483,  557,
- /*  1110 */    99,  574,  113,   99,   78,  153,   99,   78,  188,   99,
- /*  1120 */   535,  536,   99,  467,   78,  190,   78,  365,  534,   99,
- /*  1130 */   560,   78,  111,  566,   78,  270,  266,   78,  155,   99,
- /*  1140 */    78,  265,   99,   78,  481,   99,   84,   99,  888,   99,
- /*  1150 */    78,  249,   84,  529,  238,  211,  239,   99,  298,  494,
- /*  1160 */    78,  485,   99,   78,  157,  530,   78,  247,   78,  202,
- /*  1170 */    78,  498,  523,   99,  515,  519,  463,  114,   78,   96,
- /*  1180 */   505,   99,  288,   78,  204,   84,   80,   27,   80,  410,
- /*  1190 */   273,  283,  130,  128,   78,  159,  660,  118,   31,  119,
- /*  1200 */   331,  352,   78,  236,   57,   58,  295,    2,  296,  320,
- /*  1210 */     4,  239,  338,  337,  745,  578,  347,  294,  348,  210,
- /*  1220 */   306,  531,  579,   82,  224,   93,  528,   42,  227,   92,
- /*  1230 */   598,  226,   12,  489,  228,  229,   88,  230,  526,  742,
- /*  1240 */   524,  522,  520,  464,  739,  518,  269,  516,  875,  833,
- /*  1250 */   681,   87,  679,  168,  868,  504,  333,  503,  866,  502,
- /*  1260 */   495,  342,  245,   22,  492,  244,  100,  599,  101,  102,
- /*  1270 */   488,  487,   20,  484,  688,  865,  251,  593,  349,  253,
- /*  1280 */   479,   85,  480,  687,  257,  482,  255,  388,  103,  258,
- /*  1290 */   256,  259,  600,   24,  386,  584,  476,  475,  262,  263,
- /*  1300 */    26,  601,  686,  474,  344,  385,  863,  471,  267,  848,
- /*  1310 */   469,  239,   53,  466,  242,  748,  384,  110,  747,  461,
- /*  1320 */   826,  825,  458,   83,  453,  455,  279,  454,  281,  382,
- /*  1330 */    56,   55,  274,  282,  452,   29,  451,  381,  450,  447,
- /*  1340 */   290,  299,  377,  292,   30,  284,  291,  287,  293,    7,
- /*  1350 */   285,  407,   43,  121,  379,  855,  355,  605,   60,  184,
- /*  1360 */   854,  436,  131,  849,  297,  350,  616,  305,  435,  432,
- /*  1370 */   307,  431,  314,  429,  427,  308,   64,  425,   41,  358,
- /*  1380 */   351,  424,  423,  420,  419,  426,  125,  129,  322,  416,
- /*  1390 */    35,  418,   61,   62,  134,  415,   63,  371,  345,  368,
- /*  1400 */   327,    9,   70,  360,  325,  590,  332,   68,  615,   10,
- /*  1410 */   556,   54,  328,   38,  329,  400,  550,  840,  546,  397,
- /*  1420 */   401,  876,  264,  878,  879,  551,  330,  839,  545,  882,
- /*  1430 */   218,  233,  838,  396,  884,  559,  886,  549,  335,  403,
- /*  1440 */   559,   75,  554,  559,  402,  559,  559,  559,  561,  559,
- /*  1450 */   559,  559,  559,  562,  559,  559,  564,  559,  559,  559,
- /*  1460 */   559,  559,  559,  559,  559,  559,  559,  559,  559,  559,
- /*  1470 */   559,  559,  559,  559,  559,  559,  559,  559,  559,  354,
- /*  1480 */    89,  559,  559,  559,  559,  559,  559,  559,  559,  559,
- /*  1490 */   559,  559,  559,  559,  559,  559,  559,  559,  559,   90,
- /*  1500 */   559,  559,  559,  216,  559,  217,  559,  559,  559,  548,
- /*  1510 */   559,  559,  559,  559,  559,  552,  559,  559,  559,  558,
+ /*     0 */   279,  855,  125,  370,  442,  171,    2,  377,   88,   88,
+ /*    10 */    88,   88,  298,   86,   86,   86,   86,   85,   85,   84,
+ /*    20 */    84,   84,   83,  525,  523,  522,  392,   81,   86,   86,
+ /*    30 */    86,   86,   85,   85,   84,   84,   84,   83,   82,  427,
+ /*    40 */    80,  146,  187,   89,   55,  297,  402,  404,  399,  399,
+ /*    50 */    87,   87,   88,   88,   88,   88,  202,   86,   86,   86,
+ /*    60 */    86,   85,   85,   84,   84,   84,   83,  279,  298,  151,
+ /*    70 */   377,  389,  475,   69,   86,   86,   86,   86,   85,   85,
+ /*    80 */    84,   84,   84,   83,  186,  114,  254,  362,  256,  328,
+ /*    90 */   155,  232,  398,  392,  529,  442,  403,   91,  231,  485,
+ /*   100 */   508,  323,  508,  375,   85,   85,   84,   84,   84,   83,
+ /*   110 */    89,   55,  297,  402,  404,  399,  399,   87,   87,   88,
+ /*   120 */    88,   88,   88,   83,   86,   86,   86,   86,   85,   85,
+ /*   130 */    84,   84,   84,   83,  279,  218,  372,  372,  372,  489,
+ /*   140 */   429,  145,  254,  362,  256,  328,  155,  232,  454,   22,
+ /*   150 */   529,  250,  428,  529,  231,  352,  549,  527,  526,  198,
+ /*   160 */   392,  208,  331,  337,  340,  422,  277,  302,  179,  387,
+ /*   170 */   488,  160,  144,  499,  345,  180,  350,   89,   55,  297,
+ /*   180 */   402,  404,  399,  399,   87,   87,   88,   88,   88,   88,
+ /*   190 */   189,   86,   86,   86,   86,   85,   85,   84,   84,   84,
+ /*   200 */    83,  486,  391,  518,  385,  200,  279,  198,  356,  457,
+ /*   210 */   331,  337,  340,  527,  526,  541,  527,  526,  551,  353,
+ /*   220 */   356,  510,  345,  356,  542,  509,  347,  365,  147,  282,
+ /*   230 */   397,   43,  392,  543,  544,    9,  484,  319,   17,  529,
+ /*   240 */   447,  517,  397,   37,  498,  397,   37,  168,   70,   89,
+ /*   250 */    55,  297,  402,  404,  399,  399,   87,   87,   88,   88,
+ /*   260 */    88,   88,  391,   86,   86,   86,   86,   85,   85,   84,
+ /*   270 */    84,   84,   83,  497,  464,  161,  490,  290,  279,  455,
+ /*   280 */   496,  391,  483,  360,  356,  299,  281,  410,  318,  356,
+ /*   290 */   304,  242,  236,  356,  409,  206,   82,  424,   80,  146,
+ /*   300 */   424,  202,  527,  526,  392,  260,  397,   46,  451,  391,
+ /*   310 */   398,  397,   37,  214,  403,  397,   43,  188,  416,  415,
+ /*   320 */    73,   89,   55,  297,  402,  404,  399,  399,   87,   87,
+ /*   330 */    88,   88,   88,   88,  307,   86,   86,   86,   86,   85,
+ /*   340 */    85,   84,   84,   84,   83,  279,  344,  274,  429,  460,
+ /*   350 */    82,  391,   80,  146,  291,  312,  343,  529,  413,  356,
+ /*   360 */   428,  317,  289,  190,  154,  314,  424,  152,  355,  284,
+ /*   370 */   548,  392,  529,  422,   82,  431,   80,  146,  342,  380,
+ /*   380 */   381,  397,   26,  180,  313,  430,  407,  407,   89,   55,
+ /*   390 */   297,  402,  404,  399,  399,   87,   87,   88,   88,   88,
+ /*   400 */    88,  391,   86,   86,   86,   86,   85,   85,   84,   84,
+ /*   410 */    84,   83,  279,  198,  458,  475,  331,  337,  340,  475,
+ /*   420 */   527,  526,   84,   84,   84,   83,  356,  529,  345,  385,
+ /*   430 */   200,  408,  393,  506,  507,  527,  526,  282,  392,  341,
+ /*   440 */    57,  206,  231,  313,  308,  407,  407,  444,  397,   46,
+ /*   450 */   292,  165,  395,  396,  212,   89,   55,  297,  402,  404,
+ /*   460 */   399,  399,   87,   87,   88,   88,   88,   88,  218,   86,
+ /*   470 */    86,   86,   86,   85,   85,   84,   84,   84,   83,  279,
+ /*   480 */   394,  356,  202,  463,    1,  356,  303,  489,  529,  226,
+ /*   490 */   527,  526,  348,  255,  244,  305,  500,   22,  244,  313,
+ /*   500 */   122,  407,  407,  397,   35,  392,  149,  397,   37,  227,
+ /*   510 */   286,  380,  381,  218,  397,    3,  313,  443,  407,  407,
+ /*   520 */   268,  377,   89,   55,  297,  402,  404,  399,  399,   87,
+ /*   530 */    87,   88,   88,   88,   88,  356,   86,   86,   86,   86,
+ /*   540 */    85,   85,   84,   84,   84,   83,  279,  356,  192,   67,
+ /*   550 */   252,  527,  526,  356,  366,  223,  356,  397,   53,  129,
+ /*   560 */   356,  273,  423,  356,  202,  356,  387,  330,  160,  397,
+ /*   570 */    48,  489,  392,  206,  411,  397,   38,  363,  397,   10,
+ /*   580 */   556,   22,  397,   24,  377,  397,   45,  397,   32,   89,
+ /*   590 */    55,  297,  402,  404,  399,  399,   87,   87,   88,   88,
+ /*   600 */    88,   88,  356,   86,   86,   86,   86,   85,   85,   84,
+ /*   610 */    84,   84,   83,  279,  356,  177,  173,  169,   58,  356,
+ /*   620 */   421,  356,   15,  356,  397,   34,  356,  473,  356,  122,
+ /*   630 */   356,  552,  356,  171,    2,  377,  397,   36,  215,  392,
+ /*   640 */   593,  397,   30,  397,   31,  397,   41,  261,  397,   42,
+ /*   650 */   397,   44,  397,   47,  397,   49,   89,   55,  297,  402,
+ /*   660 */   404,  399,  399,   87,   87,   88,   88,   88,   88,  356,
+ /*   670 */    86,   86,   86,   86,   85,   85,   84,   84,   84,   83,
+ /*   680 */   279,  356,  475,  475,  237,  109,  356,  378,  356,   20,
+ /*   690 */   356,  397,   27,  356,  559,  551,  353,  356,  377,  356,
+ /*   700 */   449,   21,  182,  397,   50,  377,  392,  336,  397,   33,
+ /*   710 */   397,   28,  397,  111,  238,  397,  113,  300,  295,  397,
+ /*   720 */    52,  397,   25,   89,   55,  297,  402,  404,  399,  399,
+ /*   730 */    87,   87,   88,   88,   88,   88,  356,   86,   86,   86,
+ /*   740 */    86,   85,   85,   84,   84,   84,   83,  279,  356,  475,
+ /*   750 */   383,  383,  356,  195,  356,  193,  356,  440,  397,   93,
+ /*   760 */   356,  244,  244,  451,  228,  356,  122,  539,  377,   60,
+ /*   770 */   397,   39,  439,  392,  397,   97,  397,   16,  397,  112,
+ /*   780 */   477,  400,  397,  110,  288,  468,  467,  397,  100,  218,
+ /*   790 */    89,   55,  297,  402,  404,  399,  399,   87,   87,   88,
+ /*   800 */    88,   88,   88,  356,   86,   86,   86,   86,   85,   85,
+ /*   810 */    84,   84,   84,   83,  279,  356,   19,  229,  139,  356,
+ /*   820 */   528,  356,   60,  356,  296,  397,   98,  356,  244,  240,
+ /*   830 */   222,  469,  356,  461,  512,   15,  451,  397,   94,  309,
+ /*   840 */   392,  397,   96,  397,   51,  397,   23,  141,  386,  397,
+ /*   850 */    40,  470,  163,  154,  397,   29,  441,   89,   79,  297,
+ /*   860 */   402,  404,  399,  399,   87,   87,   88,   88,   88,   88,
+ /*   870 */   447,   86,   86,   86,   86,   85,   85,   84,   84,   84,
+ /*   880 */    83,  279,  452,  480,   74,  267,   72,  364,  513,  122,
+ /*   890 */   122,  477,  524,  213,  182,  436,  432,  322,  309,  425,
+ /*   900 */    54,  472,  294,  181,  241,  209,  315,  392,  514,  269,
+ /*   910 */   515,  432,  311,  218,  218,  194,  218,  153,  218,  162,
+ /*   920 */   310,  218,  447,  253,  279,   55,  297,  402,  404,  399,
+ /*   930 */   399,   87,   87,   88,   88,   88,   88,  391,   86,   86,
+ /*   940 */    86,   86,   85,   85,   84,   84,   84,   83,  792,  391,
+ /*   950 */   392,  391,  306,  391,  535,  534,  446,  533,  487,  531,
+ /*   960 */   371,  270,  243,  471,  211,  266,  263,  481,  216,  297,
+ /*   970 */   402,  404,  399,  399,   87,   87,   88,   88,   88,   88,
+ /*   980 */   466,   86,   86,   86,   86,   85,   85,   84,   84,   84,
+ /*   990 */    83,   77,  359,  221,    4,  465,  450,  540,  283,  259,
+ /*  1000 */   538,  115,   77,  359,  555,    4,  326,  357,  235,  283,
+ /*  1010 */   197,   65,  265,    5,  329,  434,  247,  326,  384,  491,
+ /*  1020 */   140,  464,  382,  369,  358,  482,  521,  245,  474,  537,
+ /*  1030 */   476,  437,  230,  389,  369,  334,  390,  301,  128,  157,
+ /*  1040 */   433,  553,  339,  503,  389,  550,   59,  434,  435,  554,
+ /*  1050 */   389,   67,   75,   76,  456,   71,  207,  116,  257,  132,
+ /*  1060 */    77,  325,  321,   75,   76,  375,  411,  536,  412,  143,
+ /*  1070 */   142,   77,  325,  321,  220,  123,  375,  324,  485,  493,
+ /*  1080 */   420,  210,  375,  287,  271,  479,  185,  494,  478,   77,
+ /*  1090 */   359,  505,    4,  136,  546,  202,  283,  516,  372,  372,
+ /*  1100 */   372,  373,  374,   14,  326,  105,  278,  338,  156,  372,
+ /*  1110 */   372,  372,  373,  374,   14,  372,  372,  372,   63,  504,
+ /*  1120 */   316,  369,  419,  164,  225,  327,  239,  203,   68,  217,
+ /*  1130 */   520,  389,  196,  158,  201,  368,  453,  495,  438,  135,
+ /*  1140 */     8,  361,  405,  492,   90,  376,  285,  426,  124,  276,
+ /*  1150 */    75,   76,  557,   56,  104,  333,  530,  501,   77,  325,
+ /*  1160 */   321,   66,  251,  375,  191,  272,  320,  205,  126,  249,
+ /*  1170 */   234,  233,  106,  127,   18,  448,   99,   95,  246,  204,
+ /*  1180 */   532,  417,  170,  174,   11,  178,  418,  219,  167,  445,
+ /*  1190 */    61,   62,  121,  519,  262,  406,  372,  372,  372,  373,
+ /*  1200 */   374,   14,  275,  107,  159,   15,  184,  248,  517,  511,
+ /*  1210 */     6,  595,  182,  183,  120,  176,  594,  117,   92,   78,
+ /*  1220 */   332,  388,  293,  119,  102,  137,  258,  502,  401,  335,
+ /*  1230 */   108,    7,  172,   64,  240,  379,  101,  346,   12,  264,
+ /*  1240 */   148,  103,  547,  354,  349,  134,  558,  166,  545,  414,
+ /*  1250 */   138,  199,  462,  459,   13,  133,  175,  367,  224,  236,
+ /*  1260 */   131,  536,  130,  280,  150,  536,  536,  536,  202,  118,
+ /*  1270 */   536,  536,  536,  536,  536,  536,  536,  536,  536,  536,
+ /*  1280 */   536,  536,  536,  536,  536,  536,  536,  536,  536,  536,
+ /*  1290 */   536,  536,  351,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     0 */    28,   30,   30,   77,   78,   79,   80,   27,   82,   83,
- /*    10 */    84,   85,   86,   87,   88,   89,   90,   91,  171,  172,
- /*    20 */   173,   49,   81,   82,   83,   84,   85,   86,   87,   88,
- /*    30 */    89,   90,   91,   86,   87,   88,   89,   90,   91,   67,
- /*    40 */    68,   69,   70,   71,   72,   73,   74,   75,   76,   77,
- /*    50 */    78,   79,   80,   69,   82,   83,   84,   85,   86,   87,
- /*    60 */    88,   89,   90,   91,   15,   26,   95,   95,  159,   29,
- /*    70 */    82,   83,   84,   85,   86,   87,   88,   89,   90,   91,
- /*    80 */   233,   97,   98,   99,  100,  101,  102,  103,  104,   49,
- /*    90 */   155,  132,  133,   53,  114,  111,  116,  117,  163,  164,
- /*   100 */   168,  223,   69,  225,  226,  134,  162,   67,   68,   69,
- /*   110 */    70,   71,   72,   73,   74,   75,   76,   77,   78,   79,
- /*   120 */    80,   27,   82,   83,   84,   85,   86,   87,   88,   89,
- /*   130 */    90,   91,   99,  100,  101,  102,  103,  104,  206,  195,
- /*   140 */   124,   27,  165,   49,  111,  168,  169,  170,   27,   21,
- /*   150 */    29,  207,  208,   27,  162,  223,  212,  225,  226,  120,
- /*   160 */    11,   67,   68,   69,   70,   71,   72,   73,   74,   75,
- /*   170 */    76,   77,   78,   79,   80,   49,   82,   83,   84,   85,
- /*   180 */    86,   87,   88,   89,   90,   91,   15,  195,  139,   88,
- /*   190 */    89,   90,   91,   67,   68,   69,   70,   71,   72,   73,
- /*   200 */    74,   75,   76,   77,   78,   79,   80,   29,   82,   83,
- /*   210 */    84,   85,   86,   87,   88,   89,   90,   91,   97,   27,
- /*   220 */    49,  100,  101,  102,   21,   58,   59,  155,  114,  175,
- /*   230 */   116,  117,  160,  112,   65,  163,  164,  183,   67,   68,
- /*   240 */    69,   70,   71,   72,   73,   74,   75,   76,   77,   78,
- /*   250 */    79,   80,   49,   82,   83,   84,   85,   86,   87,   88,
- /*   260 */    89,   90,   91,  114,   95,  116,  117,  139,   99,  141,
- /*   270 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
- /*   280 */    77,   78,   79,   80,  106,   82,   83,   84,   85,   86,
- /*   290 */    87,   88,   89,   90,   91,   49,  223,  224,  225,  226,
- /*   300 */   115,  132,  133,  134,  119,   30,  114,   21,  116,  117,
- /*   310 */    17,   18,   19,   67,   68,   69,   70,   71,   72,   73,
- /*   320 */    74,   75,   76,   77,   78,   79,   80,   49,   82,   83,
- /*   330 */    84,   85,   86,   87,   88,   89,   90,   91,  147,  148,
- /*   340 */   149,   11,   56,  152,   24,   67,   68,   69,   70,   71,
- /*   350 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   29,
- /*   360 */    82,   83,   84,   85,   86,   87,   88,   89,   90,   91,
- /*   370 */    95,   96,   97,    0,  155,  100,  101,  102,   24,   27,
- /*   380 */   155,   22,  163,  164,   11,   12,  140,  112,   30,  155,
- /*   390 */    31,  155,   26,  107,  108,  109,   30,  172,  173,  115,
- /*   400 */   167,   49,  118,   44,  118,   46,  187,  188,  155,  176,
- /*   410 */   176,  177,  176,  177,   60,   56,   62,  203,  140,   67,
- /*   420 */    68,   69,   70,   71,   72,   73,   74,   75,   76,   77,
- /*   430 */    78,   79,   80,   11,   82,   83,   84,   85,   86,   87,
- /*   440 */    88,   89,   90,   91,   86,   87,   27,  194,   29,  215,
- /*   450 */   216,   49,   97,   95,   96,  100,  101,  102,  233,  129,
- /*   460 */   155,   95,   96,   27,  106,   29,  230,  112,   64,   67,
- /*   470 */    68,   69,   70,   71,   72,   73,   74,   75,   76,   77,
- /*   480 */    78,   79,   80,  155,   82,   83,   84,   85,   86,   87,
- /*   490 */    88,   89,   90,   91,   11,  155,  142,  244,   30,  194,
- /*   500 */   158,   49,  183,  184,  176,  177,  150,  151,  106,  190,
- /*   510 */    11,   26,  156,   30,  178,   30,  176,  177,  162,   67,
- /*   520 */    68,   69,   70,   71,   72,   73,   74,   75,   76,   77,
- /*   530 */    78,   79,   80,   11,   82,   83,   84,   85,   86,   87,
- /*   540 */    88,   89,   90,   91,  155,  155,  218,  178,  144,   11,
- /*   550 */    65,  195,  162,   28,  162,   11,  216,  159,  230,  223,
- /*   560 */   155,  225,  226,   95,   96,   11,  176,  177,   30,   50,
- /*   570 */    26,   86,   87,  231,   49,   11,  220,  235,   95,   96,
- /*   580 */    95,  176,  177,  194,   99,  195,  143,  195,   69,   11,
- /*   590 */   122,  139,   67,   68,   69,   70,   71,   72,   73,   74,
- /*   600 */    75,   76,   77,   78,   79,   80,  155,   82,   83,   84,
- /*   610 */    85,   86,   87,   88,   89,   90,   91,  132,  133,  134,
- /*   620 */    76,   30,   52,  218,   49,  106,   28,  176,  177,   51,
- /*   630 */   111,  174,  175,   95,   96,  230,  114,   11,  116,  117,
- /*   640 */   183,   29,   67,   68,   69,   70,   71,   72,   73,   74,
- /*   650 */    75,   76,   77,   78,   79,   80,   30,   82,   83,   84,
- /*   660 */    85,   86,   87,   88,   89,   90,   91,  155,  114,  155,
- /*   670 */   116,  117,   11,  222,   49,   30,  106,  120,  114,   88,
- /*   680 */   116,  117,  155,  107,  108,  109,   95,   96,  176,  177,
- /*   690 */   176,  177,   67,   68,   69,   70,   71,   72,   73,   74,
- /*   700 */    75,   76,   77,   78,   79,   80,   49,   82,   83,   84,
- /*   710 */    85,   86,   87,   88,   89,   90,   91,  155,  120,   26,
- /*   720 */    30,   95,   96,   30,   49,  107,  108,  109,   71,   72,
- /*   730 */   171,  172,  173,  121,  222,  168,  169,  170,  176,  177,
- /*   740 */    95,   96,   69,   68,   69,   70,   71,   72,   73,   74,
- /*   750 */    75,   76,   77,   78,   79,   80,   99,   82,   83,   84,
- /*   760 */    85,   86,   87,   88,   89,   90,   91,  122,   11,  106,
- /*   770 */    25,   11,   99,  162,   49,  114,  155,  116,  117,   27,
- /*   780 */    67,  168,   27,  120,   29,   95,   96,  155,   95,   96,
- /*   790 */    30,   88,  233,  155,   69,   70,   71,   72,   73,   74,
- /*   800 */    75,   76,   77,   78,   79,   80,  195,   82,   83,   84,
- /*   810 */    85,   86,   87,   88,   89,   90,   91,  155,  115,  206,
- /*   820 */   155,   26,  119,  155,  162,   30,  194,  189,  162,   11,
- /*   830 */    27,  220,   29,   38,   16,  214,   26,  155,  176,  177,
- /*   840 */    30,  176,  177,  130,  176,  177,  101,  236,   38,  155,
- /*   850 */    55,   96,  241,  155,   22,   95,   96,  195,  176,  177,
- /*   860 */    65,  195,  155,   31,   69,   55,  114,   11,  116,  117,
- /*   870 */   232,  114,  155,  116,  117,   65,   44,  122,   46,   69,
- /*   880 */   218,   86,   87,  176,  177,  155,  220,  142,  194,   94,
- /*   890 */    95,   96,  230,  198,   99,  227,   86,   87,   88,  155,
- /*   900 */   205,  155,  236,  155,   94,   95,   96,  241,  105,   99,
- /*   910 */    27,  194,   29,  118,  155,  145,  155,  155,  155,  189,
- /*   920 */   176,  177,  176,  177,  176,  177,  155,  132,  133,  134,
- /*   930 */   135,  136,  137,  138,  155,  176,  177,  176,  177,   27,
- /*   940 */    37,   29,  132,  133,  134,  135,  136,  137,  138,  155,
- /*   950 */    11,  189,  189,  155,   26,  176,  177,  155,   30,  162,
- /*   960 */    57,   32,  232,  155,  155,   36,   38,  155,   11,   26,
- /*   970 */   176,  177,  155,   30,  176,  177,  120,   48,  176,  177,
- /*   980 */   155,   38,   26,   55,  176,  177,   30,   11,  176,  177,
- /*   990 */   219,   29,  195,   65,  232,  232,  155,   69,   55,  192,
- /*  1000 */   193,  176,  177,  194,  155,   24,  189,   27,   65,   29,
- /*  1010 */   155,  118,   69,  110,   86,   87,   99,  176,  177,  144,
- /*  1020 */   192,  193,   94,   95,   96,  176,  177,   99,  111,   86,
- /*  1030 */    87,  176,  177,  155,   28,  155,   30,   94,   95,   96,
- /*  1040 */   155,   60,   99,   62,  155,  106,   27,  155,   29,  232,
- /*  1050 */   155,   95,  155,   11,  176,  177,  176,  177,   96,  155,
- /*  1060 */   132,  133,  134,  135,  136,  137,  138,  139,  176,  177,
- /*  1070 */   155,  176,  177,  176,  177,  132,  133,  134,  135,  136,
- /*  1080 */   137,  138,   15,  194,  122,  155,  129,   20,   21,   22,
- /*  1090 */    23,  176,  177,  155,   11,   12,  155,   34,  194,  214,
- /*  1100 */    33,   95,   35,  155,   41,  155,  176,  177,  155,   42,
- /*  1110 */   155,  245,   30,  155,  176,  177,  155,  176,  177,  155,
- /*  1120 */   155,   54,  155,   56,  176,  177,  176,  177,   61,  155,
- /*  1130 */    63,  176,  177,   66,  176,  177,  126,  176,  177,  155,
- /*  1140 */   176,  177,  155,  176,  177,  155,  118,  155,   11,  155,
- /*  1150 */   176,  177,  118,  162,   27,  162,   29,  155,  155,  131,
- /*  1160 */   176,  177,  155,  176,  177,  131,  176,  177,  176,  177,
- /*  1170 */   176,  177,  219,  155,  107,  108,  109,   95,  176,  177,
- /*  1180 */   113,  155,  168,  176,  177,  118,  195,   26,  195,   28,
- /*  1190 */   207,  208,   86,   87,  176,  177,   27,   27,   29,   29,
- /*  1200 */    50,  155,  176,  177,   17,   18,   27,  149,   29,   27,
- /*  1210 */   152,   29,   98,   99,   11,   13,   27,  214,   29,   26,
- /*  1220 */   206,   26,   14,  196,   26,  128,  221,  106,  193,  204,
- /*  1230 */    11,   27,  155,   26,   29,  155,  200,   27,  130,   11,
- /*  1240 */   200,  110,  191,   67,   11,  200,  129,  121,   11,   11,
- /*  1250 */    11,  199,   11,   91,   11,  200,  106,  155,   11,  121,
- /*  1260 */    26,  185,  159,  154,  221,  155,  120,   11,  155,  120,
- /*  1270 */   155,  130,  154,   76,  118,   11,  125,   11,  232,   29,
- /*  1280 */   155,  197,   76,  118,  104,  200,  217,   26,  155,   30,
- /*  1290 */   179,  167,   11,  154,  178,   11,  110,  155,  217,  179,
- /*  1300 */   157,   11,  118,  191,  185,   27,   21,   11,  125,   11,
- /*  1310 */    21,   29,  178,  191,  155,  130,  180,   26,  130,   15,
- /*  1320 */   142,   11,  178,  195,  106,   26,  155,  155,  155,   26,
- /*  1330 */    47,  186,  209,  122,  159,  161,  155,   51,  142,   52,
- /*  1340 */   210,  106,  188,  123,   27,  155,  211,  155,   26,   11,
- /*  1350 */   159,  188,   39,   27,  155,  106,  179,   11,   51,   99,
- /*  1360 */   106,   43,  168,   15,  155,  217,  120,   27,   45,  240,
- /*  1370 */   210,  239,  120,  159,  106,  211,  105,  237,  178,  167,
- /*  1380 */   179,  159,  155,   28,  159,  238,  234,  234,   27,  159,
- /*  1390 */   166,  155,  179,  178,   27,  155,  180,  176,   26,  176,
- /*  1400 */   155,  153,   26,  186,  178,   11,  155,  178,  120,  154,
- /*  1410 */    40,  111,  181,  155,  182,  103,   28,   11,   27,   26,
- /*  1420 */   155,   11,  127,   11,   11,  155,  184,   11,  155,   11,
- /*  1430 */    21,  139,   11,   51,   11,  155,   11,  168,  185,  182,
- /*  1440 */   246,  197,  168,  246,  181,  246,  246,  246,  155,  246,
- /*  1450 */   246,  246,  246,  159,  246,  246,  155,  246,  246,  246,
- /*  1460 */   246,  246,  246,  246,  246,  246,  246,  246,  246,  246,
- /*  1470 */   246,  246,  246,  246,  246,  246,  246,  246,  246,  217,
- /*  1480 */   201,  246,  246,  246,  246,  246,  246,  246,  246,  246,
- /*  1490 */   246,  246,  246,  246,  246,  246,  246,  246,  246,  202,
- /*  1500 */   246,  246,  246,  228,  246,  229,  246,  246,  246,  242,
- /*  1510 */   246,  246,  246,  246,  246,  243,  246,  246,  246,  242,
+ /*     0 */    16,  138,  139,  140,   22,   21,  143,   23,   68,   69,
+ /*    10 */    70,   71,   16,   73,   74,   75,   76,   77,   78,   79,
+ /*    20 */    80,   81,   82,    7,    8,    9,   42,   72,   73,   74,
+ /*    30 */    75,   76,   77,   78,   79,   80,   81,   82,  216,  217,
+ /*    40 */   218,  219,  134,   59,   60,   61,   62,   63,   64,   65,
+ /*    50 */    66,   67,   68,   69,   70,   71,  109,   73,   74,   75,
+ /*    60 */    76,   77,   78,   79,   80,   81,   82,   16,   16,   87,
+ /*    70 */    86,   58,  146,   22,   73,   74,   75,   76,   77,   78,
+ /*    80 */    79,   80,   81,   82,   88,   89,   90,   91,   92,   93,
+ /*    90 */    94,   95,  106,   42,   23,  113,  110,   46,  102,   86,
+ /*   100 */    98,   99,  100,   90,   77,   78,   79,   80,   81,   82,
+ /*   110 */    59,   60,   61,   62,   63,   64,   65,   66,   67,   68,
+ /*   120 */    69,   70,   71,   82,   73,   74,   75,   76,   77,   78,
+ /*   130 */    79,   80,   81,   82,   16,  146,  123,  124,  125,  146,
+ /*   140 */    12,   22,   90,   91,   92,   93,   94,   95,  155,  156,
+ /*   150 */    23,  225,   24,   23,  102,  141,  142,   86,   87,   88,
+ /*   160 */    42,  147,   91,   92,   93,   37,  157,   39,  154,  160,
+ /*   170 */   161,  162,  179,  180,  103,   43,  187,   59,   60,   61,
+ /*   180 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
+ /*   190 */    19,   73,   74,   75,   76,   77,   78,   79,   80,   81,
+ /*   200 */    82,  168,  188,   11,   77,   78,   16,   88,  146,   79,
+ /*   210 */    91,   92,   93,   86,   87,  146,   86,   87,    1,    2,
+ /*   220 */   146,   25,  103,  146,   97,   29,  237,  213,  154,   97,
+ /*   230 */   168,  169,   42,  164,  165,   19,  168,   41,   67,   23,
+ /*   240 */   160,   49,  168,  169,  180,  168,  169,  154,  130,   59,
+ /*   250 */    60,   61,   62,   63,   64,   65,   66,   67,   68,   69,
+ /*   260 */    70,   71,  188,   73,   74,   75,   76,   77,   78,   79,
+ /*   270 */    80,   81,   82,  175,  176,  154,  180,  215,   16,  199,
+ /*   280 */   182,  188,   20,   79,  146,  211,  149,   27,  211,  146,
+ /*   290 */    98,   99,  100,  146,   34,  226,  216,  223,  218,  219,
+ /*   300 */   223,  109,   86,   87,   42,  146,  168,  169,  146,  188,
+ /*   310 */   106,  168,  169,  189,  110,  168,  169,  154,    7,    8,
+ /*   320 */   130,   59,   60,   61,   62,   63,   64,   65,   66,   67,
+ /*   330 */    68,   69,   70,   71,  213,   73,   74,   75,   76,   77,
+ /*   340 */    78,   79,   80,   81,   82,   16,  208,  209,   12,   20,
+ /*   350 */   216,  188,  218,  219,  211,  234,   16,   23,   20,  146,
+ /*   360 */    24,  224,  215,  200,  201,  228,  223,  154,  205,  207,
+ /*   370 */   236,   42,   23,   37,  216,   39,  218,  219,  163,  164,
+ /*   380 */   165,  168,  169,   43,  105,   49,  107,  108,   59,   60,
+ /*   390 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
+ /*   400 */    71,  188,   73,   74,   75,   76,   77,   78,   79,   80,
+ /*   410 */    81,   82,   16,   88,   20,  146,   91,   92,   93,  146,
+ /*   420 */    86,   87,   79,   80,   81,   82,  146,   23,  103,   77,
+ /*   430 */    78,   20,   42,   51,   52,   86,   87,   97,   42,  146,
+ /*   440 */    44,  226,  102,  105,  146,  107,  108,  113,  168,  169,
+ /*   450 */   181,   22,   62,   63,  181,   59,   60,   61,   62,   63,
+ /*   460 */    64,   65,   66,   67,   68,   69,   70,   71,  146,   73,
+ /*   470 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   16,
+ /*   480 */    90,  146,  109,   20,   19,  146,  185,  146,   23,  209,
+ /*   490 */    86,   87,  146,  152,  225,  122,  155,  156,  225,  105,
+ /*   500 */    22,  107,  108,  168,  169,   42,  146,  168,  169,  187,
+ /*   510 */   163,  164,  165,  146,  168,  169,  105,  113,  107,  108,
+ /*   520 */    14,   23,   59,   60,   61,   62,   63,   64,   65,   66,
+ /*   530 */    67,   68,   69,   70,   71,  146,   73,   74,   75,   76,
+ /*   540 */    77,   78,   79,   80,   81,   82,   16,  146,   19,  120,
+ /*   550 */    20,   86,   87,  146,  187,  220,  146,  168,  169,   53,
+ /*   560 */   146,   55,  223,  146,  109,  146,  160,  161,  162,  168,
+ /*   570 */   169,  146,   42,  226,   96,  168,  169,  122,  168,  169,
+ /*   580 */   155,  156,  168,  169,   86,  168,  169,  168,  169,   59,
+ /*   590 */    60,   61,   62,   63,   64,   65,   66,   67,   68,   69,
+ /*   600 */    70,   71,  146,   73,   74,   75,   76,   77,   78,   79,
+ /*   610 */    80,   81,   82,   16,  146,   98,   99,  100,   21,  146,
+ /*   620 */    20,  146,   22,  146,  168,  169,  146,   20,  146,   22,
+ /*   630 */   146,  140,  146,   21,  143,   23,  168,  169,  132,   42,
+ /*   640 */   111,  168,  169,  168,  169,  168,  169,  146,  168,  169,
+ /*   650 */   168,  169,  168,  169,  168,  169,   59,   60,   61,   62,
+ /*   660 */    63,   64,   65,   66,   67,   68,   69,   70,   71,  146,
+ /*   670 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
+ /*   680 */    16,  146,  146,  146,  146,   21,  146,   20,  146,   22,
+ /*   690 */   146,  168,  169,  146,    0,    1,    2,  146,   86,  146,
+ /*   700 */    20,   19,   22,  168,  169,   23,   42,   16,  168,  169,
+ /*   710 */   168,  169,  168,  169,   14,  168,  169,  181,  181,  168,
+ /*   720 */   169,  168,  169,   59,   60,   61,   62,   63,   64,   65,
+ /*   730 */    66,   67,   68,   69,   70,   71,  146,   73,   74,   75,
+ /*   740 */    76,   77,   78,   79,   80,   81,   82,   16,  146,  146,
+ /*   750 */   123,  124,  146,   53,  146,   55,  146,   22,  168,  169,
+ /*   760 */   146,  225,  225,  146,   20,  146,   22,   20,   86,   22,
+ /*   770 */   168,  169,  167,   42,  168,  169,  168,  169,  168,  169,
+ /*   780 */   175,   90,  168,  169,  181,   89,   90,  168,  169,  146,
+ /*   790 */    59,   60,   61,   62,   63,   64,   65,   66,   67,   68,
+ /*   800 */    69,   70,   71,  146,   73,   74,   75,   76,   77,   78,
+ /*   810 */    79,   80,   81,   82,   16,  146,   19,   90,   21,  146,
+ /*   820 */    20,  146,   22,  146,  207,  168,  169,  146,  225,  102,
+ /*   830 */   187,   30,  146,   20,   18,   22,  146,  168,  169,  146,
+ /*   840 */    42,  168,  169,  168,  169,  168,  169,  112,  160,  168,
+ /*   850 */   169,   50,  200,  201,  168,  169,  202,   59,   60,   61,
+ /*   860 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
+ /*   870 */   160,   73,   74,   75,   76,   77,   78,   79,   80,   81,
+ /*   880 */    82,   16,  166,  167,  129,  146,  131,   20,   20,   22,
+ /*   890 */    22,  175,   20,  191,   22,  184,  185,  207,  146,  146,
+ /*   900 */   198,  177,  101,  154,  146,  212,  146,   42,   92,  199,
+ /*   910 */   184,  185,  146,  146,  146,  154,  146,  154,  146,  154,
+ /*   920 */   146,  146,  160,  146,   16,   60,   61,   62,   63,   64,
+ /*   930 */    65,   66,   67,   68,   69,   70,   71,  188,   73,   74,
+ /*   940 */    75,   76,   77,   78,   79,   80,   81,   82,  132,  188,
+ /*   950 */    42,  188,  146,  188,  187,  187,  146,  187,  159,  187,
+ /*   960 */   146,  199,  187,  177,  212,  146,  146,  168,  146,   61,
+ /*   970 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
+ /*   980 */   177,   73,   74,   75,   76,   77,   78,   79,   80,   81,
+ /*   990 */    82,   16,   17,  146,   19,  146,  146,  146,   23,  146,
+ /*  1000 */   146,  146,   16,   17,  146,   19,   31,  146,  144,   23,
+ /*  1010 */   230,   19,  146,  190,  231,   23,  146,   31,  227,  146,
+ /*  1020 */   190,  176,  227,   48,  222,  148,  193,  171,  171,  193,
+ /*  1030 */   171,  171,  192,   58,   48,  172,  188,   15,  186,  111,
+ /*  1040 */   171,  151,  115,  151,   58,   33,  235,   23,  159,  151,
+ /*  1050 */    58,  120,   77,   78,   79,  129,  221,   59,  196,  183,
+ /*  1060 */    85,   86,   87,   77,   78,   90,   96,  193,  172,   77,
+ /*  1070 */    78,   85,   86,   87,   95,   19,   90,   97,   86,  170,
+ /*  1080 */   170,  210,   90,   40,  193,  178,    6,  145,  159,   16,
+ /*  1090 */    17,  145,   19,  214,  145,  109,   23,  183,  123,  124,
+ /*  1100 */   125,  126,  127,  128,   31,   19,  173,   15,  150,  123,
+ /*  1110 */   124,  125,  126,  127,  128,  123,  124,  125,  129,  233,
+ /*  1120 */   151,   48,  178,  183,  170,   38,  232,  210,  118,  195,
+ /*  1130 */   145,   58,  151,  150,  210,  114,  204,  170,  170,  214,
+ /*  1140 */    22,  153,  170,  170,  119,  197,  151,  151,  151,  173,
+ /*  1150 */    77,   78,  136,  235,  238,  151,  193,  151,   85,   86,
+ /*  1160 */    87,   97,  203,   90,    5,  203,  117,  210,  186,   10,
+ /*  1170 */    11,   12,   13,  186,  229,  204,  174,  158,  194,  174,
+ /*  1180 */    17,   20,   22,  112,   19,   26,   20,   28,  121,  113,
+ /*  1190 */    67,   67,  101,    1,   35,  106,  123,  124,  125,  126,
+ /*  1200 */   127,  128,    5,   19,   97,   22,   47,  132,   49,   45,
+ /*  1210 */   116,  111,   22,   54,   45,   56,  111,   32,   19,   19,
+ /*  1220 */    44,   20,   36,   97,   19,   21,   20,   17,   90,   16,
+ /*  1230 */    19,  116,  111,   19,  102,   20,   19,   44,   22,  135,
+ /*  1240 */   111,   14,    1,    3,   57,   20,    4,  111,   20,   11,
+ /*  1250 */    19,   44,   20,   20,   19,  121,   94,   98,   99,  100,
+ /*  1260 */   112,  239,   19,  104,   19,  239,  239,  239,  109,  101,
+ /*  1270 */   239,  239,  239,  239,  239,  239,  239,  239,  239,  239,
+ /*  1280 */   239,  239,  239,  239,  239,  239,  239,  239,  239,  239,
+ /*  1290 */   239,  239,  133,
 };
-#define YY_SHIFT_USE_DFLT (-75)
+#define YY_SHIFT_USE_DFLT (-93)
+#define YY_SHIFT_MAX 369
 static const short yy_shift_ofst[] = {
- /*     0 */  1083,  373,  -75,  -75, 1067, 1284, 1338,  -75,  293,  818,
- /*    10 */  1394,  626, 1266,  -75,  -75,  -75,  -75,  -75,  -75,  818,
- /*    20 */  1219,  818, 1256,  818, 1281, 1161, 1290,  690, 1169, 1317,
- /*    30 */  1346,  275,  -75, 1082,  -75,  -16,  -75,  690,   33,  -75,
- /*    40 */  1121,  -75, 1313,  359,  -75,  -75,  -75,  -75,  -75,  -75,
- /*    50 */   -75,  917, 1121,  -75, 1283,  -75, 1187,  -75,  -75, 1307,
- /*    60 */  1063, 1121, 1271,  -75,  -75,  -75,  -75, 1121,  -75, 1376,
- /*    70 */   943,   39,  703,  -75,  -75,  943, 1288, 1246,  -75,  795,
- /*    80 */   -75,  114,  893,  -75,  185,  -75,  612, 1117, 1010, 1295,
- /*    90 */    16, 1097,  -75,  943,   40,  943,  575,  943,  -75, 1146,
- /*   100 */   690, 1149,  690,  -75,  -75,  -75,  -75,  -75,  -75, 1291,
- /*   110 */   943,  525, 1082,  -75,  -75,  956, 1106, 1170,  -75, 1106,
- /*   120 */  1326,  -75,  -75,  -75,  -41,  -75,  -75,  -75,  -41,  -75,
- /*   130 */   -75,  -75,  -75, 1367,  -75,  943,  -75,  675,  943,  -12,
- /*   140 */   943,  -12,  943,  -12,  943,  -12,  943,  -74,  943,  -74,
- /*   150 */   943,  -53,  943,  -53,  943,  -53,  943,  -53,  943,  101,
- /*   160 */   943,  101,  943, 1162,  943, 1162,  943, 1162,  943,  -75,
- /*   170 */   -75,  657,  -75,  -75,  -75,  -75,  943,  -59,  943,  -12,
- /*   180 */   -75,  673,  -75, 1260,  -75,  -75,  -75,  943,  625,  943,
- /*   190 */   -74,  -75,  366,  795,  752,  284, 1184, 1165, 1156,  -75,
- /*   200 */   575,  943,  725,  943,  -75,  943,  -75,  943,  -75, 1193,
- /*   210 */   893,  192,  -75,  928,  452, 1292,  128, 1409,  -75,  943,
- /*   220 */   278,  943,  575, 1198,  832, 1204,  -75, 1205,  690, 1210,
- /*   230 */   -75,  943,  203,  943,  246,  943,  575, 1127,  -75,  943,
- /*   240 */   -75,  -75,  557,  690,  -75,  -75,  -75,  725,  943,  575,
- /*   250 */  1151,  943, 1250,  943, 1180, 1063,  -75, 1259,  -75,  -75,
- /*   260 */   575, 1180, 1063,  -75,  943,  575, 1183,  943, 1282,  943,
- /*   270 */   575,  -75,  -75,  962,  -75,  -75,  -75,  468,  -75,  645,
- /*   280 */   -75, 1211,  -75,  693,  557, 1006,  690,  -75,  -75, 1235,
- /*   290 */  1220,  -75, 1322,  690, 1179,  -75,  690,  -75,  -75,  943,
- /*   300 */   575,  893,  -20,  755, 1340, 1006, 1235, 1220,  -75,  810,
- /*   310 */   -28,  -75,  -75, 1252,  591,  -75,  -75,  126,  -75, 1182,
- /*   320 */   -75, 1361,  -75,   94, 1121,  -75,  690, 1372,  -75, 1150,
- /*   330 */   -75,  690,  -75,  576,  903,  -75, 1114,  -75,  -75,  -75,
- /*   340 */   -75,  903,  -75,  903,  -75,  690, 1189,  -75,  690, 1180,
- /*   350 */  1063,  -75,  -75, 1180, 1063,  -75,  -75, 1259,  -75, 1283,
- /*   360 */   -75,  -75,  485,  -75,  943,  352,  -75,  169,  -75,  -75,
- /*   370 */   169,  -75,  -75,  -75,  -75,  121,  355,  -75,  690,  -75,
- /*   380 */  1286, 1303,  690,  803, 1278, 1121,  -75, 1261,  690,  419,
- /*   390 */  1121,  -75,  943,  402,  -75, 1382, 1393,  690,  436, 1312,
- /*   400 */   690, 1372,  -75,  519, 1300,  -75,  -75,  -75,  -75,  -75,
- /*   410 */   893,  522,  745,  981,  690,  557,  -75,  690,  598, 1355,
- /*   420 */   893,  149,  690,  557,  929,  618, 1268,  690,  557,  -75,
- /*   430 */  1323,   49, 1348,  943,  171, 1318,  167,  -75,  -75, 1254,
- /*   440 */  1249,  570,  690,  178,  -75,  -75, 1287,  -75,  -75, 1196,
- /*   450 */   690,  663, 1218,  690, 1299,  690,  883,  939, 1310, 1178,
- /*   460 */  1304,  286,  757,  713,  359,  -75, 1188, 1185, 1289, 1298,
- /*   470 */  1296,  286, 1285, 1176,  690, 1186,  690,  330,  690, 1206,
- /*   480 */   943,  575, 1264, 1197,  943,  575, 1141,  690, 1207,  690,
- /*   490 */   980,  -75, 1028,  564, 1234,  943, 1019,  943,  575, 1247,
- /*   500 */   575, 1138,  690,  957, 1243,  354,  690, 1241,  690, 1239,
- /*   510 */   690, 1238,  690, 1237,  554, 1126,  690,  957, 1233, 1176,
- /*   520 */   690, 1131,  690,  330, 1228, 1108,  690, 1207, 1034,  661,
- /*   530 */  1195,  943,  912, 1203,  483, 1042,  690,  557,  544,  358,
- /*   540 */   499,  422, 1421, 1416,  690, 1391, 1406, 1370, 1082, 1388,
- /*   550 */   690,  578, 1410,  -29, 1412, 1413,  -75, 1370,  690, 1418,
- /*   560 */   538,  856, 1423,  760,  856, 1425,  320,  690,  404,  443,
- /*   570 */   690,  976,  875,  770,  690, 1137,  -75, 1202, 1208,  -75,
- /*   580 */   -75,
+ /*     0 */   217,  986, 1159,  -16,  986, 1073, 1073, 1073,   71,  -53,
+ /*    10 */   396, 1073, 1073, 1073, 1073, 1073,  -45,  127,  192,  349,
+ /*    20 */   352,  352,  498,   51,  597,  463,  329,  118,  190,  664,
+ /*    30 */   530,  262,  731,  731,  731,  731,  731,  731,  731,  798,
+ /*    40 */   731,  731,  731,  731,  731,  731,  731,  731,  731,  731,
+ /*    50 */   731,  865,  908,  908,  975, 1073, 1073, 1073, 1073, 1073,
+ /*    60 */  1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073,
+ /*    70 */  1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073,
+ /*    80 */  1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073,
+ /*    90 */  1073, 1073, 1073,  -60,  -60,   -4,    1,    1,   27,  340,
+ /*   100 */   343,  349,  349,  349,  349,  349,  816,  349,  349,  498,
+ /*   110 */    41,  -93,  -93,  -93,  992,   52,  336,  336,  349,  349,
+ /*   120 */   349,  349,  349,  349,  612,  694,  349,  349,  349,  349,
+ /*   130 */   349,  349,  349,  349,  612,  373,  455,  -53,  -53,  -53,
+ /*   140 */   -93,  -93,   13,   13,  119,  325,  465,  411,  130,  334,
+ /*   150 */   128,  404,  394,  338,  216,  349,  349,  349,  349,  349,
+ /*   160 */   682,  279,  279,  -18,  349,  349,  349,  349,  279,  801,
+ /*   170 */   349,  349,  349,  801,  349,  349,  349,  801,  349,  279,
+ /*   180 */   349,  279,  349,  349,  349,  349,  349,  349,  279,  349,
+ /*   190 */   -18,   16,  204,  349,  279,  349,  196,    2,  349,  260,
+ /*   200 */   627,  260,  -14,  260,  132,  260,  627,  755,  797,  429,
+ /*   210 */   260,  429,  478,  735,  -53, 1022,  928,  927,  928, 1012,
+ /*   220 */  1024,  928,  931,  926,  998,  970,  979, 1056,  980,  980,
+ /*   230 */   931, 1043, 1024, 1080, 1080, 1080,  998, 1086, 1092,  989,
+ /*   240 */  1043,  928,  998, 1087,  979,  980, 1010,  928, 1092, 1080,
+ /*   250 */   979, 1021,  980, 1056,  980, 1118,  980, 1025,  980,  928,
+ /*   260 */   928,  928, 1012, 1086, 1016,  928,  931,  928, 1022, 1064,
+ /*   270 */  1064, 1049, 1021, 1022,  979,  -93,  -93,  -93,  -93,  390,
+ /*   280 */   506,  700,  517,  529,  680,  171,  667,  311,  744,  747,
+ /*   290 */   800,  813,  867,  382,  696,  868,  872,  691,  727,  600,
+ /*   300 */   607, 1163, 1161, 1160, 1071, 1165, 1166, 1067, 1076, 1123,
+ /*   310 */  1124, 1091, 1192, 1089, 1197, 1184, 1107, 1075, 1183, 1164,
+ /*   320 */  1094, 1100, 1190, 1169, 1185, 1105, 1199, 1186, 1200, 1126,
+ /*   330 */  1201, 1176, 1205, 1204, 1206, 1210, 1138, 1211, 1213, 1115,
+ /*   340 */  1214, 1121, 1215, 1132, 1216, 1193, 1217, 1104, 1129,  -92,
+ /*   350 */  1187, 1227, 1241, 1240, 1242, 1225, 1136, 1228, 1238, 1231,
+ /*   360 */  1232, 1233, 1207, 1235, 1162, 1134, 1168, 1148, 1243, 1245,
 };
-#define YY_REDUCE_USE_DFLT (-154)
+#define YY_REDUCE_USE_DFLT (-179)
+#define YY_REDUCE_MAX 278
 static const short yy_reduce_ofst[] = {
- /*     0 */   191, 1058, -154, -154,  356, -154, -154, -154, 1248, 1255,
- /*    10 */  -154, 1077, -154, -154, -154, -154, -154, -154, -154, 1118,
- /*    20 */  -154, 1109, -154, 1139, -154, 1143, -154,   72, 1174, -154,
- /*    30 */  -154,  219, -154,  -23, 1224,  457, -154, 1258,   54, -154,
- /*    40 */  1200, -154, -154,  828, -154, -154, -154, -154, -154, -154,
- /*    50 */  -154, -154, 1134, -154, 1145, -154, -154, -154, -154, -154,
- /*    60 */  1213, 1215, 1216, -154, -154, -154, -154, 1229, -154, -154,
- /*    70 */   825, -154, 1244, -154, -154,  405, -154, -154, -154,  390,
- /*    80 */  -154, 1027, 1128, -154, 1084,  695, 1052, 1036, 1279, 1297,
- /*    90 */   214, 1025, -154,  707, -122, 1002, -122,  990, -154, -154,
- /*   100 */  1113, -154, 1133, -154, -154, -154, -154, -154, -154, -154,
- /*   110 */   955, -122,  567, -154, -154, 1194,  559, -154, -154, -153,
- /*   120 */  -154, -154, -154, -154, 1152, -154, -154, -154, 1153, -154,
- /*   130 */  -154, -154, -154, -154, -154,  849, -154, -122,  841, -122,
- /*   140 */   808, -122,  779, -122,  746, -122,  878, -122,  892, -122,
- /*   150 */   880, -122,  938, -122,  961, -122,  987, -122, 1018, -122,
- /*   160 */   744, -122,  761, -122,  794, -122,  798, -122,  812, -122,
- /*   170 */  -154, -154, -154, -154, -154, -154,  855,   73,  897, -122,
- /*   180 */  -154, -154, -154, -154, -154, -154, -154,  941, -122,  948,
- /*   190 */  -122, -154, 1159,  662, 1027, -154, -154, -154, -154, -154,
- /*   200 */  -122,  992, -122, 1007, -122,  514, -122,  682, -122, -154,
- /*   210 */   993, 1027, -154,  668, -122, 1275, 1276, -154, -154,  759,
- /*   220 */  -122,  748, -122, -154, 1035, -154, -154, -154, 1080, -154,
- /*   230 */  -154,  665, -122,  562, -122, 1026, -122, -154, -154,  236,
- /*   240 */  -154, -154, 1103, 1110, -154, -154, -154, -122,  974, -122,
- /*   250 */  -154,  234, -154,  340, 1069, 1111, -154, 1124, -154, -154,
- /*   260 */  -122, 1081, 1120, -154,  964, -122, -154,  328, -154,  958,
- /*   270 */  -122, -154,  983, 1123, -154, -154, -154, 1171, -154, 1173,
- /*   280 */  -154, -154, -154, 1190, 1191,  613, 1192, -154, -154, 1130,
- /*   290 */  1135, -154, -154, 1003, -154, -154, 1209, -154, -154,  930,
- /*   300 */  -122,  -56, 1027, 1123, -154, 1014, 1160, 1164, -154,  895,
- /*   310 */   -68, -154, -154, -154, 1113, -154, -154, -122, -154, -154,
- /*   320 */  -154, -154, -154, -122, 1226, -154, 1245, 1231, 1232, 1242,
- /*   330 */  -154, 1251, -154, -154, 1253, -154, -154, -154, -154, -154,
- /*   340 */  -154, 1076, -154, 1119, -154,  638, -154, -154, 1046, 1148,
- /*   350 */  1201, -154, -154, 1262, 1177, -154, -154, 1212, -154, 1217,
- /*   360 */  -154, -154,  233, -154,  950, -122, -154, 1223, -154, -154,
- /*   370 */  1221, -154, -154, -154, -154, 1163, 1154, -154, 1199, -154,
- /*   380 */  -154, -154,  730, 1136, -154, 1116, -154, -154,  762, -154,
- /*   390 */   369, -154,  802,  336, -154, -154, -154,  763, -154, -154,
- /*   400 */  1265, 1263, 1257,  319, -154, -154, -154, -154, -154, -154,
- /*   410 */    -8, 1027,  342, -154, 1240, 1230, -154, 1236, 1225, -154,
- /*   420 */   392, 1027, 1227, 1222, 1140, 1147, -154,  389, 1214, -154,
- /*   430 */  1132, 1129, -154,  915, -122, -154, -154, -154, -154, -154,
- /*   440 */  -154, -154,  621, -154, -154, -154, -154, -154, -154, -154,
- /*   450 */  1181, 1175, -154, 1172, -154,  817, -154, 1144, -154, -154,
- /*   460 */  -154,  666, 1027, 1122,  807, -154, -154, -154, -154, -154,
- /*   470 */  -154,  611, -154, 1112, 1142, -154,  771, 1085, 1125, -154,
- /*   480 */   967, -122, -154, -154,  984, -122, -154, 1115, 1043,  885,
- /*   490 */  -154, -154,  797, 1027, -154,  451, -154,  994, -122, -154,
- /*   500 */  -122, -154, 1102, 1055, -154, -154,  305, -154,  632, -154,
- /*   510 */   694, -154,  717, -154, 1027, -154,  809, 1045, -154, 1051,
- /*   520 */   889, -154,  953, 1040, -154, -154,  904, 1005,  991, 1027,
- /*   530 */  -154,  512, -154, -154,  965, -154,  527,  398, -154,  225,
- /*   540 */  -154, -154, -154, -154, 1273, -154, -154, 1267, 1269, -154,
- /*   550 */  1270, 1272, -154, 1274, -154, -154, -154, 1277, 1280, -154,
- /*   560 */  1293, 1294, -154, 1301,  -91, -154, -154,  253, -154, -154,
- /*   570 */   698, -154, -154,  866,  -65, -154, -154, -154, -154, -154,
- /*   580 */  -154,
+ /*     0 */  -137,   74,   14,   80,  213,  143,   77,  138,   -7,  163,
+ /*    10 */   134,   62,  280,  147,  335,  339, -178,   69,  121,  341,
+ /*    20 */   215,  347,    9,  158,  158,  158,  158,  158,  158,  158,
+ /*    30 */   158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
+ /*    40 */   158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
+ /*    50 */   158,  158,  158,  158,  346,  389,  401,  407,  410,  414,
+ /*    60 */   417,  419,  456,  468,  473,  475,  477,  480,  482,  484,
+ /*    70 */   486,  523,  535,  540,  542,  544,  547,  551,  553,  590,
+ /*    80 */   602,  606,  608,  610,  614,  619,  657,  669,  673,  675,
+ /*    90 */   677,  681,  686,  158,  158,  716,  158,  158,  158,   98,
+ /*   100 */   158,  269,  273,  -11,  425,  536,  137,  537,  603,  406,
+ /*   110 */   158,  158,  158,  158,  799,  605,  726,  711,  752,  775,
+ /*   120 */   690,  693,  -74,  617,  762,  491,  772,  770,  768,  767,
+ /*   130 */   162,  643,  367,  322,  710,   93,  749,  761,  763,  765,
+ /*   140 */   702,  652,   33,   68,   64,   96,  159,  124,  293,  298,
+ /*   150 */   301,  360,  124,  124,  501,  538,  739,  753,  758,  760,
+ /*   160 */   688,  124,  124,  654,  766,  774,  293,  777,  124,  724,
+ /*   170 */   806,  810,  814,  786,  819,  820,  822,  803,  847,  124,
+ /*   180 */   849,  124,  850,  851,  853,  854,  855,  858,  124,  861,
+ /*   190 */   654,  864,  823,  866,  124,  870,  780,  783,  873,  856,
+ /*   200 */   791,  857,  830,  859,  845,  860,  795,  802,  877,  833,
+ /*   210 */   869,  836,  863,  840,  848,  852,  890,  862,  892,  811,
+ /*   220 */   889,  898,  874,  835,  876,  896,  871,  879,  909,  910,
+ /*   230 */   891,  907,  929,  942,  946,  949,  914,  933,  958,  886,
+ /*   240 */   944,  969,  940,  894,  917,  954,  934,  981,  983,  985,
+ /*   250 */   924,  932,  967,  925,  968,  988,  972,  948,  973,  995,
+ /*   260 */   996,  997,  918,  976,  916, 1004,  963, 1006,  982,  959,
+ /*   270 */   962,  984,  971,  987,  957,  945, 1002, 1019, 1005,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   587,  587,  582,  585,  892,  892,  892,  586,  594,  892,
- /*    10 */   892,  892,  892,  614,  615,  616,  595,  596,  597,  892,
- /*    20 */   892,  892,  892,  892,  892,  892,  892,  892,  892,  892,
- /*    30 */   892,  892,  607,  617,  627,  609,  626,  892,  892,  628,
- /*    40 */   672,  635,  892,  892,  673,  676,  677,  678,  872,  873,
- /*    50 */   874,  892,  672,  636,  657,  655,  892,  658,  659,  892,
- /*    60 */   728,  672,  643,  637,  644,  726,  727,  672,  638,  892,
- /*    70 */   892,  758,  692,  690,  691,  824,  764,  759,  755,  892,
- /*    80 */   683,  892,  892,  684,  692,  694,  701,  740,  731,  733,
- /*    90 */   721,  735,  689,  892,  736,  892,  737,  892,  757,  892,
- /*   100 */   892,  760,  892,  761,  762,  763,  765,  766,  767,  892,
- /*   110 */   892,  892,  892,  612,  613,  619,  847,  892,  620,  847,
- /*   120 */   892,  621,  624,  625,  892,  842,  844,  845,  892,  843,
- /*   130 */   846,  623,  622,  892,  768,  892,  771,  773,  892,  774,
- /*   140 */   892,  775,  892,  776,  892,  777,  892,  778,  892,  779,
- /*   150 */   892,  780,  892,  781,  892,  782,  892,  783,  892,  784,
- /*   160 */   892,  785,  892,  786,  892,  787,  892,  788,  892,  789,
- /*   170 */   790,  892,  791,  798,  805,  808,  892,  793,  892,  792,
- /*   180 */   795,  892,  796,  892,  799,  797,  804,  892,  892,  892,
- /*   190 */   806,  807,  892,  824,  892,  892,  892,  892,  892,  811,
- /*   200 */   823,  892,  800,  892,  801,  892,  802,  892,  803,  892,
- /*   210 */   892,  892,  813,  892,  892,  892,  892,  892,  814,  892,
- /*   220 */   892,  892,  815,  892,  892,  892,  870,  892,  892,  892,
- /*   230 */   871,  892,  892,  892,  892,  892,  816,  892,  809,  824,
- /*   240 */   821,  822,  709,  892,  710,  812,  794,  772,  892,  738,
- /*   250 */   892,  892,  722,  892,  729,  728,  723,  892,  611,  730,
- /*   260 */   725,  729,  728,  724,  892,  734,  892,  824,  732,  892,
- /*   270 */   741,  693,  704,  702,  703,  712,  713,  892,  714,  892,
- /*   280 */   715,  892,  716,  892,  709,  700,  892,  698,  699,  718,
- /*   290 */   720,  705,  892,  892,  892,  719,  892,  753,  754,  892,
- /*   300 */   717,  704,  892,  892,  892,  700,  718,  720,  706,  892,
- /*   310 */   700,  695,  696,  892,  892,  697,  810,  892,  756,  892,
- /*   320 */   769,  892,  770,  892,  672,  639,  892,  828,  645,  640,
- /*   330 */   646,  892,  647,  892,  892,  648,  892,  651,  652,  653,
- /*   340 */   654,  892,  649,  892,  650,  892,  892,  829,  892,  729,
- /*   350 */   728,  830,  832,  729,  728,  831,  641,  892,  642,  657,
- /*   360 */   656,  629,  892,  630,  892,  892,  631,  892,  632,  764,
- /*   370 */   892,  633,  634,  618,  610,  892,  892,  662,  892,  665,
- /*   380 */   892,  892,  892,  892,  892,  672,  666,  892,  892,  892,
- /*   390 */   672,  667,  892,  672,  668,  892,  892,  892,  892,  892,
- /*   400 */   892,  828,  645,  670,  892,  669,  671,  663,  664,  608,
- /*   410 */   892,  892,  604,  892,  892,  709,  602,  892,  892,  892,
- /*   420 */   892,  892,  892,  709,  853,  892,  892,  892,  709,  711,
- /*   430 */   858,  892,  892,  892,  892,  892,  892,  859,  860,  892,
- /*   440 */   892,  892,  892,  892,  850,  851,  892,  852,  603,  892,
- /*   450 */   892,  892,  892,  892,  892,  892,  892,  892,  892,  892,
- /*   460 */   892,  892,  892,  892,  892,  675,  892,  892,  892,  892,
- /*   470 */   892,  892,  892,  674,  892,  892,  892,  892,  892,  892,
- /*   480 */   892,  743,  892,  892,  892,  744,  892,  892,  751,  892,
- /*   490 */   892,  752,  892,  892,  892,  892,  892,  892,  749,  892,
- /*   500 */   750,  892,  892,  892,  892,  892,  892,  892,  892,  892,
- /*   510 */   892,  892,  892,  892,  892,  892,  892,  892,  892,  674,
- /*   520 */   892,  892,  892,  892,  892,  892,  892,  751,  892,  892,
- /*   530 */   892,  892,  892,  892,  892,  892,  892,  709,  892,  847,
- /*   540 */   892,  892,  892,  892,  892,  892,  892,  881,  892,  892,
- /*   550 */   892,  892,  892,  892,  892,  892,  880,  881,  892,  892,
- /*   560 */   892,  892,  892,  892,  892,  892,  892,  892,  892,  892,
- /*   570 */   892,  892,  892,  890,  892,  892,  891,  588,  892,  589,
- /*   580 */   583,
+ /*     0 */   565,  789,  854,  680,  854,  789,  789,  854,  854,  684,
+ /*    10 */   840,  854,  854,  854,  785,  789,  760,  811,  854,  854,
+ /*    20 */   811,  811,  596,  715,  854,  854,  854,  854,  854,  854,
+ /*    30 */   854,  854,  723,  780,  722,  784,  825,  788,  841,  854,
+ /*    40 */   716,  696,  720,  729,  713,  728,  704,  717,  844,  781,
+ /*    50 */   782,  750,  766,  749,  854,  854,  854,  854,  854,  854,
+ /*    60 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*    70 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*    80 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*    90 */   854,  854,  854,  771,  752,  589,  751,  759,  753,  649,
+ /*   100 */   754,  854,  854,  854,  854,  854,  584,  854,  854,  854,
+ /*   110 */   755,  768,  756,  767,  854,  854,  854,  854,  854,  854,
+ /*   120 */   854,  854,  854,  854,  680,  565,  854,  854,  854,  854,
+ /*   130 */   854,  854,  854,  854,  680,  854,  854,  854,  854,  854,
+ /*   140 */   674,  684,  854,  854,  640,  854,  854,  854,  854,  854,
+ /*   150 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*   160 */   598,  832,  586,  682,  854,  854,  854,  854,  830,  854,
+ /*   170 */   854,  854,  854,  854,  854,  854,  845,  854,  847,  663,
+ /*   180 */   854,  725,  854,  799,  854,  570,  854,  854,  687,  854,
+ /*   190 */   688,  572,  672,  854,  661,  854,  817,  854,  854,  707,
+ /*   200 */   854,  707,  672,  707,  619,  707,  854,  783,  854,  719,
+ /*   210 */   707,  719,  622,  681,  854,  660,  689,  700,  689,  843,
+ /*   220 */   854,  689,  719,  854,  653,  622,  708,  730,  651,  651,
+ /*   230 */   719,  636,  854,  569,  569,  569,  653,  793,  581,  824,
+ /*   240 */   636,  689,  653,  821,  708,  651,  712,  689,  581,  569,
+ /*   250 */   708,  699,  651,  730,  651,  639,  651,  714,  651,  689,
+ /*   260 */   689,  689,  843,  793,  852,  689,  719,  689,  660,  697,
+ /*   270 */   697,  710,  699,  660,  708,  827,  624,  606,  624,  854,
+ /*   280 */   854,  854,  854,  737,  854,  806,  854,  854,  854,  854,
+ /*   290 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*   300 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*   310 */   854,  854,  854,  666,  854,  854,  854,  854,  711,  854,
+ /*   320 */   854,  738,  820,  819,  854,  742,  854,  854,  854,  854,
+ /*   330 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*   340 */   854,  739,  854,  854,  701,  854,  854,  854,  854,  854,
+ /*   350 */   851,  854,  854,  566,  854,  854,  854,  854,  854,  854,
+ /*   360 */   854,  854,  854,  854,  854,  854,  854,  854,  854,  854,
+ /*   370 */   561,  740,  741,  743,  744,  736,  669,  592,  599,  600,
+ /*   380 */   603,  604,  807,  809,  808,  810,  602,  601,  745,  748,
+ /*   390 */   665,  664,  757,  758,  764,  770,  773,  734,  671,  762,
+ /*   400 */   763,  765,  769,  670,  772,  617,  667,  668,  776,  706,
+ /*   410 */   705,  623,  616,  778,  779,  638,  637,  833,  834,  634,
+ /*   420 */   615,  774,  837,  786,  787,  690,  777,  761,  836,  835,
+ /*   430 */   657,  656,  655,  702,  591,  709,  652,  703,  614,  607,
+ /*   440 */   673,  683,  692,  693,  694,  695,  678,  679,  685,  698,
+ /*   450 */   732,  733,  605,  686,  587,  675,  676,  677,  775,  585,
+ /*   460 */   735,  746,  747,  618,  625,  626,  627,  630,  631,  632,
+ /*   470 */   633,  628,  629,  794,  795,  797,  796,  620,  621,  635,
+ /*   480 */   608,  609,  579,  610,  611,  742,  612,  613,  597,  590,
+ /*   490 */   641,  644,  645,  646,  578,  647,  648,  650,  642,  643,
+ /*   500 */   588,  580,  582,  691,  813,  577,  822,  823,  818,  814,
+ /*   510 */   815,  816,  583,  790,  791,  654,  726,  727,  812,  826,
+ /*   520 */   576,  828,  575,  574,  731,  573,  595,  594,  829,  593,
+ /*   530 */   831,  658,  659,  662,  798,  838,  718,  721,  571,  724,
+ /*   540 */   800,  801,  802,  803,  804,  805,  568,  564,  839,  562,
+ /*   550 */   842,  563,  560,  846,  848,  849,  850,  853,  567,
 };
 #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
 
@@ -682,75 +584,66 @@
 #ifdef YYFALLBACK
 static const YYCODETYPE yyFallback[] = {
     0,  /*          $ => nothing */
-    0,  /* END_OF_FILE => nothing */
-    0,  /*    ILLEGAL => nothing */
-    0,  /*      SPACE => nothing */
-    0,  /* UNCLOSED_STRING => nothing */
-    0,  /*    COMMENT => nothing */
-    0,  /*   FUNCTION => nothing */
-    0,  /*     COLUMN => nothing */
-    0,  /* AGG_FUNCTION => nothing */
-    0,  /* AGG_COLUMN => nothing */
-    0,  /* CONST_FUNC => nothing */
     0,  /*       SEMI => nothing */
-   30,  /*    EXPLAIN => ID */
-   30,  /*      QUERY => ID */
-   30,  /*       PLAN => ID */
-   30,  /*      BEGIN => ID */
+   23,  /*    EXPLAIN => ID */
+   23,  /*      QUERY => ID */
+   23,  /*       PLAN => ID */
+   23,  /*      BEGIN => ID */
     0,  /* TRANSACTION => nothing */
-   30,  /*   DEFERRED => ID */
-   30,  /*  IMMEDIATE => ID */
-   30,  /*  EXCLUSIVE => ID */
+   23,  /*   DEFERRED => ID */
+   23,  /*  IMMEDIATE => ID */
+   23,  /*  EXCLUSIVE => ID */
     0,  /*     COMMIT => nothing */
-   30,  /*        END => ID */
+   23,  /*        END => ID */
     0,  /*   ROLLBACK => nothing */
     0,  /*     CREATE => nothing */
     0,  /*      TABLE => nothing */
-   30,  /*       TEMP => ID */
+   23,  /*         IF => ID */
+    0,  /*        NOT => nothing */
+    0,  /*     EXISTS => nothing */
+   23,  /*       TEMP => ID */
     0,  /*         LP => nothing */
     0,  /*         RP => nothing */
     0,  /*         AS => nothing */
     0,  /*      COMMA => nothing */
     0,  /*         ID => nothing */
-   30,  /*      ABORT => ID */
-   30,  /*      AFTER => ID */
-   30,  /*    ANALYZE => ID */
-   30,  /*        ASC => ID */
-   30,  /*     ATTACH => ID */
-   30,  /*     BEFORE => ID */
-   30,  /*    CASCADE => ID */
-   30,  /*       CAST => ID */
-   30,  /*   CONFLICT => ID */
-   30,  /*   DATABASE => ID */
-   30,  /*       DESC => ID */
-   30,  /*     DETACH => ID */
-   30,  /*       EACH => ID */
-   30,  /*       FAIL => ID */
-   30,  /*        FOR => ID */
-   30,  /*     IGNORE => ID */
-   30,  /*  INITIALLY => ID */
-   30,  /*    INSTEAD => ID */
-   30,  /*    LIKE_KW => ID */
-   30,  /*      MATCH => ID */
-   30,  /*        KEY => ID */
-   30,  /*         OF => ID */
-   30,  /*     OFFSET => ID */
-   30,  /*     PRAGMA => ID */
-   30,  /*      RAISE => ID */
-   30,  /*    REPLACE => ID */
-   30,  /*   RESTRICT => ID */
-   30,  /*        ROW => ID */
-   30,  /*  STATEMENT => ID */
-   30,  /*    TRIGGER => ID */
-   30,  /*     VACUUM => ID */
-   30,  /*       VIEW => ID */
-   30,  /*    REINDEX => ID */
-   30,  /*     RENAME => ID */
-   30,  /*   CTIME_KW => ID */
-   30,  /*      ALTER => ID */
+   23,  /*      ABORT => ID */
+   23,  /*      AFTER => ID */
+   23,  /*    ANALYZE => ID */
+   23,  /*        ASC => ID */
+   23,  /*     ATTACH => ID */
+   23,  /*     BEFORE => ID */
+   23,  /*    CASCADE => ID */
+   23,  /*       CAST => ID */
+   23,  /*   CONFLICT => ID */
+   23,  /*   DATABASE => ID */
+   23,  /*       DESC => ID */
+   23,  /*     DETACH => ID */
+   23,  /*       EACH => ID */
+   23,  /*       FAIL => ID */
+   23,  /*        FOR => ID */
+   23,  /*     IGNORE => ID */
+   23,  /*  INITIALLY => ID */
+   23,  /*    INSTEAD => ID */
+   23,  /*    LIKE_KW => ID */
+   23,  /*      MATCH => ID */
+   23,  /*        KEY => ID */
+   23,  /*         OF => ID */
+   23,  /*     OFFSET => ID */
+   23,  /*     PRAGMA => ID */
+   23,  /*      RAISE => ID */
+   23,  /*    REPLACE => ID */
+   23,  /*   RESTRICT => ID */
+   23,  /*        ROW => ID */
+   23,  /*  STATEMENT => ID */
+   23,  /*    TRIGGER => ID */
+   23,  /*     VACUUM => ID */
+   23,  /*       VIEW => ID */
+   23,  /*    REINDEX => ID */
+   23,  /*     RENAME => ID */
+   23,  /*   CTIME_KW => ID */
     0,  /*         OR => nothing */
     0,  /*        AND => nothing */
-    0,  /*        NOT => nothing */
     0,  /*         IS => nothing */
     0,  /*    BETWEEN => nothing */
     0,  /*         IN => nothing */
@@ -797,8 +690,8 @@
     0,  /*       DROP => nothing */
     0,  /*      UNION => nothing */
     0,  /*        ALL => nothing */
-    0,  /*  INTERSECT => nothing */
     0,  /*     EXCEPT => nothing */
+    0,  /*  INTERSECT => nothing */
     0,  /*     SELECT => nothing */
     0,  /*   DISTINCT => nothing */
     0,  /*        DOT => nothing */
@@ -818,12 +711,12 @@
     0,  /*       BLOB => nothing */
     0,  /*   REGISTER => nothing */
     0,  /*   VARIABLE => nothing */
-    0,  /*     EXISTS => nothing */
     0,  /*       CASE => nothing */
     0,  /*       WHEN => nothing */
     0,  /*       THEN => nothing */
     0,  /*       ELSE => nothing */
     0,  /*      INDEX => nothing */
+    0,  /*      ALTER => nothing */
     0,  /*         TO => nothing */
     0,  /*        ADD => nothing */
     0,  /*   COLUMNKW => nothing */
@@ -897,46 +790,44 @@
 /* For tracing shifts, the names of all terminals and nonterminals
 ** are required.  The following table supplies these names */
 static const char *const yyTokenName[] = { 
-  "$",             "END_OF_FILE",   "ILLEGAL",       "SPACE",       
-  "UNCLOSED_STRING",  "COMMENT",       "FUNCTION",      "COLUMN",      
-  "AGG_FUNCTION",  "AGG_COLUMN",    "CONST_FUNC",    "SEMI",        
-  "EXPLAIN",       "QUERY",         "PLAN",          "BEGIN",       
-  "TRANSACTION",   "DEFERRED",      "IMMEDIATE",     "EXCLUSIVE",   
-  "COMMIT",        "END",           "ROLLBACK",      "CREATE",      
-  "TABLE",         "TEMP",          "LP",            "RP",          
-  "AS",            "COMMA",         "ID",            "ABORT",       
-  "AFTER",         "ANALYZE",       "ASC",           "ATTACH",      
-  "BEFORE",        "CASCADE",       "CAST",          "CONFLICT",    
-  "DATABASE",      "DESC",          "DETACH",        "EACH",        
-  "FAIL",          "FOR",           "IGNORE",        "INITIALLY",   
-  "INSTEAD",       "LIKE_KW",       "MATCH",         "KEY",         
-  "OF",            "OFFSET",        "PRAGMA",        "RAISE",       
-  "REPLACE",       "RESTRICT",      "ROW",           "STATEMENT",   
-  "TRIGGER",       "VACUUM",        "VIEW",          "REINDEX",     
-  "RENAME",        "CTIME_KW",      "ALTER",         "OR",          
-  "AND",           "NOT",           "IS",            "BETWEEN",     
-  "IN",            "ISNULL",        "NOTNULL",       "NE",          
-  "EQ",            "GT",            "LE",            "LT",          
-  "GE",            "ESCAPE",        "BITAND",        "BITOR",       
-  "LSHIFT",        "RSHIFT",        "PLUS",          "MINUS",       
-  "STAR",          "SLASH",         "REM",           "CONCAT",      
-  "UMINUS",        "UPLUS",         "BITNOT",        "STRING",      
-  "JOIN_KW",       "CONSTRAINT",    "DEFAULT",       "NULL",        
-  "PRIMARY",       "UNIQUE",        "CHECK",         "REFERENCES",  
-  "COLLATE",       "AUTOINCR",      "ON",            "DELETE",      
-  "UPDATE",        "INSERT",        "SET",           "DEFERRABLE",  
-  "FOREIGN",       "DROP",          "UNION",         "ALL",         
-  "INTERSECT",     "EXCEPT",        "SELECT",        "DISTINCT",    
-  "DOT",           "FROM",          "JOIN",          "USING",       
-  "ORDER",         "BY",            "GROUP",         "HAVING",      
-  "LIMIT",         "WHERE",         "INTO",          "VALUES",      
-  "INTEGER",       "FLOAT",         "BLOB",          "REGISTER",    
-  "VARIABLE",      "EXISTS",        "CASE",          "WHEN",        
-  "THEN",          "ELSE",          "INDEX",         "TO",          
-  "ADD",           "COLUMNKW",      "error",         "input",       
-  "cmdlist",       "ecmd",          "cmdx",          "cmd",         
-  "explain",       "transtype",     "trans_opt",     "nm",          
-  "create_table",  "create_table_args",  "temp",          "dbnm",        
+  "$",             "SEMI",          "EXPLAIN",       "QUERY",       
+  "PLAN",          "BEGIN",         "TRANSACTION",   "DEFERRED",    
+  "IMMEDIATE",     "EXCLUSIVE",     "COMMIT",        "END",         
+  "ROLLBACK",      "CREATE",        "TABLE",         "IF",          
+  "NOT",           "EXISTS",        "TEMP",          "LP",          
+  "RP",            "AS",            "COMMA",         "ID",          
+  "ABORT",         "AFTER",         "ANALYZE",       "ASC",         
+  "ATTACH",        "BEFORE",        "CASCADE",       "CAST",        
+  "CONFLICT",      "DATABASE",      "DESC",          "DETACH",      
+  "EACH",          "FAIL",          "FOR",           "IGNORE",      
+  "INITIALLY",     "INSTEAD",       "LIKE_KW",       "MATCH",       
+  "KEY",           "OF",            "OFFSET",        "PRAGMA",      
+  "RAISE",         "REPLACE",       "RESTRICT",      "ROW",         
+  "STATEMENT",     "TRIGGER",       "VACUUM",        "VIEW",        
+  "REINDEX",       "RENAME",        "CTIME_KW",      "OR",          
+  "AND",           "IS",            "BETWEEN",       "IN",          
+  "ISNULL",        "NOTNULL",       "NE",            "EQ",          
+  "GT",            "LE",            "LT",            "GE",          
+  "ESCAPE",        "BITAND",        "BITOR",         "LSHIFT",      
+  "RSHIFT",        "PLUS",          "MINUS",         "STAR",        
+  "SLASH",         "REM",           "CONCAT",        "UMINUS",      
+  "UPLUS",         "BITNOT",        "STRING",        "JOIN_KW",     
+  "CONSTRAINT",    "DEFAULT",       "NULL",          "PRIMARY",     
+  "UNIQUE",        "CHECK",         "REFERENCES",    "COLLATE",     
+  "AUTOINCR",      "ON",            "DELETE",        "UPDATE",      
+  "INSERT",        "SET",           "DEFERRABLE",    "FOREIGN",     
+  "DROP",          "UNION",         "ALL",           "EXCEPT",      
+  "INTERSECT",     "SELECT",        "DISTINCT",      "DOT",         
+  "FROM",          "JOIN",          "USING",         "ORDER",       
+  "BY",            "GROUP",         "HAVING",        "LIMIT",       
+  "WHERE",         "INTO",          "VALUES",        "INTEGER",     
+  "FLOAT",         "BLOB",          "REGISTER",      "VARIABLE",    
+  "CASE",          "WHEN",          "THEN",          "ELSE",        
+  "INDEX",         "ALTER",         "TO",            "ADD",         
+  "COLUMNKW",      "error",         "input",         "cmdlist",     
+  "ecmd",          "cmdx",          "cmd",           "explain",     
+  "transtype",     "trans_opt",     "nm",            "create_table",
+  "create_table_args",  "temp",          "ifnotexists",   "dbnm",        
   "columnlist",    "conslist_opt",  "select",        "column",      
   "columnid",      "type",          "carglist",      "id",          
   "ids",           "typetoken",     "typename",      "signed",      
@@ -945,20 +836,20 @@
   "autoinc",       "idxlist_opt",   "refargs",       "defer_subclause",
   "refarg",        "refact",        "init_deferred_pred_opt",  "conslist",    
   "tcons",         "idxlist",       "defer_subclause_opt",  "orconf",      
-  "resolvetype",   "raisetype",     "fullname",      "oneselect",   
-  "multiselect_op",  "distinct",      "selcollist",    "from",        
-  "where_opt",     "groupby_opt",   "having_opt",    "orderby_opt", 
-  "limit_opt",     "sclp",          "as",            "seltablist",  
-  "stl_prefix",    "joinop",        "on_opt",        "using_opt",   
-  "seltablist_paren",  "joinop2",       "inscollist",    "sortlist",    
-  "sortitem",      "collate",       "exprlist",      "setlist",     
-  "insert_cmd",    "inscollist_opt",  "itemlist",      "likeop",      
-  "escape",        "between_op",    "in_op",         "case_operand",
-  "case_exprlist",  "case_else",     "expritem",      "uniqueflag",  
-  "idxitem",       "plus_opt",      "number",        "trigger_decl",
-  "trigger_cmd_list",  "trigger_time",  "trigger_event",  "foreach_clause",
-  "when_clause",   "trigger_cmd",   "database_kw_opt",  "key_opt",     
-  "add_column_fullname",  "kwcolumn_opt",
+  "resolvetype",   "raisetype",     "ifexists",      "fullname",    
+  "oneselect",     "multiselect_op",  "distinct",      "selcollist",  
+  "from",          "where_opt",     "groupby_opt",   "having_opt",  
+  "orderby_opt",   "limit_opt",     "sclp",          "as",          
+  "seltablist",    "stl_prefix",    "joinop",        "on_opt",      
+  "using_opt",     "seltablist_paren",  "joinop2",       "inscollist",  
+  "sortlist",      "sortitem",      "collate",       "exprlist",    
+  "setlist",       "insert_cmd",    "inscollist_opt",  "itemlist",    
+  "likeop",        "escape",        "between_op",    "in_op",       
+  "case_operand",  "case_exprlist",  "case_else",     "expritem",    
+  "uniqueflag",    "idxitem",       "plus_opt",      "number",      
+  "trigger_decl",  "trigger_cmd_list",  "trigger_time",  "trigger_event",
+  "foreach_clause",  "when_clause",   "trigger_cmd",   "database_kw_opt",
+  "key_opt",       "add_column_fullname",  "kwcolumn_opt",
 };
 #endif /* NDEBUG */
 
@@ -987,296 +878,280 @@
  /*  18 */ "cmd ::= END trans_opt",
  /*  19 */ "cmd ::= ROLLBACK trans_opt",
  /*  20 */ "cmd ::= create_table create_table_args",
- /*  21 */ "create_table ::= CREATE temp TABLE nm dbnm",
- /*  22 */ "temp ::= TEMP",
- /*  23 */ "temp ::=",
- /*  24 */ "create_table_args ::= LP columnlist conslist_opt RP",
- /*  25 */ "create_table_args ::= AS select",
- /*  26 */ "columnlist ::= columnlist COMMA column",
- /*  27 */ "columnlist ::= column",
- /*  28 */ "column ::= columnid type carglist",
- /*  29 */ "columnid ::= nm",
- /*  30 */ "id ::= ID",
- /*  31 */ "ids ::= ID",
- /*  32 */ "ids ::= STRING",
- /*  33 */ "nm ::= ID",
- /*  34 */ "nm ::= STRING",
- /*  35 */ "nm ::= JOIN_KW",
- /*  36 */ "type ::=",
- /*  37 */ "type ::= typetoken",
- /*  38 */ "typetoken ::= typename",
- /*  39 */ "typetoken ::= typename LP signed RP",
- /*  40 */ "typetoken ::= typename LP signed COMMA signed RP",
- /*  41 */ "typename ::= ids",
- /*  42 */ "typename ::= typename ids",
- /*  43 */ "signed ::= plus_num",
- /*  44 */ "signed ::= minus_num",
- /*  45 */ "carglist ::= carglist carg",
- /*  46 */ "carglist ::=",
- /*  47 */ "carg ::= CONSTRAINT nm ccons",
- /*  48 */ "carg ::= ccons",
- /*  49 */ "carg ::= DEFAULT term",
- /*  50 */ "carg ::= DEFAULT LP expr RP",
- /*  51 */ "carg ::= DEFAULT PLUS term",
- /*  52 */ "carg ::= DEFAULT MINUS term",
- /*  53 */ "carg ::= DEFAULT id",
- /*  54 */ "ccons ::= NULL onconf",
- /*  55 */ "ccons ::= NOT NULL onconf",
- /*  56 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /*  57 */ "ccons ::= UNIQUE onconf",
- /*  58 */ "ccons ::= CHECK LP expr RP onconf",
- /*  59 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
- /*  60 */ "ccons ::= defer_subclause",
- /*  61 */ "ccons ::= COLLATE id",
- /*  62 */ "autoinc ::=",
- /*  63 */ "autoinc ::= AUTOINCR",
- /*  64 */ "refargs ::=",
- /*  65 */ "refargs ::= refargs refarg",
- /*  66 */ "refarg ::= MATCH nm",
- /*  67 */ "refarg ::= ON DELETE refact",
- /*  68 */ "refarg ::= ON UPDATE refact",
- /*  69 */ "refarg ::= ON INSERT refact",
- /*  70 */ "refact ::= SET NULL",
- /*  71 */ "refact ::= SET DEFAULT",
- /*  72 */ "refact ::= CASCADE",
- /*  73 */ "refact ::= RESTRICT",
- /*  74 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /*  75 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /*  76 */ "init_deferred_pred_opt ::=",
- /*  77 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /*  78 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /*  79 */ "conslist_opt ::=",
- /*  80 */ "conslist_opt ::= COMMA conslist",
- /*  81 */ "conslist ::= conslist COMMA tcons",
- /*  82 */ "conslist ::= conslist tcons",
- /*  83 */ "conslist ::= tcons",
- /*  84 */ "tcons ::= CONSTRAINT nm",
- /*  85 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /*  86 */ "tcons ::= UNIQUE LP idxlist RP onconf",
- /*  87 */ "tcons ::= CHECK expr onconf",
- /*  88 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
- /*  89 */ "defer_subclause_opt ::=",
- /*  90 */ "defer_subclause_opt ::= defer_subclause",
- /*  91 */ "onconf ::=",
- /*  92 */ "onconf ::= ON CONFLICT resolvetype",
- /*  93 */ "orconf ::=",
- /*  94 */ "orconf ::= OR resolvetype",
- /*  95 */ "resolvetype ::= raisetype",
- /*  96 */ "resolvetype ::= IGNORE",
- /*  97 */ "resolvetype ::= REPLACE",
- /*  98 */ "cmd ::= DROP TABLE fullname",
- /*  99 */ "cmd ::= CREATE temp VIEW nm dbnm AS select",
- /* 100 */ "cmd ::= DROP VIEW fullname",
- /* 101 */ "cmd ::= select",
- /* 102 */ "select ::= oneselect",
- /* 103 */ "select ::= select multiselect_op oneselect",
- /* 104 */ "multiselect_op ::= UNION",
- /* 105 */ "multiselect_op ::= UNION ALL",
- /* 106 */ "multiselect_op ::= INTERSECT",
- /* 107 */ "multiselect_op ::= EXCEPT",
- /* 108 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 109 */ "distinct ::= DISTINCT",
- /* 110 */ "distinct ::= ALL",
- /* 111 */ "distinct ::=",
- /* 112 */ "sclp ::= selcollist COMMA",
- /* 113 */ "sclp ::=",
- /* 114 */ "selcollist ::= sclp expr as",
- /* 115 */ "selcollist ::= sclp STAR",
- /* 116 */ "selcollist ::= sclp nm DOT STAR",
- /* 117 */ "as ::= AS nm",
- /* 118 */ "as ::= ids",
- /* 119 */ "as ::=",
- /* 120 */ "from ::=",
- /* 121 */ "from ::= FROM seltablist",
- /* 122 */ "stl_prefix ::= seltablist joinop",
- /* 123 */ "stl_prefix ::=",
- /* 124 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt",
- /* 125 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
- /* 126 */ "seltablist_paren ::= select",
- /* 127 */ "seltablist_paren ::= seltablist",
- /* 128 */ "dbnm ::=",
- /* 129 */ "dbnm ::= DOT nm",
- /* 130 */ "fullname ::= nm dbnm",
- /* 131 */ "joinop ::= COMMA",
- /* 132 */ "joinop ::= JOIN",
- /* 133 */ "joinop ::= JOIN_KW JOIN",
- /* 134 */ "joinop ::= JOIN_KW nm JOIN",
- /* 135 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 136 */ "on_opt ::= ON expr",
- /* 137 */ "on_opt ::=",
- /* 138 */ "using_opt ::= USING LP inscollist RP",
- /* 139 */ "using_opt ::=",
- /* 140 */ "orderby_opt ::=",
- /* 141 */ "orderby_opt ::= ORDER BY sortlist",
- /* 142 */ "sortlist ::= sortlist COMMA sortitem collate sortorder",
- /* 143 */ "sortlist ::= sortitem collate sortorder",
- /* 144 */ "sortitem ::= expr",
- /* 145 */ "sortorder ::= ASC",
- /* 146 */ "sortorder ::= DESC",
- /* 147 */ "sortorder ::=",
- /* 148 */ "collate ::=",
- /* 149 */ "collate ::= COLLATE id",
- /* 150 */ "groupby_opt ::=",
- /* 151 */ "groupby_opt ::= GROUP BY exprlist",
- /* 152 */ "having_opt ::=",
- /* 153 */ "having_opt ::= HAVING expr",
- /* 154 */ "limit_opt ::=",
- /* 155 */ "limit_opt ::= LIMIT expr",
- /* 156 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 157 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 158 */ "cmd ::= DELETE FROM fullname where_opt",
- /* 159 */ "where_opt ::=",
- /* 160 */ "where_opt ::= WHERE expr",
- /* 161 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt",
- /* 162 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 163 */ "setlist ::= nm EQ expr",
- /* 164 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
- /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 166 */ "insert_cmd ::= INSERT orconf",
- /* 167 */ "insert_cmd ::= REPLACE",
- /* 168 */ "itemlist ::= itemlist COMMA expr",
- /* 169 */ "itemlist ::= expr",
- /* 170 */ "inscollist_opt ::=",
- /* 171 */ "inscollist_opt ::= LP inscollist RP",
- /* 172 */ "inscollist ::= inscollist COMMA nm",
- /* 173 */ "inscollist ::= nm",
- /* 174 */ "expr ::= term",
- /* 175 */ "expr ::= LP expr RP",
- /* 176 */ "term ::= NULL",
- /* 177 */ "expr ::= ID",
- /* 178 */ "expr ::= JOIN_KW",
- /* 179 */ "expr ::= nm DOT nm",
- /* 180 */ "expr ::= nm DOT nm DOT nm",
- /* 181 */ "term ::= INTEGER",
- /* 182 */ "term ::= FLOAT",
+ /*  21 */ "create_table ::= CREATE temp TABLE ifnotexists nm dbnm",
+ /*  22 */ "ifnotexists ::=",
+ /*  23 */ "ifnotexists ::= IF NOT EXISTS",
+ /*  24 */ "temp ::= TEMP",
+ /*  25 */ "temp ::=",
+ /*  26 */ "create_table_args ::= LP columnlist conslist_opt RP",
+ /*  27 */ "create_table_args ::= AS select",
+ /*  28 */ "columnlist ::= columnlist COMMA column",
+ /*  29 */ "columnlist ::= column",
+ /*  30 */ "column ::= columnid type carglist",
+ /*  31 */ "columnid ::= nm",
+ /*  32 */ "id ::= ID",
+ /*  33 */ "ids ::= ID|STRING",
+ /*  34 */ "nm ::= ID",
+ /*  35 */ "nm ::= STRING",
+ /*  36 */ "nm ::= JOIN_KW",
+ /*  37 */ "type ::=",
+ /*  38 */ "type ::= typetoken",
+ /*  39 */ "typetoken ::= typename",
+ /*  40 */ "typetoken ::= typename LP signed RP",
+ /*  41 */ "typetoken ::= typename LP signed COMMA signed RP",
+ /*  42 */ "typename ::= ids",
+ /*  43 */ "typename ::= typename ids",
+ /*  44 */ "signed ::= plus_num",
+ /*  45 */ "signed ::= minus_num",
+ /*  46 */ "carglist ::= carglist carg",
+ /*  47 */ "carglist ::=",
+ /*  48 */ "carg ::= CONSTRAINT nm ccons",
+ /*  49 */ "carg ::= ccons",
+ /*  50 */ "carg ::= DEFAULT term",
+ /*  51 */ "carg ::= DEFAULT LP expr RP",
+ /*  52 */ "carg ::= DEFAULT PLUS term",
+ /*  53 */ "carg ::= DEFAULT MINUS term",
+ /*  54 */ "carg ::= DEFAULT id",
+ /*  55 */ "ccons ::= NULL onconf",
+ /*  56 */ "ccons ::= NOT NULL onconf",
+ /*  57 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /*  58 */ "ccons ::= UNIQUE onconf",
+ /*  59 */ "ccons ::= CHECK LP expr RP",
+ /*  60 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+ /*  61 */ "ccons ::= defer_subclause",
+ /*  62 */ "ccons ::= COLLATE id",
+ /*  63 */ "autoinc ::=",
+ /*  64 */ "autoinc ::= AUTOINCR",
+ /*  65 */ "refargs ::=",
+ /*  66 */ "refargs ::= refargs refarg",
+ /*  67 */ "refarg ::= MATCH nm",
+ /*  68 */ "refarg ::= ON DELETE refact",
+ /*  69 */ "refarg ::= ON UPDATE refact",
+ /*  70 */ "refarg ::= ON INSERT refact",
+ /*  71 */ "refact ::= SET NULL",
+ /*  72 */ "refact ::= SET DEFAULT",
+ /*  73 */ "refact ::= CASCADE",
+ /*  74 */ "refact ::= RESTRICT",
+ /*  75 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /*  76 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /*  77 */ "init_deferred_pred_opt ::=",
+ /*  78 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /*  79 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /*  80 */ "conslist_opt ::=",
+ /*  81 */ "conslist_opt ::= COMMA conslist",
+ /*  82 */ "conslist ::= conslist COMMA tcons",
+ /*  83 */ "conslist ::= conslist tcons",
+ /*  84 */ "conslist ::= tcons",
+ /*  85 */ "tcons ::= CONSTRAINT nm",
+ /*  86 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
+ /*  87 */ "tcons ::= UNIQUE LP idxlist RP onconf",
+ /*  88 */ "tcons ::= CHECK LP expr RP onconf",
+ /*  89 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+ /*  90 */ "defer_subclause_opt ::=",
+ /*  91 */ "defer_subclause_opt ::= defer_subclause",
+ /*  92 */ "onconf ::=",
+ /*  93 */ "onconf ::= ON CONFLICT resolvetype",
+ /*  94 */ "orconf ::=",
+ /*  95 */ "orconf ::= OR resolvetype",
+ /*  96 */ "resolvetype ::= raisetype",
+ /*  97 */ "resolvetype ::= IGNORE",
+ /*  98 */ "resolvetype ::= REPLACE",
+ /*  99 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 100 */ "ifexists ::= IF EXISTS",
+ /* 101 */ "ifexists ::=",
+ /* 102 */ "cmd ::= CREATE temp VIEW nm dbnm AS select",
+ /* 103 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 104 */ "cmd ::= select",
+ /* 105 */ "select ::= oneselect",
+ /* 106 */ "select ::= select multiselect_op oneselect",
+ /* 107 */ "multiselect_op ::= UNION",
+ /* 108 */ "multiselect_op ::= UNION ALL",
+ /* 109 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 110 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 111 */ "distinct ::= DISTINCT",
+ /* 112 */ "distinct ::= ALL",
+ /* 113 */ "distinct ::=",
+ /* 114 */ "sclp ::= selcollist COMMA",
+ /* 115 */ "sclp ::=",
+ /* 116 */ "selcollist ::= sclp expr as",
+ /* 117 */ "selcollist ::= sclp STAR",
+ /* 118 */ "selcollist ::= sclp nm DOT STAR",
+ /* 119 */ "as ::= AS nm",
+ /* 120 */ "as ::= ids",
+ /* 121 */ "as ::=",
+ /* 122 */ "from ::=",
+ /* 123 */ "from ::= FROM seltablist",
+ /* 124 */ "stl_prefix ::= seltablist joinop",
+ /* 125 */ "stl_prefix ::=",
+ /* 126 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt",
+ /* 127 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
+ /* 128 */ "seltablist_paren ::= select",
+ /* 129 */ "seltablist_paren ::= seltablist",
+ /* 130 */ "dbnm ::=",
+ /* 131 */ "dbnm ::= DOT nm",
+ /* 132 */ "fullname ::= nm dbnm",
+ /* 133 */ "joinop ::= COMMA|JOIN",
+ /* 134 */ "joinop ::= JOIN_KW JOIN",
+ /* 135 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 136 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 137 */ "on_opt ::= ON expr",
+ /* 138 */ "on_opt ::=",
+ /* 139 */ "using_opt ::= USING LP inscollist RP",
+ /* 140 */ "using_opt ::=",
+ /* 141 */ "orderby_opt ::=",
+ /* 142 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 143 */ "sortlist ::= sortlist COMMA sortitem collate sortorder",
+ /* 144 */ "sortlist ::= sortitem collate sortorder",
+ /* 145 */ "sortitem ::= expr",
+ /* 146 */ "sortorder ::= ASC",
+ /* 147 */ "sortorder ::= DESC",
+ /* 148 */ "sortorder ::=",
+ /* 149 */ "collate ::=",
+ /* 150 */ "collate ::= COLLATE id",
+ /* 151 */ "groupby_opt ::=",
+ /* 152 */ "groupby_opt ::= GROUP BY exprlist",
+ /* 153 */ "having_opt ::=",
+ /* 154 */ "having_opt ::= HAVING expr",
+ /* 155 */ "limit_opt ::=",
+ /* 156 */ "limit_opt ::= LIMIT expr",
+ /* 157 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 158 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 159 */ "cmd ::= DELETE FROM fullname where_opt",
+ /* 160 */ "where_opt ::=",
+ /* 161 */ "where_opt ::= WHERE expr",
+ /* 162 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt",
+ /* 163 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 164 */ "setlist ::= nm EQ expr",
+ /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
+ /* 166 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
+ /* 167 */ "insert_cmd ::= INSERT orconf",
+ /* 168 */ "insert_cmd ::= REPLACE",
+ /* 169 */ "itemlist ::= itemlist COMMA expr",
+ /* 170 */ "itemlist ::= expr",
+ /* 171 */ "inscollist_opt ::=",
+ /* 172 */ "inscollist_opt ::= LP inscollist RP",
+ /* 173 */ "inscollist ::= inscollist COMMA nm",
+ /* 174 */ "inscollist ::= nm",
+ /* 175 */ "expr ::= term",
+ /* 176 */ "expr ::= LP expr RP",
+ /* 177 */ "term ::= NULL",
+ /* 178 */ "expr ::= ID",
+ /* 179 */ "expr ::= JOIN_KW",
+ /* 180 */ "expr ::= nm DOT nm",
+ /* 181 */ "expr ::= nm DOT nm DOT nm",
+ /* 182 */ "term ::= INTEGER|FLOAT|BLOB",
  /* 183 */ "term ::= STRING",
- /* 184 */ "term ::= BLOB",
- /* 185 */ "expr ::= REGISTER",
- /* 186 */ "expr ::= VARIABLE",
- /* 187 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 188 */ "expr ::= ID LP distinct exprlist RP",
- /* 189 */ "expr ::= ID LP STAR RP",
- /* 190 */ "term ::= CTIME_KW",
- /* 191 */ "expr ::= expr AND expr",
- /* 192 */ "expr ::= expr OR expr",
- /* 193 */ "expr ::= expr LT expr",
- /* 194 */ "expr ::= expr GT expr",
- /* 195 */ "expr ::= expr LE expr",
- /* 196 */ "expr ::= expr GE expr",
- /* 197 */ "expr ::= expr NE expr",
- /* 198 */ "expr ::= expr EQ expr",
- /* 199 */ "expr ::= expr BITAND expr",
- /* 200 */ "expr ::= expr BITOR expr",
- /* 201 */ "expr ::= expr LSHIFT expr",
- /* 202 */ "expr ::= expr RSHIFT expr",
- /* 203 */ "expr ::= expr PLUS expr",
- /* 204 */ "expr ::= expr MINUS expr",
- /* 205 */ "expr ::= expr STAR expr",
- /* 206 */ "expr ::= expr SLASH expr",
- /* 207 */ "expr ::= expr REM expr",
- /* 208 */ "expr ::= expr CONCAT expr",
- /* 209 */ "likeop ::= LIKE_KW",
- /* 210 */ "likeop ::= NOT LIKE_KW",
- /* 211 */ "escape ::= ESCAPE expr",
- /* 212 */ "escape ::=",
- /* 213 */ "expr ::= expr likeop expr escape",
- /* 214 */ "expr ::= expr ISNULL",
- /* 215 */ "expr ::= expr IS NULL",
- /* 216 */ "expr ::= expr NOTNULL",
- /* 217 */ "expr ::= expr NOT NULL",
- /* 218 */ "expr ::= expr IS NOT NULL",
- /* 219 */ "expr ::= NOT expr",
- /* 220 */ "expr ::= BITNOT expr",
- /* 221 */ "expr ::= MINUS expr",
- /* 222 */ "expr ::= PLUS expr",
- /* 223 */ "between_op ::= BETWEEN",
- /* 224 */ "between_op ::= NOT BETWEEN",
- /* 225 */ "expr ::= expr between_op expr AND expr",
- /* 226 */ "in_op ::= IN",
- /* 227 */ "in_op ::= NOT IN",
- /* 228 */ "expr ::= expr in_op LP exprlist RP",
- /* 229 */ "expr ::= LP select RP",
- /* 230 */ "expr ::= expr in_op LP select RP",
- /* 231 */ "expr ::= expr in_op nm dbnm",
- /* 232 */ "expr ::= EXISTS LP select RP",
- /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 235 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 236 */ "case_else ::= ELSE expr",
- /* 237 */ "case_else ::=",
- /* 238 */ "case_operand ::= expr",
- /* 239 */ "case_operand ::=",
- /* 240 */ "exprlist ::= exprlist COMMA expritem",
- /* 241 */ "exprlist ::= expritem",
- /* 242 */ "expritem ::= expr",
- /* 243 */ "expritem ::=",
- /* 244 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf",
- /* 245 */ "uniqueflag ::= UNIQUE",
- /* 246 */ "uniqueflag ::=",
- /* 247 */ "idxlist_opt ::=",
- /* 248 */ "idxlist_opt ::= LP idxlist RP",
- /* 249 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
- /* 250 */ "idxlist ::= idxitem collate sortorder",
- /* 251 */ "idxitem ::= nm",
- /* 252 */ "cmd ::= DROP INDEX fullname",
- /* 253 */ "cmd ::= VACUUM",
- /* 254 */ "cmd ::= VACUUM nm",
- /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nm",
- /* 256 */ "cmd ::= PRAGMA nm dbnm EQ ON",
- /* 257 */ "cmd ::= PRAGMA nm dbnm EQ plus_num",
- /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 259 */ "cmd ::= PRAGMA nm dbnm LP nm RP",
- /* 260 */ "cmd ::= PRAGMA nm dbnm",
- /* 261 */ "plus_num ::= plus_opt number",
- /* 262 */ "minus_num ::= MINUS number",
- /* 263 */ "number ::= INTEGER",
- /* 264 */ "number ::= FLOAT",
- /* 265 */ "plus_opt ::= PLUS",
- /* 266 */ "plus_opt ::=",
- /* 267 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
- /* 268 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 269 */ "trigger_time ::= BEFORE",
- /* 270 */ "trigger_time ::= AFTER",
- /* 271 */ "trigger_time ::= INSTEAD OF",
- /* 272 */ "trigger_time ::=",
- /* 273 */ "trigger_event ::= DELETE",
- /* 274 */ "trigger_event ::= INSERT",
- /* 275 */ "trigger_event ::= UPDATE",
- /* 276 */ "trigger_event ::= UPDATE OF inscollist",
- /* 277 */ "foreach_clause ::=",
- /* 278 */ "foreach_clause ::= FOR EACH ROW",
- /* 279 */ "foreach_clause ::= FOR EACH STATEMENT",
- /* 280 */ "when_clause ::=",
- /* 281 */ "when_clause ::= WHEN expr",
- /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list",
- /* 283 */ "trigger_cmd_list ::=",
- /* 284 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
- /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
- /* 286 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
- /* 287 */ "trigger_cmd ::= DELETE FROM nm where_opt",
- /* 288 */ "trigger_cmd ::= select",
- /* 289 */ "expr ::= RAISE LP IGNORE RP",
- /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 291 */ "raisetype ::= ROLLBACK",
- /* 292 */ "raisetype ::= ABORT",
- /* 293 */ "raisetype ::= FAIL",
- /* 294 */ "cmd ::= DROP TRIGGER fullname",
- /* 295 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt",
- /* 296 */ "key_opt ::=",
- /* 297 */ "key_opt ::= KEY ids",
- /* 298 */ "key_opt ::= KEY BLOB",
- /* 299 */ "database_kw_opt ::= DATABASE",
- /* 300 */ "database_kw_opt ::=",
- /* 301 */ "cmd ::= DETACH database_kw_opt nm",
- /* 302 */ "cmd ::= REINDEX",
- /* 303 */ "cmd ::= REINDEX nm dbnm",
- /* 304 */ "cmd ::= ANALYZE",
- /* 305 */ "cmd ::= ANALYZE nm dbnm",
- /* 306 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 307 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 308 */ "add_column_fullname ::= fullname",
- /* 309 */ "kwcolumn_opt ::=",
- /* 310 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 184 */ "expr ::= REGISTER",
+ /* 185 */ "expr ::= VARIABLE",
+ /* 186 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 187 */ "expr ::= ID LP distinct exprlist RP",
+ /* 188 */ "expr ::= ID LP STAR RP",
+ /* 189 */ "term ::= CTIME_KW",
+ /* 190 */ "expr ::= expr AND expr",
+ /* 191 */ "expr ::= expr OR expr",
+ /* 192 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 193 */ "expr ::= expr EQ|NE expr",
+ /* 194 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 195 */ "expr ::= expr PLUS|MINUS expr",
+ /* 196 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 197 */ "expr ::= expr CONCAT expr",
+ /* 198 */ "likeop ::= LIKE_KW",
+ /* 199 */ "likeop ::= NOT LIKE_KW",
+ /* 200 */ "escape ::= ESCAPE expr",
+ /* 201 */ "escape ::=",
+ /* 202 */ "expr ::= expr likeop expr escape",
+ /* 203 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 204 */ "expr ::= expr IS NULL",
+ /* 205 */ "expr ::= expr NOT NULL",
+ /* 206 */ "expr ::= expr IS NOT NULL",
+ /* 207 */ "expr ::= NOT|BITNOT expr",
+ /* 208 */ "expr ::= MINUS expr",
+ /* 209 */ "expr ::= PLUS expr",
+ /* 210 */ "between_op ::= BETWEEN",
+ /* 211 */ "between_op ::= NOT BETWEEN",
+ /* 212 */ "expr ::= expr between_op expr AND expr",
+ /* 213 */ "in_op ::= IN",
+ /* 214 */ "in_op ::= NOT IN",
+ /* 215 */ "expr ::= expr in_op LP exprlist RP",
+ /* 216 */ "expr ::= LP select RP",
+ /* 217 */ "expr ::= expr in_op LP select RP",
+ /* 218 */ "expr ::= expr in_op nm dbnm",
+ /* 219 */ "expr ::= EXISTS LP select RP",
+ /* 220 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 221 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 222 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 223 */ "case_else ::= ELSE expr",
+ /* 224 */ "case_else ::=",
+ /* 225 */ "case_operand ::= expr",
+ /* 226 */ "case_operand ::=",
+ /* 227 */ "exprlist ::= exprlist COMMA expritem",
+ /* 228 */ "exprlist ::= expritem",
+ /* 229 */ "expritem ::= expr",
+ /* 230 */ "expritem ::=",
+ /* 231 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
+ /* 232 */ "uniqueflag ::= UNIQUE",
+ /* 233 */ "uniqueflag ::=",
+ /* 234 */ "idxlist_opt ::=",
+ /* 235 */ "idxlist_opt ::= LP idxlist RP",
+ /* 236 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
+ /* 237 */ "idxlist ::= idxitem collate sortorder",
+ /* 238 */ "idxitem ::= nm",
+ /* 239 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 240 */ "cmd ::= VACUUM",
+ /* 241 */ "cmd ::= VACUUM nm",
+ /* 242 */ "cmd ::= PRAGMA nm dbnm EQ nm",
+ /* 243 */ "cmd ::= PRAGMA nm dbnm EQ ON",
+ /* 244 */ "cmd ::= PRAGMA nm dbnm EQ plus_num",
+ /* 245 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 246 */ "cmd ::= PRAGMA nm dbnm LP nm RP",
+ /* 247 */ "cmd ::= PRAGMA nm dbnm",
+ /* 248 */ "plus_num ::= plus_opt number",
+ /* 249 */ "minus_num ::= MINUS number",
+ /* 250 */ "number ::= INTEGER|FLOAT",
+ /* 251 */ "plus_opt ::= PLUS",
+ /* 252 */ "plus_opt ::=",
+ /* 253 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
+ /* 254 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 255 */ "trigger_time ::= BEFORE",
+ /* 256 */ "trigger_time ::= AFTER",
+ /* 257 */ "trigger_time ::= INSTEAD OF",
+ /* 258 */ "trigger_time ::=",
+ /* 259 */ "trigger_event ::= DELETE|INSERT",
+ /* 260 */ "trigger_event ::= UPDATE",
+ /* 261 */ "trigger_event ::= UPDATE OF inscollist",
+ /* 262 */ "foreach_clause ::=",
+ /* 263 */ "foreach_clause ::= FOR EACH ROW",
+ /* 264 */ "foreach_clause ::= FOR EACH STATEMENT",
+ /* 265 */ "when_clause ::=",
+ /* 266 */ "when_clause ::= WHEN expr",
+ /* 267 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 268 */ "trigger_cmd_list ::=",
+ /* 269 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
+ /* 270 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
+ /* 271 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
+ /* 272 */ "trigger_cmd ::= DELETE FROM nm where_opt",
+ /* 273 */ "trigger_cmd ::= select",
+ /* 274 */ "expr ::= RAISE LP IGNORE RP",
+ /* 275 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 276 */ "raisetype ::= ROLLBACK",
+ /* 277 */ "raisetype ::= ABORT",
+ /* 278 */ "raisetype ::= FAIL",
+ /* 279 */ "cmd ::= DROP TRIGGER fullname",
+ /* 280 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 281 */ "key_opt ::=",
+ /* 282 */ "key_opt ::= KEY expr",
+ /* 283 */ "database_kw_opt ::= DATABASE",
+ /* 284 */ "database_kw_opt ::=",
+ /* 285 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 286 */ "cmd ::= REINDEX",
+ /* 287 */ "cmd ::= REINDEX nm dbnm",
+ /* 288 */ "cmd ::= ANALYZE",
+ /* 289 */ "cmd ::= ANALYZE nm dbnm",
+ /* 290 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 291 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 292 */ "add_column_fullname ::= fullname",
+ /* 293 */ "kwcolumn_opt ::=",
+ /* 294 */ "kwcolumn_opt ::= COLUMNKW",
 };
 #endif /* NDEBUG */
 
@@ -1334,73 +1209,82 @@
     ** which appear on the RHS of the rule, but which are not used
     ** inside the C code.
     */
-    case 162:
-    case 195:
-    case 212:
-#line 370 "parse.y"
-{sqlite3SelectDelete((yypminor->yy375));}
-#line 1344 "parse.c"
+    case 154:
+    case 188:
+    case 205:
+#line 371 "parse.y"
+{sqlite3SelectDelete((yypminor->yy239));}
+#line 1219 "parse.c"
       break;
-    case 176:
-    case 177:
-    case 200:
-    case 202:
-    case 210:
-    case 216:
-    case 230:
-#line 629 "parse.y"
-{sqlite3ExprDelete((yypminor->yy62));}
-#line 1355 "parse.c"
-      break;
-    case 181:
-    case 189:
-    case 198:
-    case 201:
+    case 168:
+    case 169:
+    case 193:
+    case 195:
     case 203:
-    case 205:
-    case 215:
-    case 218:
-    case 219:
+    case 209:
+    case 217:
+    case 220:
     case 222:
-    case 228:
-#line 876 "parse.y"
-{sqlite3ExprListDelete((yypminor->yy418));}
-#line 1370 "parse.c"
+    case 223:
+    case 233:
+#line 628 "parse.y"
+{sqlite3ExprDelete((yypminor->yy178));}
+#line 1234 "parse.c"
       break;
+    case 173:
+    case 181:
+    case 191:
     case 194:
-    case 199:
-    case 207:
+    case 196:
+    case 198:
     case 208:
+    case 211:
+    case 212:
+    case 215:
+    case 221:
+#line 859 "parse.y"
+{sqlite3ExprListDelete((yypminor->yy462));}
+#line 1249 "parse.c"
+      break;
+    case 187:
+    case 192:
+    case 200:
+    case 201:
 #line 499 "parse.y"
-{sqlite3SrcListDelete((yypminor->yy151));}
-#line 1378 "parse.c"
+{sqlite3SrcListDelete((yypminor->yy285));}
+#line 1257 "parse.c"
       break;
-    case 204:
-#line 561 "parse.y"
+    case 197:
+#line 560 "parse.y"
 {
-  sqlite3ExprDelete((yypminor->yy220).pLimit);
-  sqlite3ExprDelete((yypminor->yy220).pOffset);
+  sqlite3ExprDelete((yypminor->yy270).pLimit);
+  sqlite3ExprDelete((yypminor->yy270).pOffset);
 }
-#line 1386 "parse.c"
+#line 1265 "parse.c"
       break;
-    case 211:
+    case 204:
+    case 207:
     case 214:
-    case 221:
-#line 517 "parse.y"
-{sqlite3IdListDelete((yypminor->yy240));}
-#line 1393 "parse.c"
+#line 516 "parse.y"
+{sqlite3IdListDelete((yypminor->yy160));}
+#line 1272 "parse.c"
       break;
-    case 236:
-    case 241:
-#line 969 "parse.y"
-{sqlite3DeleteTriggerStep((yypminor->yy360));}
-#line 1399 "parse.c"
-      break;
-    case 238:
+    case 229:
+    case 234:
 #line 953 "parse.y"
-{sqlite3IdListDelete((yypminor->yy30).b);}
-#line 1404 "parse.c"
+{sqlite3DeleteTriggerStep((yypminor->yy247));}
+#line 1278 "parse.c"
       break;
+    case 231:
+#line 937 "parse.y"
+{sqlite3IdListDelete((yypminor->yy132).b);}
+#line 1283 "parse.c"
+      break;
+    case 236:
+#line 1021 "parse.y"
+{sqlite3ExprDelete((yypminor->yy292));}
+#line 1288 "parse.c"
+      break;
     default:  break;   /* If no destructor action specified: do nothing */
   }
 }
@@ -1468,9 +1352,7 @@
   int i;
   int stateno = pParser->yystack[pParser->yyidx].stateno;
  
-  /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-  i = yy_shift_ofst[stateno];
-  if( i==YY_SHIFT_USE_DFLT ){
+  if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
     return yy_default[stateno];
   }
   if( iLookAhead==YYNOCODE ){
@@ -1512,8 +1394,8 @@
   int i;
   /* int stateno = pParser->yystack[pParser->yyidx].stateno; */
  
-  i = yy_reduce_ofst[stateno];
-  if( i==YY_REDUCE_USE_DFLT ){
+  if( stateno>YY_REDUCE_MAX ||
+      (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){
     return yy_default[stateno];
   }
   if( iLookAhead==YYNOCODE ){
@@ -1549,6 +1431,10 @@
      while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
      /* Here code is inserted which will execute if the parser
      ** stack every overflows */
+#line 43 "parse.y"
+
+  sqlite3ErrorMsg(pParse, "parser stack overflow");
+#line 1440 "parse.c"
      sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
      return;
   }
@@ -1575,317 +1461,301 @@
   YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
   unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
 } yyRuleInfo[] = {
-  { 147, 1 },
-  { 148, 2 },
-  { 148, 1 },
-  { 150, 1 },
+  { 138, 1 },
+  { 139, 2 },
+  { 139, 1 },
+  { 141, 1 },
+  { 140, 1 },
+  { 140, 3 },
+  { 143, 0 },
+  { 143, 1 },
+  { 143, 3 },
+  { 142, 3 },
+  { 145, 0 },
+  { 145, 1 },
+  { 145, 2 },
+  { 144, 0 },
+  { 144, 1 },
+  { 144, 1 },
+  { 144, 1 },
+  { 142, 2 },
+  { 142, 2 },
+  { 142, 2 },
+  { 142, 2 },
+  { 147, 6 },
+  { 150, 0 },
+  { 150, 3 },
   { 149, 1 },
-  { 149, 3 },
-  { 152, 0 },
-  { 152, 1 },
+  { 149, 0 },
+  { 148, 4 },
+  { 148, 2 },
   { 152, 3 },
-  { 151, 3 },
-  { 154, 0 },
-  { 154, 1 },
-  { 154, 2 },
-  { 153, 0 },
-  { 153, 1 },
-  { 153, 1 },
-  { 153, 1 },
-  { 151, 2 },
-  { 151, 2 },
-  { 151, 2 },
-  { 151, 2 },
-  { 156, 5 },
-  { 158, 1 },
-  { 158, 0 },
-  { 157, 4 },
-  { 157, 2 },
-  { 160, 3 },
+  { 152, 1 },
+  { 155, 3 },
+  { 156, 1 },
+  { 159, 1 },
   { 160, 1 },
-  { 163, 3 },
-  { 164, 1 },
-  { 167, 1 },
-  { 168, 1 },
-  { 168, 1 },
-  { 155, 1 },
-  { 155, 1 },
-  { 155, 1 },
-  { 165, 0 },
-  { 165, 1 },
-  { 169, 1 },
-  { 169, 4 },
-  { 169, 6 },
-  { 170, 1 },
-  { 170, 2 },
-  { 171, 1 },
-  { 171, 1 },
+  { 146, 1 },
+  { 146, 1 },
+  { 146, 1 },
+  { 157, 0 },
+  { 157, 1 },
+  { 161, 1 },
+  { 161, 4 },
+  { 161, 6 },
+  { 162, 1 },
+  { 162, 2 },
+  { 163, 1 },
+  { 163, 1 },
+  { 158, 2 },
+  { 158, 0 },
+  { 166, 3 },
+  { 166, 1 },
   { 166, 2 },
-  { 166, 0 },
-  { 174, 3 },
-  { 174, 1 },
+  { 166, 4 },
+  { 166, 3 },
+  { 166, 3 },
+  { 166, 2 },
+  { 167, 2 },
+  { 167, 3 },
+  { 167, 5 },
+  { 167, 2 },
+  { 167, 4 },
+  { 167, 4 },
+  { 167, 1 },
+  { 167, 2 },
+  { 172, 0 },
+  { 172, 1 },
+  { 174, 0 },
   { 174, 2 },
-  { 174, 4 },
-  { 174, 3 },
-  { 174, 3 },
-  { 174, 2 },
-  { 175, 2 },
+  { 176, 2 },
+  { 176, 3 },
+  { 176, 3 },
+  { 176, 3 },
+  { 177, 2 },
+  { 177, 2 },
+  { 177, 1 },
+  { 177, 1 },
   { 175, 3 },
-  { 175, 5 },
   { 175, 2 },
-  { 175, 5 },
-  { 175, 4 },
-  { 175, 1 },
-  { 175, 2 },
-  { 180, 0 },
-  { 180, 1 },
+  { 178, 0 },
+  { 178, 2 },
+  { 178, 2 },
+  { 153, 0 },
+  { 153, 2 },
+  { 179, 3 },
+  { 179, 2 },
+  { 179, 1 },
+  { 180, 2 },
+  { 180, 7 },
+  { 180, 5 },
+  { 180, 5 },
+  { 180, 10 },
   { 182, 0 },
-  { 182, 2 },
-  { 184, 2 },
-  { 184, 3 },
-  { 184, 3 },
-  { 184, 3 },
-  { 185, 2 },
-  { 185, 2 },
-  { 185, 1 },
-  { 185, 1 },
-  { 183, 3 },
+  { 182, 1 },
+  { 170, 0 },
+  { 170, 3 },
+  { 183, 0 },
   { 183, 2 },
-  { 186, 0 },
+  { 184, 1 },
+  { 184, 1 },
+  { 184, 1 },
+  { 142, 4 },
   { 186, 2 },
-  { 186, 2 },
-  { 161, 0 },
-  { 161, 2 },
-  { 187, 3 },
-  { 187, 2 },
-  { 187, 1 },
-  { 188, 2 },
-  { 188, 7 },
-  { 188, 5 },
-  { 188, 3 },
-  { 188, 10 },
-  { 190, 0 },
+  { 186, 0 },
+  { 142, 7 },
+  { 142, 4 },
+  { 142, 1 },
+  { 154, 1 },
+  { 154, 3 },
+  { 189, 1 },
+  { 189, 2 },
+  { 189, 1 },
+  { 188, 9 },
   { 190, 1 },
-  { 178, 0 },
-  { 178, 3 },
-  { 191, 0 },
-  { 191, 2 },
-  { 192, 1 },
-  { 192, 1 },
-  { 192, 1 },
-  { 151, 3 },
-  { 151, 7 },
-  { 151, 3 },
-  { 151, 1 },
-  { 162, 1 },
-  { 162, 3 },
-  { 196, 1 },
-  { 196, 2 },
-  { 196, 1 },
-  { 196, 1 },
-  { 195, 9 },
-  { 197, 1 },
-  { 197, 1 },
-  { 197, 0 },
-  { 205, 2 },
-  { 205, 0 },
-  { 198, 3 },
+  { 190, 1 },
+  { 190, 0 },
   { 198, 2 },
-  { 198, 4 },
-  { 206, 2 },
-  { 206, 1 },
-  { 206, 0 },
-  { 199, 0 },
+  { 198, 0 },
+  { 191, 3 },
+  { 191, 2 },
+  { 191, 4 },
   { 199, 2 },
-  { 208, 2 },
-  { 208, 0 },
-  { 207, 6 },
-  { 207, 7 },
-  { 212, 1 },
-  { 212, 1 },
-  { 159, 0 },
-  { 159, 2 },
-  { 194, 2 },
+  { 199, 1 },
+  { 199, 0 },
+  { 192, 0 },
+  { 192, 2 },
+  { 201, 2 },
+  { 201, 0 },
+  { 200, 6 },
+  { 200, 7 },
+  { 205, 1 },
+  { 205, 1 },
+  { 151, 0 },
+  { 151, 2 },
+  { 187, 2 },
+  { 202, 1 },
+  { 202, 2 },
+  { 202, 3 },
+  { 202, 4 },
+  { 203, 2 },
+  { 203, 0 },
+  { 204, 4 },
+  { 204, 0 },
+  { 196, 0 },
+  { 196, 3 },
+  { 208, 5 },
+  { 208, 3 },
   { 209, 1 },
-  { 209, 1 },
-  { 209, 2 },
-  { 209, 3 },
-  { 209, 4 },
-  { 210, 2 },
+  { 171, 1 },
+  { 171, 1 },
+  { 171, 0 },
   { 210, 0 },
-  { 211, 4 },
-  { 211, 0 },
-  { 203, 0 },
-  { 203, 3 },
-  { 215, 5 },
+  { 210, 2 },
+  { 194, 0 },
+  { 194, 3 },
+  { 195, 0 },
+  { 195, 2 },
+  { 197, 0 },
+  { 197, 2 },
+  { 197, 4 },
+  { 197, 4 },
+  { 142, 4 },
+  { 193, 0 },
+  { 193, 2 },
+  { 142, 6 },
+  { 212, 5 },
+  { 212, 3 },
+  { 142, 8 },
+  { 142, 5 },
+  { 213, 2 },
+  { 213, 1 },
   { 215, 3 },
+  { 215, 1 },
+  { 214, 0 },
+  { 214, 3 },
+  { 207, 3 },
+  { 207, 1 },
+  { 169, 1 },
+  { 169, 3 },
+  { 168, 1 },
+  { 169, 1 },
+  { 169, 1 },
+  { 169, 3 },
+  { 169, 5 },
+  { 168, 1 },
+  { 168, 1 },
+  { 169, 1 },
+  { 169, 1 },
+  { 169, 6 },
+  { 169, 5 },
+  { 169, 4 },
+  { 168, 1 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 3 },
   { 216, 1 },
-  { 179, 1 },
-  { 179, 1 },
-  { 179, 0 },
-  { 217, 0 },
+  { 216, 2 },
   { 217, 2 },
-  { 201, 0 },
-  { 201, 3 },
-  { 202, 0 },
-  { 202, 2 },
-  { 204, 0 },
-  { 204, 2 },
-  { 204, 4 },
-  { 204, 4 },
-  { 151, 4 },
-  { 200, 0 },
-  { 200, 2 },
-  { 151, 6 },
-  { 219, 5 },
-  { 219, 3 },
-  { 151, 8 },
-  { 151, 5 },
-  { 220, 2 },
+  { 217, 0 },
+  { 169, 4 },
+  { 169, 2 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 4 },
+  { 169, 2 },
+  { 169, 2 },
+  { 169, 2 },
+  { 218, 1 },
+  { 218, 2 },
+  { 169, 5 },
+  { 219, 1 },
+  { 219, 2 },
+  { 169, 5 },
+  { 169, 3 },
+  { 169, 5 },
+  { 169, 4 },
+  { 169, 4 },
+  { 169, 5 },
+  { 221, 5 },
+  { 221, 4 },
+  { 222, 2 },
+  { 222, 0 },
   { 220, 1 },
-  { 222, 3 },
-  { 222, 1 },
-  { 221, 0 },
-  { 221, 3 },
-  { 214, 3 },
-  { 214, 1 },
-  { 177, 1 },
-  { 177, 3 },
-  { 176, 1 },
-  { 177, 1 },
-  { 177, 1 },
-  { 177, 3 },
-  { 177, 5 },
-  { 176, 1 },
-  { 176, 1 },
-  { 176, 1 },
-  { 176, 1 },
-  { 177, 1 },
-  { 177, 1 },
-  { 177, 6 },
-  { 177, 5 },
-  { 177, 4 },
-  { 176, 1 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
-  { 177, 3 },
+  { 220, 0 },
+  { 211, 3 },
+  { 211, 1 },
   { 223, 1 },
-  { 223, 2 },
-  { 224, 2 },
+  { 223, 0 },
+  { 142, 11 },
+  { 224, 1 },
   { 224, 0 },
-  { 177, 4 },
-  { 177, 2 },
-  { 177, 3 },
-  { 177, 2 },
-  { 177, 3 },
-  { 177, 4 },
-  { 177, 2 },
-  { 177, 2 },
-  { 177, 2 },
-  { 177, 2 },
+  { 173, 0 },
+  { 173, 3 },
+  { 181, 5 },
+  { 181, 3 },
   { 225, 1 },
-  { 225, 2 },
-  { 177, 5 },
-  { 226, 1 },
-  { 226, 2 },
-  { 177, 5 },
-  { 177, 3 },
-  { 177, 5 },
-  { 177, 4 },
-  { 177, 4 },
-  { 177, 5 },
-  { 228, 5 },
-  { 228, 4 },
-  { 229, 2 },
-  { 229, 0 },
+  { 142, 4 },
+  { 142, 1 },
+  { 142, 2 },
+  { 142, 5 },
+  { 142, 5 },
+  { 142, 5 },
+  { 142, 5 },
+  { 142, 6 },
+  { 142, 3 },
+  { 164, 2 },
+  { 165, 2 },
   { 227, 1 },
-  { 227, 0 },
-  { 218, 3 },
-  { 218, 1 },
+  { 226, 1 },
+  { 226, 0 },
+  { 142, 5 },
+  { 228, 10 },
   { 230, 1 },
+  { 230, 1 },
+  { 230, 2 },
   { 230, 0 },
-  { 151, 11 },
   { 231, 1 },
-  { 231, 0 },
-  { 181, 0 },
-  { 181, 3 },
-  { 189, 5 },
-  { 189, 3 },
-  { 232, 1 },
-  { 151, 3 },
-  { 151, 1 },
-  { 151, 2 },
-  { 151, 5 },
-  { 151, 5 },
-  { 151, 5 },
-  { 151, 5 },
-  { 151, 6 },
-  { 151, 3 },
-  { 172, 2 },
-  { 173, 2 },
-  { 234, 1 },
-  { 234, 1 },
-  { 233, 1 },
+  { 231, 1 },
+  { 231, 3 },
+  { 232, 0 },
+  { 232, 3 },
+  { 232, 3 },
   { 233, 0 },
-  { 151, 5 },
-  { 235, 10 },
+  { 233, 2 },
+  { 229, 3 },
+  { 229, 0 },
+  { 234, 6 },
+  { 234, 8 },
+  { 234, 5 },
+  { 234, 4 },
+  { 234, 1 },
+  { 169, 4 },
+  { 169, 6 },
+  { 185, 1 },
+  { 185, 1 },
+  { 185, 1 },
+  { 142, 3 },
+  { 142, 6 },
+  { 236, 0 },
+  { 236, 2 },
+  { 235, 1 },
+  { 235, 0 },
+  { 142, 3 },
+  { 142, 1 },
+  { 142, 3 },
+  { 142, 1 },
+  { 142, 3 },
+  { 142, 6 },
+  { 142, 6 },
   { 237, 1 },
-  { 237, 1 },
-  { 237, 2 },
-  { 237, 0 },
+  { 238, 0 },
   { 238, 1 },
-  { 238, 1 },
-  { 238, 1 },
-  { 238, 3 },
-  { 239, 0 },
-  { 239, 3 },
-  { 239, 3 },
-  { 240, 0 },
-  { 240, 2 },
-  { 236, 3 },
-  { 236, 0 },
-  { 241, 6 },
-  { 241, 8 },
-  { 241, 5 },
-  { 241, 4 },
-  { 241, 1 },
-  { 177, 4 },
-  { 177, 6 },
-  { 193, 1 },
-  { 193, 1 },
-  { 193, 1 },
-  { 151, 3 },
-  { 151, 6 },
-  { 243, 0 },
-  { 243, 2 },
-  { 243, 2 },
-  { 242, 1 },
-  { 242, 0 },
-  { 151, 3 },
-  { 151, 1 },
-  { 151, 3 },
-  { 151, 1 },
-  { 151, 3 },
-  { 151, 6 },
-  { 151, 6 },
-  { 244, 1 },
-  { 245, 0 },
-  { 245, 1 },
 };
 
 static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -1935,777 +1805,781 @@
   **     break;
   */
       case 3:
-#line 102 "parse.y"
+#line 98 "parse.y"
 { sqlite3FinishCoding(pParse); }
-#line 1942 "parse.c"
+#line 1813 "parse.c"
         break;
       case 6:
-#line 105 "parse.y"
+#line 101 "parse.y"
 { sqlite3BeginParse(pParse, 0); }
-#line 1947 "parse.c"
+#line 1818 "parse.c"
         break;
       case 7:
-#line 107 "parse.y"
+#line 103 "parse.y"
 { sqlite3BeginParse(pParse, 1); }
-#line 1952 "parse.c"
+#line 1823 "parse.c"
         break;
       case 8:
-#line 108 "parse.y"
+#line 104 "parse.y"
 { sqlite3BeginParse(pParse, 2); }
-#line 1957 "parse.c"
+#line 1828 "parse.c"
         break;
       case 9:
-#line 114 "parse.y"
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy280);}
-#line 1962 "parse.c"
+#line 110 "parse.y"
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy230);}
+#line 1833 "parse.c"
         break;
       case 13:
-#line 119 "parse.y"
-{yygotominor.yy280 = TK_DEFERRED;}
-#line 1967 "parse.c"
+#line 115 "parse.y"
+{yygotominor.yy230 = TK_DEFERRED;}
+#line 1838 "parse.c"
         break;
       case 14:
       case 15:
       case 16:
-      case 104:
-      case 106:
       case 107:
-#line 120 "parse.y"
-{yygotominor.yy280 = yymsp[0].major;}
-#line 1977 "parse.c"
+      case 109:
+#line 116 "parse.y"
+{yygotominor.yy230 = yymsp[0].major;}
+#line 1847 "parse.c"
         break;
       case 17:
       case 18:
-#line 123 "parse.y"
+#line 119 "parse.y"
 {sqlite3CommitTransaction(pParse);}
-#line 1983 "parse.c"
+#line 1853 "parse.c"
         break;
       case 19:
-#line 125 "parse.y"
+#line 121 "parse.y"
 {sqlite3RollbackTransaction(pParse);}
-#line 1988 "parse.c"
+#line 1858 "parse.c"
         break;
       case 21:
-#line 130 "parse.y"
+#line 126 "parse.y"
 {
-   sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy198,&yymsp[0].minor.yy198,yymsp[-3].minor.yy280,0);
+   sqlite3StartTable(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384,yymsp[-4].minor.yy230,0,yymsp[-2].minor.yy230);
 }
-#line 1995 "parse.c"
+#line 1865 "parse.c"
         break;
       case 22:
+      case 25:
       case 63:
       case 77:
-      case 109:
-      case 224:
-      case 227:
-#line 135 "parse.y"
-{yygotominor.yy280 = 1;}
-#line 2005 "parse.c"
+      case 79:
+      case 90:
+      case 101:
+      case 112:
+      case 113:
+      case 210:
+      case 213:
+#line 130 "parse.y"
+{yygotominor.yy230 = 0;}
+#line 1880 "parse.c"
         break;
       case 23:
-      case 62:
-      case 76:
+      case 24:
+      case 64:
       case 78:
-      case 89:
-      case 110:
+      case 100:
       case 111:
-      case 223:
-      case 226:
-#line 137 "parse.y"
-{yygotominor.yy280 = 0;}
-#line 2018 "parse.c"
+      case 211:
+      case 214:
+#line 131 "parse.y"
+{yygotominor.yy230 = 1;}
+#line 1892 "parse.c"
         break;
-      case 24:
-#line 138 "parse.y"
+      case 26:
+#line 137 "parse.y"
 {
-  sqlite3EndTable(pParse,&yymsp[-1].minor.yy198,&yymsp[0].minor.yy0,0);
+  sqlite3EndTable(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy0,0);
 }
-#line 2025 "parse.c"
+#line 1899 "parse.c"
         break;
-      case 25:
-#line 141 "parse.y"
+      case 27:
+#line 140 "parse.y"
 {
-  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy375);
-  sqlite3SelectDelete(yymsp[0].minor.yy375);
+  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy239);
+  sqlite3SelectDelete(yymsp[0].minor.yy239);
 }
-#line 2033 "parse.c"
+#line 1907 "parse.c"
         break;
-      case 28:
-#line 153 "parse.y"
+      case 30:
+#line 152 "parse.y"
 {
-  yygotominor.yy198.z = yymsp[-2].minor.yy198.z;
-  yygotominor.yy198.n = (pParse->sLastToken.z-yymsp[-2].minor.yy198.z) + pParse->sLastToken.n;
+  yygotominor.yy384.z = yymsp[-2].minor.yy384.z;
+  yygotominor.yy384.n = (pParse->sLastToken.z-yymsp[-2].minor.yy384.z) + pParse->sLastToken.n;
 }
-#line 2041 "parse.c"
+#line 1915 "parse.c"
         break;
-      case 29:
-#line 157 "parse.y"
+      case 31:
+#line 156 "parse.y"
 {
-  sqlite3AddColumn(pParse,&yymsp[0].minor.yy198);
-  yygotominor.yy198 = yymsp[0].minor.yy198;
+  sqlite3AddColumn(pParse,&yymsp[0].minor.yy384);
+  yygotominor.yy384 = yymsp[0].minor.yy384;
 }
-#line 2049 "parse.c"
+#line 1923 "parse.c"
         break;
-      case 30:
-      case 31:
       case 32:
       case 33:
       case 34:
       case 35:
-      case 263:
-      case 264:
-#line 167 "parse.y"
-{yygotominor.yy198 = yymsp[0].minor.yy0;}
-#line 2061 "parse.c"
+      case 36:
+      case 250:
+#line 166 "parse.y"
+{yygotominor.yy384 = yymsp[0].minor.yy0;}
+#line 1933 "parse.c"
         break;
-      case 37:
-#line 227 "parse.y"
-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy198);}
-#line 2066 "parse.c"
-        break;
       case 38:
-      case 41:
-      case 117:
-      case 118:
-      case 129:
-      case 149:
-      case 251:
-      case 261:
-      case 262:
-#line 228 "parse.y"
-{yygotominor.yy198 = yymsp[0].minor.yy198;}
-#line 2079 "parse.c"
+#line 225 "parse.y"
+{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy384);}
+#line 1938 "parse.c"
         break;
       case 39:
-#line 229 "parse.y"
+      case 42:
+      case 119:
+      case 120:
+      case 131:
+      case 150:
+      case 238:
+      case 248:
+      case 249:
+#line 226 "parse.y"
+{yygotominor.yy384 = yymsp[0].minor.yy384;}
+#line 1951 "parse.c"
+        break;
+      case 40:
+#line 227 "parse.y"
 {
-  yygotominor.yy198.z = yymsp[-3].minor.yy198.z;
-  yygotominor.yy198.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy198.z;
+  yygotominor.yy384.z = yymsp[-3].minor.yy384.z;
+  yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy384.z;
 }
-#line 2087 "parse.c"
+#line 1959 "parse.c"
         break;
-      case 40:
-#line 233 "parse.y"
+      case 41:
+#line 231 "parse.y"
 {
-  yygotominor.yy198.z = yymsp[-5].minor.yy198.z;
-  yygotominor.yy198.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy198.z;
+  yygotominor.yy384.z = yymsp[-5].minor.yy384.z;
+  yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy384.z;
 }
-#line 2095 "parse.c"
+#line 1967 "parse.c"
         break;
-      case 42:
-#line 239 "parse.y"
-{yygotominor.yy198.z=yymsp[-1].minor.yy198.z; yygotominor.yy198.n=yymsp[0].minor.yy198.n+(yymsp[0].minor.yy198.z-yymsp[-1].minor.yy198.z);}
-#line 2100 "parse.c"
-        break;
       case 43:
-#line 241 "parse.y"
-{ yygotominor.yy280 = atoi(yymsp[0].minor.yy198.z); }
-#line 2105 "parse.c"
+#line 237 "parse.y"
+{yygotominor.yy384.z=yymsp[-1].minor.yy384.z; yygotominor.yy384.n=yymsp[0].minor.yy384.n+(yymsp[0].minor.yy384.z-yymsp[-1].minor.yy384.z);}
+#line 1972 "parse.c"
         break;
       case 44:
-#line 242 "parse.y"
-{ yygotominor.yy280 = -atoi(yymsp[0].minor.yy198.z); }
-#line 2110 "parse.c"
+#line 239 "parse.y"
+{ yygotominor.yy230 = atoi((char*)yymsp[0].minor.yy384.z); }
+#line 1977 "parse.c"
         break;
-      case 49:
-      case 51:
-#line 251 "parse.y"
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy62);}
-#line 2116 "parse.c"
+      case 45:
+#line 240 "parse.y"
+{ yygotominor.yy230 = -atoi((char*)yymsp[0].minor.yy384.z); }
+#line 1982 "parse.c"
         break;
       case 50:
-#line 252 "parse.y"
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy62);}
-#line 2121 "parse.c"
-        break;
       case 52:
-#line 254 "parse.y"
+#line 249 "parse.y"
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy178);}
+#line 1988 "parse.c"
+        break;
+      case 51:
+#line 250 "parse.y"
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy178);}
+#line 1993 "parse.c"
+        break;
+      case 53:
+#line 252 "parse.y"
 {
-  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy62, 0, 0);
+  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0);
   sqlite3AddDefaultValue(pParse,p);
 }
-#line 2129 "parse.c"
+#line 2001 "parse.c"
         break;
-      case 53:
-#line 258 "parse.y"
+      case 54:
+#line 256 "parse.y"
 {
-  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy198);
+  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy384);
   sqlite3AddDefaultValue(pParse,p);
 }
-#line 2137 "parse.c"
+#line 2009 "parse.c"
         break;
-      case 55:
-#line 267 "parse.y"
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy280);}
-#line 2142 "parse.c"
-        break;
       case 56:
-#line 269 "parse.y"
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy280,yymsp[0].minor.yy280);}
-#line 2147 "parse.c"
+#line 265 "parse.y"
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy230);}
+#line 2014 "parse.c"
         break;
       case 57:
-#line 270 "parse.y"
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy280,0,0);}
-#line 2152 "parse.c"
+#line 267 "parse.y"
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy230,yymsp[0].minor.yy230,yymsp[-2].minor.yy230);}
+#line 2019 "parse.c"
         break;
       case 58:
-#line 271 "parse.y"
-{sqlite3ExprDelete(yymsp[-2].minor.yy62);}
-#line 2157 "parse.c"
+#line 268 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy230,0,0,0,0);}
+#line 2024 "parse.c"
         break;
       case 59:
-#line 273 "parse.y"
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy198,yymsp[-1].minor.yy418,yymsp[0].minor.yy280);}
-#line 2162 "parse.c"
+#line 269 "parse.y"
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy178);}
+#line 2029 "parse.c"
         break;
       case 60:
-#line 274 "parse.y"
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy280);}
-#line 2167 "parse.c"
+#line 271 "parse.y"
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy384,yymsp[-1].minor.yy462,yymsp[0].minor.yy230);}
+#line 2034 "parse.c"
         break;
       case 61:
-#line 275 "parse.y"
-{sqlite3AddCollateType(pParse, yymsp[0].minor.yy198.z, yymsp[0].minor.yy198.n);}
-#line 2172 "parse.c"
+#line 272 "parse.y"
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy230);}
+#line 2039 "parse.c"
         break;
-      case 64:
-#line 288 "parse.y"
-{ yygotominor.yy280 = OE_Restrict * 0x010101; }
-#line 2177 "parse.c"
+      case 62:
+#line 273 "parse.y"
+{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy384.z, yymsp[0].minor.yy384.n);}
+#line 2044 "parse.c"
         break;
       case 65:
-#line 289 "parse.y"
-{ yygotominor.yy280 = (yymsp[-1].minor.yy280 & yymsp[0].minor.yy359.mask) | yymsp[0].minor.yy359.value; }
-#line 2182 "parse.c"
+#line 286 "parse.y"
+{ yygotominor.yy230 = OE_Restrict * 0x010101; }
+#line 2049 "parse.c"
         break;
       case 66:
-#line 291 "parse.y"
-{ yygotominor.yy359.value = 0;     yygotominor.yy359.mask = 0x000000; }
-#line 2187 "parse.c"
+#line 287 "parse.y"
+{ yygotominor.yy230 = (yymsp[-1].minor.yy230 & yymsp[0].minor.yy13.mask) | yymsp[0].minor.yy13.value; }
+#line 2054 "parse.c"
         break;
       case 67:
-#line 292 "parse.y"
-{ yygotominor.yy359.value = yymsp[0].minor.yy280;     yygotominor.yy359.mask = 0x0000ff; }
-#line 2192 "parse.c"
+#line 289 "parse.y"
+{ yygotominor.yy13.value = 0;     yygotominor.yy13.mask = 0x000000; }
+#line 2059 "parse.c"
         break;
       case 68:
-#line 293 "parse.y"
-{ yygotominor.yy359.value = yymsp[0].minor.yy280<<8;  yygotominor.yy359.mask = 0x00ff00; }
-#line 2197 "parse.c"
+#line 290 "parse.y"
+{ yygotominor.yy13.value = yymsp[0].minor.yy230;     yygotominor.yy13.mask = 0x0000ff; }
+#line 2064 "parse.c"
         break;
       case 69:
-#line 294 "parse.y"
-{ yygotominor.yy359.value = yymsp[0].minor.yy280<<16; yygotominor.yy359.mask = 0xff0000; }
-#line 2202 "parse.c"
+#line 291 "parse.y"
+{ yygotominor.yy13.value = yymsp[0].minor.yy230<<8;  yygotominor.yy13.mask = 0x00ff00; }
+#line 2069 "parse.c"
         break;
       case 70:
-#line 296 "parse.y"
-{ yygotominor.yy280 = OE_SetNull; }
-#line 2207 "parse.c"
+#line 292 "parse.y"
+{ yygotominor.yy13.value = yymsp[0].minor.yy230<<16; yygotominor.yy13.mask = 0xff0000; }
+#line 2074 "parse.c"
         break;
       case 71:
-#line 297 "parse.y"
-{ yygotominor.yy280 = OE_SetDflt; }
-#line 2212 "parse.c"
+#line 294 "parse.y"
+{ yygotominor.yy230 = OE_SetNull; }
+#line 2079 "parse.c"
         break;
       case 72:
-#line 298 "parse.y"
-{ yygotominor.yy280 = OE_Cascade; }
-#line 2217 "parse.c"
+#line 295 "parse.y"
+{ yygotominor.yy230 = OE_SetDflt; }
+#line 2084 "parse.c"
         break;
       case 73:
-#line 299 "parse.y"
-{ yygotominor.yy280 = OE_Restrict; }
-#line 2222 "parse.c"
+#line 296 "parse.y"
+{ yygotominor.yy230 = OE_Cascade; }
+#line 2089 "parse.c"
         break;
       case 74:
+#line 297 "parse.y"
+{ yygotominor.yy230 = OE_Restrict; }
+#line 2094 "parse.c"
+        break;
       case 75:
-      case 90:
-      case 92:
-      case 94:
+      case 76:
+      case 91:
+      case 93:
       case 95:
-      case 166:
-#line 301 "parse.y"
-{yygotominor.yy280 = yymsp[0].minor.yy280;}
-#line 2233 "parse.c"
+      case 96:
+      case 167:
+#line 299 "parse.y"
+{yygotominor.yy230 = yymsp[0].minor.yy230;}
+#line 2105 "parse.c"
         break;
-      case 79:
-#line 311 "parse.y"
-{yygotominor.yy198.n = 0; yygotominor.yy198.z = 0;}
-#line 2238 "parse.c"
-        break;
       case 80:
-#line 312 "parse.y"
-{yygotominor.yy198 = yymsp[-1].minor.yy0;}
-#line 2243 "parse.c"
+#line 309 "parse.y"
+{yygotominor.yy384.n = 0; yygotominor.yy384.z = 0;}
+#line 2110 "parse.c"
         break;
-      case 85:
-#line 318 "parse.y"
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy418,yymsp[0].minor.yy280,yymsp[-2].minor.yy280);}
-#line 2248 "parse.c"
+      case 81:
+#line 310 "parse.y"
+{yygotominor.yy384 = yymsp[-1].minor.yy0;}
+#line 2115 "parse.c"
         break;
       case 86:
-#line 320 "parse.y"
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy418,yymsp[0].minor.yy280,0,0);}
-#line 2253 "parse.c"
+#line 316 "parse.y"
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy462,yymsp[0].minor.yy230,yymsp[-2].minor.yy230,0);}
+#line 2120 "parse.c"
         break;
+      case 87:
+#line 318 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy462,yymsp[0].minor.yy230,0,0,0,0);}
+#line 2125 "parse.c"
+        break;
       case 88:
-#line 323 "parse.y"
+#line 319 "parse.y"
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy178);}
+#line 2130 "parse.c"
+        break;
+      case 89:
+#line 321 "parse.y"
 {
-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy418, &yymsp[-3].minor.yy198, yymsp[-2].minor.yy418, yymsp[-1].minor.yy280);
-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy280);
+    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy462, &yymsp[-3].minor.yy384, yymsp[-2].minor.yy462, yymsp[-1].minor.yy230);
+    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy230);
 }
-#line 2261 "parse.c"
+#line 2138 "parse.c"
         break;
-      case 91:
-      case 93:
-#line 337 "parse.y"
-{yygotominor.yy280 = OE_Default;}
-#line 2267 "parse.c"
+      case 92:
+      case 94:
+#line 335 "parse.y"
+{yygotominor.yy230 = OE_Default;}
+#line 2144 "parse.c"
         break;
-      case 96:
-#line 342 "parse.y"
-{yygotominor.yy280 = OE_Ignore;}
-#line 2272 "parse.c"
-        break;
       case 97:
-      case 167:
-#line 343 "parse.y"
-{yygotominor.yy280 = OE_Replace;}
-#line 2278 "parse.c"
+#line 340 "parse.y"
+{yygotominor.yy230 = OE_Ignore;}
+#line 2149 "parse.c"
         break;
       case 98:
-#line 347 "parse.y"
+      case 168:
+#line 341 "parse.y"
+{yygotominor.yy230 = OE_Replace;}
+#line 2155 "parse.c"
+        break;
+      case 99:
+#line 345 "parse.y"
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy151, 0);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy285, 0, yymsp[-1].minor.yy230);
 }
-#line 2285 "parse.c"
+#line 2162 "parse.c"
         break;
-      case 99:
-#line 354 "parse.y"
+      case 102:
+#line 355 "parse.y"
 {
-  sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy198, &yymsp[-2].minor.yy198, yymsp[0].minor.yy375, yymsp[-5].minor.yy280);
+  sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy384, &yymsp[-2].minor.yy384, yymsp[0].minor.yy239, yymsp[-5].minor.yy230);
 }
-#line 2292 "parse.c"
+#line 2169 "parse.c"
         break;
-      case 100:
-#line 357 "parse.y"
+      case 103:
+#line 358 "parse.y"
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy151, 1);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy285, 1, yymsp[-1].minor.yy230);
 }
-#line 2299 "parse.c"
+#line 2176 "parse.c"
         break;
-      case 101:
-#line 364 "parse.y"
+      case 104:
+#line 365 "parse.y"
 {
-  sqlite3Select(pParse, yymsp[0].minor.yy375, SRT_Callback, 0, 0, 0, 0, 0);
-  sqlite3SelectDelete(yymsp[0].minor.yy375);
+  sqlite3Select(pParse, yymsp[0].minor.yy239, SRT_Callback, 0, 0, 0, 0, 0);
+  sqlite3SelectDelete(yymsp[0].minor.yy239);
 }
-#line 2307 "parse.c"
+#line 2184 "parse.c"
         break;
-      case 102:
-      case 126:
-#line 374 "parse.y"
-{yygotominor.yy375 = yymsp[0].minor.yy375;}
-#line 2313 "parse.c"
+      case 105:
+      case 128:
+#line 375 "parse.y"
+{yygotominor.yy239 = yymsp[0].minor.yy239;}
+#line 2190 "parse.c"
         break;
-      case 103:
-#line 376 "parse.y"
+      case 106:
+#line 377 "parse.y"
 {
-  if( yymsp[0].minor.yy375 ){
-    yymsp[0].minor.yy375->op = yymsp[-1].minor.yy280;
-    yymsp[0].minor.yy375->pPrior = yymsp[-2].minor.yy375;
+  if( yymsp[0].minor.yy239 ){
+    yymsp[0].minor.yy239->op = yymsp[-1].minor.yy230;
+    yymsp[0].minor.yy239->pPrior = yymsp[-2].minor.yy239;
   }
-  yygotominor.yy375 = yymsp[0].minor.yy375;
+  yygotominor.yy239 = yymsp[0].minor.yy239;
 }
-#line 2324 "parse.c"
+#line 2201 "parse.c"
         break;
-      case 105:
-#line 385 "parse.y"
-{yygotominor.yy280 = TK_ALL;}
-#line 2329 "parse.c"
-        break;
       case 108:
+#line 386 "parse.y"
+{yygotominor.yy230 = TK_ALL;}
+#line 2206 "parse.c"
+        break;
+      case 110:
 #line 390 "parse.y"
 {
-  yygotominor.yy375 = sqlite3SelectNew(yymsp[-6].minor.yy418,yymsp[-5].minor.yy151,yymsp[-4].minor.yy62,yymsp[-3].minor.yy418,yymsp[-2].minor.yy62,yymsp[-1].minor.yy418,yymsp[-7].minor.yy280,yymsp[0].minor.yy220.pLimit,yymsp[0].minor.yy220.pOffset);
+  yygotominor.yy239 = sqlite3SelectNew(yymsp[-6].minor.yy462,yymsp[-5].minor.yy285,yymsp[-4].minor.yy178,yymsp[-3].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy462,yymsp[-7].minor.yy230,yymsp[0].minor.yy270.pLimit,yymsp[0].minor.yy270.pOffset);
 }
-#line 2336 "parse.c"
+#line 2213 "parse.c"
         break;
-      case 112:
-      case 248:
+      case 114:
+      case 235:
 #line 411 "parse.y"
-{yygotominor.yy418 = yymsp[-1].minor.yy418;}
-#line 2342 "parse.c"
+{yygotominor.yy462 = yymsp[-1].minor.yy462;}
+#line 2219 "parse.c"
         break;
-      case 113:
-      case 140:
-      case 150:
-      case 247:
+      case 115:
+      case 141:
+      case 151:
+      case 234:
 #line 412 "parse.y"
-{yygotominor.yy418 = 0;}
-#line 2350 "parse.c"
+{yygotominor.yy462 = 0;}
+#line 2227 "parse.c"
         break;
-      case 114:
+      case 116:
 #line 413 "parse.y"
 {
-   yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-2].minor.yy418,yymsp[-1].minor.yy62,yymsp[0].minor.yy198.n?&yymsp[0].minor.yy198:0);
+   yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[-1].minor.yy178,yymsp[0].minor.yy384.n?&yymsp[0].minor.yy384:0);
 }
-#line 2357 "parse.c"
+#line 2234 "parse.c"
         break;
-      case 115:
+      case 117:
 #line 416 "parse.y"
 {
-  yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-1].minor.yy418, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
+  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-1].minor.yy462, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
 }
-#line 2364 "parse.c"
+#line 2241 "parse.c"
         break;
-      case 116:
+      case 118:
 #line 419 "parse.y"
 {
   Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0);
-  Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy198);
-  yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-3].minor.yy418, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
+  Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384);
+  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-3].minor.yy462, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
 }
-#line 2373 "parse.c"
+#line 2250 "parse.c"
         break;
-      case 119:
+      case 121:
 #line 431 "parse.y"
-{yygotominor.yy198.n = 0;}
-#line 2378 "parse.c"
+{yygotominor.yy384.n = 0;}
+#line 2255 "parse.c"
         break;
-      case 120:
+      case 122:
 #line 443 "parse.y"
-{yygotominor.yy151 = sqliteMalloc(sizeof(*yygotominor.yy151));}
-#line 2383 "parse.c"
+{yygotominor.yy285 = sqliteMalloc(sizeof(*yygotominor.yy285));}
+#line 2260 "parse.c"
         break;
-      case 121:
+      case 123:
 #line 444 "parse.y"
-{yygotominor.yy151 = yymsp[0].minor.yy151;}
-#line 2388 "parse.c"
+{yygotominor.yy285 = yymsp[0].minor.yy285;}
+#line 2265 "parse.c"
         break;
-      case 122:
+      case 124:
 #line 449 "parse.y"
 {
-   yygotominor.yy151 = yymsp[-1].minor.yy151;
-   if( yygotominor.yy151 && yygotominor.yy151->nSrc>0 ) yygotominor.yy151->a[yygotominor.yy151->nSrc-1].jointype = yymsp[0].minor.yy280;
+   yygotominor.yy285 = yymsp[-1].minor.yy285;
+   if( yygotominor.yy285 && yygotominor.yy285->nSrc>0 ) yygotominor.yy285->a[yygotominor.yy285->nSrc-1].jointype = yymsp[0].minor.yy230;
 }
-#line 2396 "parse.c"
+#line 2273 "parse.c"
         break;
-      case 123:
+      case 125:
 #line 453 "parse.y"
-{yygotominor.yy151 = 0;}
-#line 2401 "parse.c"
+{yygotominor.yy285 = 0;}
+#line 2278 "parse.c"
         break;
-      case 124:
+      case 126:
 #line 454 "parse.y"
 {
-  yygotominor.yy151 = sqlite3SrcListAppend(yymsp[-5].minor.yy151,&yymsp[-4].minor.yy198,&yymsp[-3].minor.yy198);
-  if( yymsp[-2].minor.yy198.n ) sqlite3SrcListAddAlias(yygotominor.yy151,&yymsp[-2].minor.yy198);
-  if( yymsp[-1].minor.yy62 ){
-    if( yygotominor.yy151 && yygotominor.yy151->nSrc>1 ){ yygotominor.yy151->a[yygotominor.yy151->nSrc-2].pOn = yymsp[-1].minor.yy62; }
-    else { sqlite3ExprDelete(yymsp[-1].minor.yy62); }
+  yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-5].minor.yy285,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384);
+  if( yymsp[-2].minor.yy384.n ) sqlite3SrcListAddAlias(yygotominor.yy285,&yymsp[-2].minor.yy384);
+  if( yymsp[-1].minor.yy178 ){
+    if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pOn = yymsp[-1].minor.yy178; }
+    else { sqlite3ExprDelete(yymsp[-1].minor.yy178); }
   }
-  if( yymsp[0].minor.yy240 ){
-    if( yygotominor.yy151 && yygotominor.yy151->nSrc>1 ){ yygotominor.yy151->a[yygotominor.yy151->nSrc-2].pUsing = yymsp[0].minor.yy240; }
-    else { sqlite3IdListDelete(yymsp[0].minor.yy240); }
+  if( yymsp[0].minor.yy160 ){
+    if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pUsing = yymsp[0].minor.yy160; }
+    else { sqlite3IdListDelete(yymsp[0].minor.yy160); }
   }
 }
-#line 2417 "parse.c"
+#line 2294 "parse.c"
         break;
-      case 125:
+      case 127:
 #line 468 "parse.y"
 {
-    yygotominor.yy151 = sqlite3SrcListAppend(yymsp[-6].minor.yy151,0,0);
-    yygotominor.yy151->a[yygotominor.yy151->nSrc-1].pSelect = yymsp[-4].minor.yy375;
-    if( yymsp[-2].minor.yy198.n ) sqlite3SrcListAddAlias(yygotominor.yy151,&yymsp[-2].minor.yy198);
-    if( yymsp[-1].minor.yy62 ){
-      if( yygotominor.yy151 && yygotominor.yy151->nSrc>1 ){ yygotominor.yy151->a[yygotominor.yy151->nSrc-2].pOn = yymsp[-1].minor.yy62; }
-      else { sqlite3ExprDelete(yymsp[-1].minor.yy62); }
+    yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-6].minor.yy285,0,0);
+    yygotominor.yy285->a[yygotominor.yy285->nSrc-1].pSelect = yymsp[-4].minor.yy239;
+    if( yymsp[-2].minor.yy384.n ) sqlite3SrcListAddAlias(yygotominor.yy285,&yymsp[-2].minor.yy384);
+    if( yymsp[-1].minor.yy178 ){
+      if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pOn = yymsp[-1].minor.yy178; }
+      else { sqlite3ExprDelete(yymsp[-1].minor.yy178); }
     }
-    if( yymsp[0].minor.yy240 ){
-      if( yygotominor.yy151 && yygotominor.yy151->nSrc>1 ){ yygotominor.yy151->a[yygotominor.yy151->nSrc-2].pUsing = yymsp[0].minor.yy240; }
-      else { sqlite3IdListDelete(yymsp[0].minor.yy240); }
+    if( yymsp[0].minor.yy160 ){
+      if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pUsing = yymsp[0].minor.yy160; }
+      else { sqlite3IdListDelete(yymsp[0].minor.yy160); }
     }
   }
-#line 2434 "parse.c"
+#line 2311 "parse.c"
         break;
-      case 127:
+      case 129:
 #line 489 "parse.y"
 {
-     yygotominor.yy375 = sqlite3SelectNew(0,yymsp[0].minor.yy151,0,0,0,0,0,0,0);
+     yygotominor.yy239 = sqlite3SelectNew(0,yymsp[0].minor.yy285,0,0,0,0,0,0,0);
   }
-#line 2441 "parse.c"
+#line 2318 "parse.c"
         break;
-      case 128:
+      case 130:
 #line 495 "parse.y"
-{yygotominor.yy198.z=0; yygotominor.yy198.n=0;}
-#line 2446 "parse.c"
+{yygotominor.yy384.z=0; yygotominor.yy384.n=0;}
+#line 2323 "parse.c"
         break;
-      case 130:
+      case 132:
 #line 500 "parse.y"
-{yygotominor.yy151 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy198,&yymsp[0].minor.yy198);}
-#line 2451 "parse.c"
+{yygotominor.yy285 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384);}
+#line 2328 "parse.c"
         break;
-      case 131:
-      case 132:
+      case 133:
 #line 504 "parse.y"
-{ yygotominor.yy280 = JT_INNER; }
-#line 2457 "parse.c"
+{ yygotominor.yy230 = JT_INNER; }
+#line 2333 "parse.c"
         break;
-      case 133:
-#line 506 "parse.y"
-{ yygotominor.yy280 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
-#line 2462 "parse.c"
-        break;
       case 134:
-#line 507 "parse.y"
-{ yygotominor.yy280 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy198,0); }
-#line 2467 "parse.c"
+#line 505 "parse.y"
+{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+#line 2338 "parse.c"
         break;
       case 135:
-#line 509 "parse.y"
-{ yygotominor.yy280 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy198,&yymsp[-1].minor.yy198); }
-#line 2472 "parse.c"
+#line 506 "parse.y"
+{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy384,0); }
+#line 2343 "parse.c"
         break;
       case 136:
-      case 144:
+#line 508 "parse.y"
+{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy384,&yymsp[-1].minor.yy384); }
+#line 2348 "parse.c"
+        break;
+      case 137:
+      case 145:
+      case 154:
+      case 161:
+      case 175:
+      case 200:
+      case 223:
+      case 225:
+      case 229:
+#line 512 "parse.y"
+{yygotominor.yy178 = yymsp[0].minor.yy178;}
+#line 2361 "parse.c"
+        break;
+      case 138:
       case 153:
       case 160:
-      case 174:
-      case 211:
-      case 236:
-      case 238:
-      case 242:
+      case 201:
+      case 224:
+      case 226:
+      case 230:
 #line 513 "parse.y"
-{yygotominor.yy62 = yymsp[0].minor.yy62;}
-#line 2485 "parse.c"
+{yygotominor.yy178 = 0;}
+#line 2372 "parse.c"
         break;
-      case 137:
-      case 152:
-      case 159:
-      case 212:
-      case 237:
-      case 239:
-      case 243:
-#line 514 "parse.y"
-{yygotominor.yy62 = 0;}
-#line 2496 "parse.c"
+      case 139:
+      case 172:
+#line 517 "parse.y"
+{yygotominor.yy160 = yymsp[-1].minor.yy160;}
+#line 2378 "parse.c"
         break;
-      case 138:
+      case 140:
       case 171:
 #line 518 "parse.y"
-{yygotominor.yy240 = yymsp[-1].minor.yy240;}
-#line 2502 "parse.c"
+{yygotominor.yy160 = 0;}
+#line 2384 "parse.c"
         break;
-      case 139:
-      case 170:
-#line 519 "parse.y"
-{yygotominor.yy240 = 0;}
-#line 2508 "parse.c"
+      case 142:
+      case 152:
+#line 529 "parse.y"
+{yygotominor.yy462 = yymsp[0].minor.yy462;}
+#line 2390 "parse.c"
         break;
-      case 141:
-      case 151:
+      case 143:
 #line 530 "parse.y"
-{yygotominor.yy418 = yymsp[0].minor.yy418;}
-#line 2514 "parse.c"
-        break;
-      case 142:
-#line 531 "parse.y"
 {
-  yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-4].minor.yy418,yymsp[-2].minor.yy62,yymsp[-1].minor.yy198.n>0?&yymsp[-1].minor.yy198:0);
-  if( yygotominor.yy418 ) yygotominor.yy418->a[yygotominor.yy418->nExpr-1].sortOrder = yymsp[0].minor.yy280;
+  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0);
+  if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230;
 }
-#line 2522 "parse.c"
+#line 2398 "parse.c"
         break;
-      case 143:
-#line 535 "parse.y"
+      case 144:
+#line 534 "parse.y"
 {
-  yygotominor.yy418 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy62,yymsp[-1].minor.yy198.n>0?&yymsp[-1].minor.yy198:0);
-  if( yygotominor.yy418 && yygotominor.yy418->a ) yygotominor.yy418->a[0].sortOrder = yymsp[0].minor.yy280;
+  yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0);
+  if( yygotominor.yy462 && yygotominor.yy462->a ) yygotominor.yy462->a[0].sortOrder = yymsp[0].minor.yy230;
 }
-#line 2530 "parse.c"
+#line 2406 "parse.c"
         break;
-      case 145:
-      case 147:
-#line 544 "parse.y"
-{yygotominor.yy280 = SQLITE_SO_ASC;}
-#line 2536 "parse.c"
-        break;
       case 146:
-#line 545 "parse.y"
-{yygotominor.yy280 = SQLITE_SO_DESC;}
-#line 2541 "parse.c"
-        break;
       case 148:
-#line 547 "parse.y"
-{yygotominor.yy198.z = 0; yygotominor.yy198.n = 0;}
-#line 2546 "parse.c"
+#line 543 "parse.y"
+{yygotominor.yy230 = SQLITE_SO_ASC;}
+#line 2412 "parse.c"
         break;
-      case 154:
-#line 565 "parse.y"
-{yygotominor.yy220.pLimit = 0; yygotominor.yy220.pOffset = 0;}
-#line 2551 "parse.c"
+      case 147:
+#line 544 "parse.y"
+{yygotominor.yy230 = SQLITE_SO_DESC;}
+#line 2417 "parse.c"
         break;
+      case 149:
+#line 546 "parse.y"
+{yygotominor.yy384.z = 0; yygotominor.yy384.n = 0;}
+#line 2422 "parse.c"
+        break;
       case 155:
-#line 566 "parse.y"
-{yygotominor.yy220.pLimit = yymsp[0].minor.yy62; yygotominor.yy220.pOffset = 0;}
-#line 2556 "parse.c"
+#line 564 "parse.y"
+{yygotominor.yy270.pLimit = 0; yygotominor.yy270.pOffset = 0;}
+#line 2427 "parse.c"
         break;
       case 156:
-#line 568 "parse.y"
-{yygotominor.yy220.pLimit = yymsp[-2].minor.yy62; yygotominor.yy220.pOffset = yymsp[0].minor.yy62;}
-#line 2561 "parse.c"
+#line 565 "parse.y"
+{yygotominor.yy270.pLimit = yymsp[0].minor.yy178; yygotominor.yy270.pOffset = 0;}
+#line 2432 "parse.c"
         break;
       case 157:
-#line 570 "parse.y"
-{yygotominor.yy220.pOffset = yymsp[-2].minor.yy62; yygotominor.yy220.pLimit = yymsp[0].minor.yy62;}
-#line 2566 "parse.c"
+#line 567 "parse.y"
+{yygotominor.yy270.pLimit = yymsp[-2].minor.yy178; yygotominor.yy270.pOffset = yymsp[0].minor.yy178;}
+#line 2437 "parse.c"
         break;
       case 158:
-#line 574 "parse.y"
-{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy151,yymsp[0].minor.yy62);}
-#line 2571 "parse.c"
+#line 569 "parse.y"
+{yygotominor.yy270.pOffset = yymsp[-2].minor.yy178; yygotominor.yy270.pLimit = yymsp[0].minor.yy178;}
+#line 2442 "parse.c"
         break;
-      case 161:
-#line 585 "parse.y"
-{sqlite3Update(pParse,yymsp[-3].minor.yy151,yymsp[-1].minor.yy418,yymsp[0].minor.yy62,yymsp[-4].minor.yy280);}
-#line 2576 "parse.c"
+      case 159:
+#line 573 "parse.y"
+{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy285,yymsp[0].minor.yy178);}
+#line 2447 "parse.c"
         break;
       case 162:
-#line 591 "parse.y"
-{yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-4].minor.yy418,yymsp[0].minor.yy62,&yymsp[-2].minor.yy198);}
-#line 2581 "parse.c"
+#line 584 "parse.y"
+{sqlite3Update(pParse,yymsp[-3].minor.yy285,yymsp[-1].minor.yy462,yymsp[0].minor.yy178,yymsp[-4].minor.yy230);}
+#line 2452 "parse.c"
         break;
       case 163:
-#line 592 "parse.y"
-{yygotominor.yy418 = sqlite3ExprListAppend(0,yymsp[0].minor.yy62,&yymsp[-2].minor.yy198);}
-#line 2586 "parse.c"
+#line 590 "parse.y"
+{yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);}
+#line 2457 "parse.c"
         break;
       case 164:
-#line 598 "parse.y"
-{sqlite3Insert(pParse, yymsp[-5].minor.yy151, yymsp[-1].minor.yy418, 0, yymsp[-4].minor.yy240, yymsp[-7].minor.yy280);}
-#line 2591 "parse.c"
+#line 591 "parse.y"
+{yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);}
+#line 2462 "parse.c"
         break;
       case 165:
-#line 600 "parse.y"
-{sqlite3Insert(pParse, yymsp[-2].minor.yy151, 0, yymsp[0].minor.yy375, yymsp[-1].minor.yy240, yymsp[-4].minor.yy280);}
-#line 2596 "parse.c"
+#line 597 "parse.y"
+{sqlite3Insert(pParse, yymsp[-5].minor.yy285, yymsp[-1].minor.yy462, 0, yymsp[-4].minor.yy160, yymsp[-7].minor.yy230);}
+#line 2467 "parse.c"
         break;
-      case 168:
-      case 240:
-#line 610 "parse.y"
-{yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-2].minor.yy418,yymsp[0].minor.yy62,0);}
-#line 2602 "parse.c"
+      case 166:
+#line 599 "parse.y"
+{sqlite3Insert(pParse, yymsp[-2].minor.yy285, 0, yymsp[0].minor.yy239, yymsp[-1].minor.yy160, yymsp[-4].minor.yy230);}
+#line 2472 "parse.c"
         break;
       case 169:
-      case 241:
-#line 611 "parse.y"
-{yygotominor.yy418 = sqlite3ExprListAppend(0,yymsp[0].minor.yy62,0);}
-#line 2608 "parse.c"
+      case 227:
+#line 609 "parse.y"
+{yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[0].minor.yy178,0);}
+#line 2478 "parse.c"
         break;
-      case 172:
-#line 620 "parse.y"
-{yygotominor.yy240 = sqlite3IdListAppend(yymsp[-2].minor.yy240,&yymsp[0].minor.yy198);}
-#line 2613 "parse.c"
+      case 170:
+      case 228:
+#line 610 "parse.y"
+{yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,0);}
+#line 2484 "parse.c"
         break;
       case 173:
-#line 621 "parse.y"
-{yygotominor.yy240 = sqlite3IdListAppend(0,&yymsp[0].minor.yy198);}
-#line 2618 "parse.c"
+#line 619 "parse.y"
+{yygotominor.yy160 = sqlite3IdListAppend(yymsp[-2].minor.yy160,&yymsp[0].minor.yy384);}
+#line 2489 "parse.c"
         break;
-      case 175:
-#line 632 "parse.y"
-{yygotominor.yy62 = yymsp[-1].minor.yy62; sqlite3ExprSpan(yygotominor.yy62,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
-#line 2623 "parse.c"
+      case 174:
+#line 620 "parse.y"
+{yygotominor.yy160 = sqlite3IdListAppend(0,&yymsp[0].minor.yy384);}
+#line 2494 "parse.c"
         break;
       case 176:
-      case 181:
+#line 631 "parse.y"
+{yygotominor.yy178 = yymsp[-1].minor.yy178; sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+#line 2499 "parse.c"
+        break;
+      case 177:
       case 182:
       case 183:
-      case 184:
-#line 633 "parse.y"
-{yygotominor.yy62 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
-#line 2632 "parse.c"
+#line 632 "parse.y"
+{yygotominor.yy178 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+#line 2506 "parse.c"
         break;
-      case 177:
       case 178:
-#line 634 "parse.y"
-{yygotominor.yy62 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
-#line 2638 "parse.c"
-        break;
       case 179:
-#line 636 "parse.y"
+#line 633 "parse.y"
+{yygotominor.yy178 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+#line 2512 "parse.c"
+        break;
+      case 180:
+#line 635 "parse.y"
 {
-  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy198);
-  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy198);
-  yygotominor.yy62 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
+  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384);
+  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy384);
+  yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
 }
-#line 2647 "parse.c"
+#line 2521 "parse.c"
         break;
-      case 180:
-#line 641 "parse.y"
+      case 181:
+#line 640 "parse.y"
 {
-  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy198);
-  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy198);
-  Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy198);
+  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy384);
+  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384);
+  Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy384);
   Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
-  yygotominor.yy62 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
+  yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
 }
-#line 2658 "parse.c"
+#line 2532 "parse.c"
         break;
-      case 185:
-#line 652 "parse.y"
-{yygotominor.yy62 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
-#line 2663 "parse.c"
+      case 184:
+#line 649 "parse.y"
+{yygotominor.yy178 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+#line 2537 "parse.c"
         break;
-      case 186:
-#line 653 "parse.y"
+      case 185:
+#line 650 "parse.y"
 {
   Token *pToken = &yymsp[0].minor.yy0;
-  Expr *pExpr = yygotominor.yy62 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
+  Expr *pExpr = yygotominor.yy178 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
   sqlite3ExprAssignVarNumber(pParse, pExpr);
 }
-#line 2672 "parse.c"
+#line 2546 "parse.c"
         break;
-      case 187:
-#line 659 "parse.y"
+      case 186:
+#line 656 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy62, 0, &yymsp[-1].minor.yy198);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy178, 0, &yymsp[-1].minor.yy384);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
 }
-#line 2680 "parse.c"
+#line 2554 "parse.c"
         break;
-      case 188:
-#line 664 "parse.y"
+      case 187:
+#line 661 "parse.y"
 {
-  yygotominor.yy62 = sqlite3ExprFunction(yymsp[-1].minor.yy418, &yymsp[-4].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
-  if( yymsp[-2].minor.yy280 ){
-    yygotominor.yy62->flags |= EP_Distinct;
+  yygotominor.yy178 = sqlite3ExprFunction(yymsp[-1].minor.yy462, &yymsp[-4].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+  if( yymsp[-2].minor.yy230 && yygotominor.yy178 ){
+    yygotominor.yy178->flags |= EP_Distinct;
   }
 }
-#line 2691 "parse.c"
+#line 2565 "parse.c"
         break;
-      case 189:
-#line 671 "parse.y"
+      case 188:
+#line 668 "parse.y"
 {
-  yygotominor.yy62 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
 }
-#line 2699 "parse.c"
+#line 2573 "parse.c"
         break;
-      case 190:
-#line 675 "parse.y"
+      case 189:
+#line 672 "parse.y"
 {
   /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
   ** treated as functions that return constants */
-  yygotominor.yy62 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
-  if( yygotominor.yy62 ) yygotominor.yy62->op = TK_CONST_FUNC;  
+  yygotominor.yy178 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
+  if( yygotominor.yy178 ) yygotominor.yy178->op = TK_CONST_FUNC;  
 }
-#line 2709 "parse.c"
+#line 2583 "parse.c"
         break;
+      case 190:
       case 191:
       case 192:
       case 193:
@@ -2713,516 +2587,501 @@
       case 195:
       case 196:
       case 197:
+#line 678 "parse.y"
+{yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy178, yymsp[0].minor.yy178, 0);}
+#line 2595 "parse.c"
+        break;
       case 198:
+#line 688 "parse.y"
+{yygotominor.yy440.eOperator = yymsp[0].minor.yy0; yygotominor.yy440.not = 0;}
+#line 2600 "parse.c"
+        break;
       case 199:
-      case 200:
-      case 201:
-      case 202:
-      case 203:
-      case 204:
-      case 205:
-      case 206:
-      case 207:
-      case 208:
-#line 681 "parse.y"
-{yygotominor.yy62 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy62, yymsp[0].minor.yy62, 0);}
-#line 2731 "parse.c"
+#line 689 "parse.y"
+{yygotominor.yy440.eOperator = yymsp[0].minor.yy0; yygotominor.yy440.not = 1;}
+#line 2605 "parse.c"
         break;
-      case 209:
-#line 700 "parse.y"
-{yygotominor.yy222.operator = yymsp[0].minor.yy0; yygotominor.yy222.not = 0;}
-#line 2736 "parse.c"
-        break;
-      case 210:
-#line 701 "parse.y"
-{yygotominor.yy222.operator = yymsp[0].minor.yy0; yygotominor.yy222.not = 1;}
-#line 2741 "parse.c"
-        break;
-      case 213:
-#line 705 "parse.y"
+      case 202:
+#line 694 "parse.y"
 {
-  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy62, 0);
-  pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy62, 0);
-  if( yymsp[0].minor.yy62 ){
-    pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy62, 0);
+  ExprList *pList;
+  pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy178, 0);
+  pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy178, 0);
+  if( yymsp[0].minor.yy178 ){
+    pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy178, 0);
   }
-  yygotominor.yy62 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy222.operator);
-  if( yymsp[-2].minor.yy222.not ) yygotominor.yy62 = sqlite3Expr(TK_NOT, yygotominor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62, &yymsp[-3].minor.yy62->span, &yymsp[-1].minor.yy62->span);
+  yygotominor.yy178 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy440.eOperator);
+  if( yymsp[-2].minor.yy440.not ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy178->span, &yymsp[-1].minor.yy178->span);
 }
-#line 2755 "parse.c"
+#line 2620 "parse.c"
         break;
-      case 214:
-#line 716 "parse.y"
+      case 203:
+#line 706 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-1].minor.yy62->span,&yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy178->span,&yymsp[0].minor.yy0);
 }
-#line 2763 "parse.c"
+#line 2628 "parse.c"
         break;
-      case 215:
-#line 720 "parse.y"
+      case 204:
+#line 710 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-2].minor.yy62->span,&yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0);
 }
-#line 2771 "parse.c"
+#line 2636 "parse.c"
         break;
-      case 216:
-#line 724 "parse.y"
+      case 205:
+#line 714 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-1].minor.yy62->span,&yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0);
 }
-#line 2779 "parse.c"
+#line 2644 "parse.c"
         break;
-      case 217:
-#line 728 "parse.y"
+      case 206:
+#line 718 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-2].minor.yy62->span,&yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,&yymsp[0].minor.yy0);
 }
-#line 2787 "parse.c"
+#line 2652 "parse.c"
         break;
-      case 218:
-#line 732 "parse.y"
+      case 207:
+#line 722 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-3].minor.yy62->span,&yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span);
 }
-#line 2795 "parse.c"
+#line 2660 "parse.c"
         break;
-      case 219:
-      case 220:
-#line 736 "parse.y"
+      case 208:
+#line 726 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy62->span);
+  yygotominor.yy178 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span);
 }
-#line 2804 "parse.c"
+#line 2668 "parse.c"
         break;
-      case 221:
-#line 744 "parse.y"
+      case 209:
+#line 730 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy62->span);
+  yygotominor.yy178 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span);
 }
-#line 2812 "parse.c"
+#line 2676 "parse.c"
         break;
-      case 222:
-#line 748 "parse.y"
+      case 212:
+#line 737 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy62->span);
-}
-#line 2820 "parse.c"
-        break;
-      case 225:
-#line 755 "parse.y"
-{
-  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy62, 0);
-  pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy62, 0);
-  yygotominor.yy62 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy62, 0, 0);
-  if( yygotominor.yy62 ){
-    yygotominor.yy62->pList = pList;
+  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0);
+  pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy178, 0);
+  yygotominor.yy178 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy178, 0, 0);
+  if( yygotominor.yy178 ){
+    yygotominor.yy178->pList = pList;
   }else{
     sqlite3ExprListDelete(pList);
   } 
-  if( yymsp[-3].minor.yy280 ) yygotominor.yy62 = sqlite3Expr(TK_NOT, yygotominor.yy62, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy62,&yymsp[-4].minor.yy62->span,&yymsp[0].minor.yy62->span);
+  if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy178->span);
 }
-#line 2836 "parse.c"
+#line 2692 "parse.c"
         break;
-      case 228:
-#line 771 "parse.y"
+      case 215:
+#line 753 "parse.y"
 {
-    yygotominor.yy62 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy62, 0, 0);
-    if( yygotominor.yy62 ){
-      yygotominor.yy62->pList = yymsp[-1].minor.yy418;
+    yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0);
+    if( yygotominor.yy178 ){
+      yygotominor.yy178->pList = yymsp[-1].minor.yy462;
     }else{
-      sqlite3ExprListDelete(yymsp[-1].minor.yy418);
+      sqlite3ExprListDelete(yymsp[-1].minor.yy462);
     }
-    if( yymsp[-3].minor.yy280 ) yygotominor.yy62 = sqlite3Expr(TK_NOT, yygotominor.yy62, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy62,&yymsp[-4].minor.yy62->span,&yymsp[0].minor.yy0);
+    if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0);
   }
-#line 2850 "parse.c"
+#line 2706 "parse.c"
         break;
-      case 229:
-#line 781 "parse.y"
+      case 216:
+#line 763 "parse.y"
 {
-    yygotominor.yy62 = sqlite3Expr(TK_SELECT, 0, 0, 0);
-    if( yygotominor.yy62 ){
-      yygotominor.yy62->pSelect = yymsp[-1].minor.yy375;
+    yygotominor.yy178 = sqlite3Expr(TK_SELECT, 0, 0, 0);
+    if( yygotominor.yy178 ){
+      yygotominor.yy178->pSelect = yymsp[-1].minor.yy239;
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy375);
+      sqlite3SelectDelete(yymsp[-1].minor.yy239);
     }
-    sqlite3ExprSpan(yygotominor.yy62,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
   }
-#line 2863 "parse.c"
+#line 2719 "parse.c"
         break;
-      case 230:
-#line 790 "parse.y"
+      case 217:
+#line 772 "parse.y"
 {
-    yygotominor.yy62 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy62, 0, 0);
-    if( yygotominor.yy62 ){
-      yygotominor.yy62->pSelect = yymsp[-1].minor.yy375;
+    yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0);
+    if( yygotominor.yy178 ){
+      yygotominor.yy178->pSelect = yymsp[-1].minor.yy239;
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy375);
+      sqlite3SelectDelete(yymsp[-1].minor.yy239);
     }
-    if( yymsp[-3].minor.yy280 ) yygotominor.yy62 = sqlite3Expr(TK_NOT, yygotominor.yy62, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy62,&yymsp[-4].minor.yy62->span,&yymsp[0].minor.yy0);
+    if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0);
   }
-#line 2877 "parse.c"
+#line 2733 "parse.c"
         break;
-      case 231:
-#line 800 "parse.y"
+      case 218:
+#line 782 "parse.y"
 {
-    SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy198,&yymsp[0].minor.yy198);
-    yygotominor.yy62 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy62, 0, 0);
-    if( yygotominor.yy62 ){
-      yygotominor.yy62->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0);
+    SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384);
+    yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy178, 0, 0);
+    if( yygotominor.yy178 ){
+      yygotominor.yy178->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0);
     }else{
       sqlite3SrcListDelete(pSrc);
     }
-    if( yymsp[-2].minor.yy280 ) yygotominor.yy62 = sqlite3Expr(TK_NOT, yygotominor.yy62, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy62,&yymsp[-3].minor.yy62->span,yymsp[0].minor.yy198.z?&yymsp[0].minor.yy198:&yymsp[-1].minor.yy198);
+    if( yymsp[-2].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,yymsp[0].minor.yy384.z?&yymsp[0].minor.yy384:&yymsp[-1].minor.yy384);
   }
-#line 2892 "parse.c"
+#line 2748 "parse.c"
         break;
-      case 232:
-#line 811 "parse.y"
+      case 219:
+#line 793 "parse.y"
 {
-    Expr *p = yygotominor.yy62 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
+    Expr *p = yygotominor.yy178 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
     if( p ){
-      p->pSelect = yymsp[-1].minor.yy375;
+      p->pSelect = yymsp[-1].minor.yy239;
       sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy375);
+      sqlite3SelectDelete(yymsp[-1].minor.yy239);
     }
   }
-#line 2905 "parse.c"
+#line 2761 "parse.c"
         break;
-      case 233:
-#line 823 "parse.y"
+      case 220:
+#line 805 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy62, yymsp[-1].minor.yy62, 0);
-  if( yygotominor.yy62 ){
-    yygotominor.yy62->pList = yymsp[-2].minor.yy418;
+  yygotominor.yy178 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, 0);
+  if( yygotominor.yy178 ){
+    yygotominor.yy178->pList = yymsp[-2].minor.yy462;
   }else{
-    sqlite3ExprListDelete(yymsp[-2].minor.yy418);
+    sqlite3ExprListDelete(yymsp[-2].minor.yy462);
   }
-  sqlite3ExprSpan(yygotominor.yy62, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy178, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
 }
-#line 2918 "parse.c"
+#line 2774 "parse.c"
         break;
-      case 234:
-#line 834 "parse.y"
+      case 221:
+#line 816 "parse.y"
 {
-  yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-4].minor.yy418, yymsp[-2].minor.yy62, 0);
-  yygotominor.yy418 = sqlite3ExprListAppend(yygotominor.yy418, yymsp[0].minor.yy62, 0);
+  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, yymsp[-2].minor.yy178, 0);
+  yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0);
 }
-#line 2926 "parse.c"
+#line 2782 "parse.c"
         break;
-      case 235:
-#line 838 "parse.y"
+      case 222:
+#line 820 "parse.y"
 {
-  yygotominor.yy418 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy62, 0);
-  yygotominor.yy418 = sqlite3ExprListAppend(yygotominor.yy418, yymsp[0].minor.yy62, 0);
+  yygotominor.yy462 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0);
+  yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0);
 }
-#line 2934 "parse.c"
+#line 2790 "parse.c"
         break;
-      case 244:
-#line 863 "parse.y"
+      case 231:
+#line 847 "parse.y"
 {
-  if( yymsp[-9].minor.yy280!=OE_None ) yymsp[-9].minor.yy280 = yymsp[0].minor.yy280;
-  if( yymsp[-9].minor.yy280==OE_Default) yymsp[-9].minor.yy280 = OE_Abort;
-  sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy198, &yymsp[-6].minor.yy198, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy198,0),yymsp[-2].minor.yy418,yymsp[-9].minor.yy280, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0);
+  sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy384, &yymsp[-5].minor.yy384, sqlite3SrcListAppend(0,&yymsp[-3].minor.yy384,0), yymsp[-1].minor.yy462, yymsp[-9].minor.yy230,
+                      &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy230);
 }
-#line 2943 "parse.c"
+#line 2798 "parse.c"
         break;
-      case 245:
-      case 292:
-#line 870 "parse.y"
-{yygotominor.yy280 = OE_Abort;}
-#line 2949 "parse.c"
+      case 232:
+      case 277:
+#line 853 "parse.y"
+{yygotominor.yy230 = OE_Abort;}
+#line 2804 "parse.c"
         break;
-      case 246:
-#line 871 "parse.y"
-{yygotominor.yy280 = OE_None;}
-#line 2954 "parse.c"
+      case 233:
+#line 854 "parse.y"
+{yygotominor.yy230 = OE_None;}
+#line 2809 "parse.c"
         break;
-      case 249:
-#line 881 "parse.y"
+      case 236:
+#line 864 "parse.y"
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy198.n>0 ){
+  if( yymsp[-1].minor.yy384.n>0 ){
     p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
-    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy198.z, yymsp[-1].minor.yy198.n);
+    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy384.z, yymsp[-1].minor.yy384.n);
   }
-  yygotominor.yy418 = sqlite3ExprListAppend(yymsp[-4].minor.yy418, p, &yymsp[-2].minor.yy198);
+  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, p, &yymsp[-2].minor.yy384);
+  if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230;
 }
-#line 2966 "parse.c"
+#line 2822 "parse.c"
         break;
-      case 250:
-#line 889 "parse.y"
+      case 237:
+#line 873 "parse.y"
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy198.n>0 ){
+  if( yymsp[-1].minor.yy384.n>0 ){
     p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
-    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy198.z, yymsp[-1].minor.yy198.n);
+    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy384.z, yymsp[-1].minor.yy384.n);
   }
-  yygotominor.yy418 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy198);
+  yygotominor.yy462 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy384);
+  if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230;
 }
-#line 2978 "parse.c"
+#line 2835 "parse.c"
         break;
-      case 252:
-#line 902 "parse.y"
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy151);}
-#line 2983 "parse.c"
+      case 239:
+#line 887 "parse.y"
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy285, yymsp[-1].minor.yy230);}
+#line 2840 "parse.c"
         break;
-      case 253:
-      case 254:
-#line 906 "parse.y"
-{sqlite3Vacuum(pParse,0);}
-#line 2989 "parse.c"
+      case 240:
+      case 241:
+#line 891 "parse.y"
+{sqlite3Vacuum(pParse);}
+#line 2846 "parse.c"
         break;
-      case 255:
-      case 257:
-#line 912 "parse.y"
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy198,&yymsp[-2].minor.yy198,&yymsp[0].minor.yy198,0);}
-#line 2995 "parse.c"
+      case 242:
+      case 244:
+#line 897 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,0);}
+#line 2852 "parse.c"
         break;
-      case 256:
-#line 913 "parse.y"
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy198,&yymsp[-2].minor.yy198,&yymsp[0].minor.yy0,0);}
-#line 3000 "parse.c"
+      case 243:
+#line 898 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy0,0);}
+#line 2857 "parse.c"
         break;
-      case 258:
-#line 915 "parse.y"
+      case 245:
+#line 900 "parse.y"
 {
-  sqlite3Pragma(pParse,&yymsp[-3].minor.yy198,&yymsp[-2].minor.yy198,&yymsp[0].minor.yy198,1);
+  sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,1);
 }
-#line 3007 "parse.c"
+#line 2864 "parse.c"
         break;
-      case 259:
-#line 918 "parse.y"
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy198,&yymsp[-3].minor.yy198,&yymsp[-1].minor.yy198,0);}
-#line 3012 "parse.c"
+      case 246:
+#line 903 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384,&yymsp[-1].minor.yy384,0);}
+#line 2869 "parse.c"
         break;
-      case 260:
-#line 919 "parse.y"
-{sqlite3Pragma(pParse,&yymsp[-1].minor.yy198,&yymsp[0].minor.yy198,0,0);}
-#line 3017 "parse.c"
+      case 247:
+#line 904 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384,0,0);}
+#line 2874 "parse.c"
         break;
-      case 267:
-#line 932 "parse.y"
+      case 253:
+#line 916 "parse.y"
 {
   Token all;
-  all.z = yymsp[-3].minor.yy198.z;
-  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy198.z) + yymsp[0].minor.yy0.n;
-  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy360, &all);
+  all.z = yymsp[-3].minor.yy384.z;
+  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy384.z) + yymsp[0].minor.yy0.n;
+  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy247, &all);
 }
-#line 3027 "parse.c"
+#line 2884 "parse.c"
         break;
-      case 268:
-#line 941 "parse.y"
+      case 254:
+#line 925 "parse.y"
 {
-  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy198, &yymsp[-6].minor.yy198, yymsp[-5].minor.yy280, yymsp[-4].minor.yy30.a, yymsp[-4].minor.yy30.b, yymsp[-2].minor.yy151, yymsp[-1].minor.yy280, yymsp[0].minor.yy62, yymsp[-9].minor.yy280);
-  yygotominor.yy198 = (yymsp[-6].minor.yy198.n==0?yymsp[-7].minor.yy198:yymsp[-6].minor.yy198);
+  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy384, &yymsp[-6].minor.yy384, yymsp[-5].minor.yy230, yymsp[-4].minor.yy132.a, yymsp[-4].minor.yy132.b, yymsp[-2].minor.yy285, yymsp[-1].minor.yy230, yymsp[0].minor.yy178, yymsp[-9].minor.yy230);
+  yygotominor.yy384 = (yymsp[-6].minor.yy384.n==0?yymsp[-7].minor.yy384:yymsp[-6].minor.yy384);
 }
-#line 3035 "parse.c"
+#line 2892 "parse.c"
         break;
-      case 269:
-      case 272:
-#line 947 "parse.y"
-{ yygotominor.yy280 = TK_BEFORE; }
-#line 3041 "parse.c"
+      case 255:
+      case 258:
+#line 931 "parse.y"
+{ yygotominor.yy230 = TK_BEFORE; }
+#line 2898 "parse.c"
         break;
-      case 270:
-#line 948 "parse.y"
-{ yygotominor.yy280 = TK_AFTER;  }
-#line 3046 "parse.c"
+      case 256:
+#line 932 "parse.y"
+{ yygotominor.yy230 = TK_AFTER;  }
+#line 2903 "parse.c"
         break;
-      case 271:
-#line 949 "parse.y"
-{ yygotominor.yy280 = TK_INSTEAD;}
-#line 3051 "parse.c"
+      case 257:
+#line 933 "parse.y"
+{ yygotominor.yy230 = TK_INSTEAD;}
+#line 2908 "parse.c"
         break;
-      case 273:
-      case 274:
-      case 275:
-#line 954 "parse.y"
-{yygotominor.yy30.a = yymsp[0].major; yygotominor.yy30.b = 0;}
-#line 3058 "parse.c"
+      case 259:
+      case 260:
+#line 938 "parse.y"
+{yygotominor.yy132.a = yymsp[0].major; yygotominor.yy132.b = 0;}
+#line 2914 "parse.c"
         break;
-      case 276:
-#line 957 "parse.y"
-{yygotominor.yy30.a = TK_UPDATE; yygotominor.yy30.b = yymsp[0].minor.yy240;}
-#line 3063 "parse.c"
+      case 261:
+#line 940 "parse.y"
+{yygotominor.yy132.a = TK_UPDATE; yygotominor.yy132.b = yymsp[0].minor.yy160;}
+#line 2919 "parse.c"
         break;
-      case 277:
-      case 278:
-#line 960 "parse.y"
-{ yygotominor.yy280 = TK_ROW; }
-#line 3069 "parse.c"
+      case 262:
+      case 263:
+#line 943 "parse.y"
+{ yygotominor.yy230 = TK_ROW; }
+#line 2925 "parse.c"
         break;
-      case 279:
-#line 962 "parse.y"
-{ yygotominor.yy280 = TK_STATEMENT; }
-#line 3074 "parse.c"
+      case 264:
+#line 945 "parse.y"
+{ yygotominor.yy230 = TK_STATEMENT; }
+#line 2930 "parse.c"
         break;
-      case 280:
-#line 965 "parse.y"
-{ yygotominor.yy62 = 0; }
-#line 3079 "parse.c"
+      case 265:
+#line 949 "parse.y"
+{ yygotominor.yy178 = 0; }
+#line 2935 "parse.c"
         break;
-      case 281:
-#line 966 "parse.y"
-{ yygotominor.yy62 = yymsp[0].minor.yy62; }
-#line 3084 "parse.c"
+      case 266:
+#line 950 "parse.y"
+{ yygotominor.yy178 = yymsp[0].minor.yy178; }
+#line 2940 "parse.c"
         break;
-      case 282:
-#line 970 "parse.y"
+      case 267:
+#line 954 "parse.y"
 {
-  yymsp[-2].minor.yy360->pNext = yymsp[0].minor.yy360;
-  yygotominor.yy360 = yymsp[-2].minor.yy360;
+  if( yymsp[-2].minor.yy247 ){
+    yymsp[-2].minor.yy247->pLast->pNext = yymsp[-1].minor.yy247;
+  }else{
+    yymsp[-2].minor.yy247 = yymsp[-1].minor.yy247;
+  }
+  yymsp[-2].minor.yy247->pLast = yymsp[-1].minor.yy247;
+  yygotominor.yy247 = yymsp[-2].minor.yy247;
 }
-#line 3092 "parse.c"
+#line 2953 "parse.c"
         break;
-      case 283:
-#line 974 "parse.y"
-{ yygotominor.yy360 = 0; }
-#line 3097 "parse.c"
+      case 268:
+#line 963 "parse.y"
+{ yygotominor.yy247 = 0; }
+#line 2958 "parse.c"
         break;
-      case 284:
-#line 980 "parse.y"
-{ yygotominor.yy360 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy198, yymsp[-1].minor.yy418, yymsp[0].minor.yy62, yymsp[-4].minor.yy280); }
-#line 3102 "parse.c"
+      case 269:
+#line 969 "parse.y"
+{ yygotominor.yy247 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy384, yymsp[-1].minor.yy462, yymsp[0].minor.yy178, yymsp[-4].minor.yy230); }
+#line 2963 "parse.c"
         break;
-      case 285:
-#line 985 "parse.y"
-{yygotominor.yy360 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy198, yymsp[-4].minor.yy240, yymsp[-1].minor.yy418, 0, yymsp[-7].minor.yy280);}
-#line 3107 "parse.c"
+      case 270:
+#line 974 "parse.y"
+{yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy384, yymsp[-4].minor.yy160, yymsp[-1].minor.yy462, 0, yymsp[-7].minor.yy230);}
+#line 2968 "parse.c"
         break;
-      case 286:
-#line 988 "parse.y"
-{yygotominor.yy360 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy198, yymsp[-1].minor.yy240, 0, yymsp[0].minor.yy375, yymsp[-4].minor.yy280);}
-#line 3112 "parse.c"
+      case 271:
+#line 977 "parse.y"
+{yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy384, yymsp[-1].minor.yy160, 0, yymsp[0].minor.yy239, yymsp[-4].minor.yy230);}
+#line 2973 "parse.c"
         break;
-      case 287:
-#line 992 "parse.y"
-{yygotominor.yy360 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy198, yymsp[0].minor.yy62);}
-#line 3117 "parse.c"
+      case 272:
+#line 981 "parse.y"
+{yygotominor.yy247 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy384, yymsp[0].minor.yy178);}
+#line 2978 "parse.c"
         break;
-      case 288:
-#line 995 "parse.y"
-{yygotominor.yy360 = sqlite3TriggerSelectStep(yymsp[0].minor.yy375); }
-#line 3122 "parse.c"
+      case 273:
+#line 984 "parse.y"
+{yygotominor.yy247 = sqlite3TriggerSelectStep(yymsp[0].minor.yy239); }
+#line 2983 "parse.c"
         break;
-      case 289:
-#line 998 "parse.y"
+      case 274:
+#line 987 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_RAISE, 0, 0, 0); 
-  yygotominor.yy62->iColumn = OE_Ignore;
-  sqlite3ExprSpan(yygotominor.yy62, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, 0); 
+  if( yygotominor.yy178 ){
+    yygotominor.yy178->iColumn = OE_Ignore;
+    sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+  }
 }
-#line 3131 "parse.c"
+#line 2994 "parse.c"
         break;
-      case 290:
-#line 1003 "parse.y"
+      case 275:
+#line 994 "parse.y"
 {
-  yygotominor.yy62 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy198); 
-  yygotominor.yy62->iColumn = yymsp[-3].minor.yy280;
-  sqlite3ExprSpan(yygotominor.yy62, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+  yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy384); 
+  if( yygotominor.yy178 ) {
+    yygotominor.yy178->iColumn = yymsp[-3].minor.yy230;
+    sqlite3ExprSpan(yygotominor.yy178, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+  }
 }
-#line 3140 "parse.c"
+#line 3005 "parse.c"
         break;
-      case 291:
-#line 1011 "parse.y"
-{yygotominor.yy280 = OE_Rollback;}
-#line 3145 "parse.c"
+      case 276:
+#line 1004 "parse.y"
+{yygotominor.yy230 = OE_Rollback;}
+#line 3010 "parse.c"
         break;
-      case 293:
-#line 1013 "parse.y"
-{yygotominor.yy280 = OE_Fail;}
-#line 3150 "parse.c"
+      case 278:
+#line 1006 "parse.y"
+{yygotominor.yy230 = OE_Fail;}
+#line 3015 "parse.c"
         break;
-      case 294:
-#line 1018 "parse.y"
+      case 279:
+#line 1011 "parse.y"
 {
-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy151);
+  sqlite3DropTrigger(pParse,yymsp[0].minor.yy285);
 }
-#line 3157 "parse.c"
+#line 3022 "parse.c"
         break;
-      case 295:
-#line 1024 "parse.y"
+      case 280:
+#line 1017 "parse.y"
 {
-  sqlite3Attach(pParse, &yymsp[-3].minor.yy198, &yymsp[-1].minor.yy198, yymsp[0].minor.yy361.type, &yymsp[0].minor.yy361.key);
+  sqlite3Attach(pParse, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, yymsp[0].minor.yy292);
 }
-#line 3164 "parse.c"
+#line 3029 "parse.c"
         break;
-      case 296:
-#line 1028 "parse.y"
-{ yygotominor.yy361.type = 0; }
-#line 3169 "parse.c"
+      case 281:
+#line 1022 "parse.y"
+{ yygotominor.yy292 = 0; }
+#line 3034 "parse.c"
         break;
-      case 297:
-#line 1029 "parse.y"
-{ yygotominor.yy361.type=1; yygotominor.yy361.key = yymsp[0].minor.yy198; }
-#line 3174 "parse.c"
+      case 282:
+#line 1023 "parse.y"
+{ yygotominor.yy292 = yymsp[0].minor.yy178; }
+#line 3039 "parse.c"
         break;
-      case 298:
-#line 1030 "parse.y"
-{ yygotominor.yy361.type=2; yygotominor.yy361.key = yymsp[0].minor.yy0; }
-#line 3179 "parse.c"
-        break;
-      case 301:
-#line 1036 "parse.y"
+      case 285:
+#line 1029 "parse.y"
 {
-  sqlite3Detach(pParse, &yymsp[0].minor.yy198);
+  sqlite3Detach(pParse, yymsp[0].minor.yy178);
 }
-#line 3186 "parse.c"
+#line 3046 "parse.c"
         break;
-      case 302:
-#line 1042 "parse.y"
+      case 286:
+#line 1035 "parse.y"
 {sqlite3Reindex(pParse, 0, 0);}
-#line 3191 "parse.c"
+#line 3051 "parse.c"
         break;
-      case 303:
-#line 1043 "parse.y"
-{sqlite3Reindex(pParse, &yymsp[-1].minor.yy198, &yymsp[0].minor.yy198);}
-#line 3196 "parse.c"
+      case 287:
+#line 1036 "parse.y"
+{sqlite3Reindex(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);}
+#line 3056 "parse.c"
         break;
-      case 304:
-#line 1048 "parse.y"
+      case 288:
+#line 1041 "parse.y"
 {sqlite3Analyze(pParse, 0, 0);}
-#line 3201 "parse.c"
+#line 3061 "parse.c"
         break;
-      case 305:
-#line 1049 "parse.y"
-{sqlite3Analyze(pParse, &yymsp[-1].minor.yy198, &yymsp[0].minor.yy198);}
-#line 3206 "parse.c"
+      case 289:
+#line 1042 "parse.y"
+{sqlite3Analyze(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);}
+#line 3066 "parse.c"
         break;
-      case 306:
-#line 1054 "parse.y"
+      case 290:
+#line 1047 "parse.y"
 {
-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy151,&yymsp[0].minor.yy198);
+  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy285,&yymsp[0].minor.yy384);
 }
-#line 3213 "parse.c"
+#line 3073 "parse.c"
         break;
-      case 307:
-#line 1057 "parse.y"
+      case 291:
+#line 1050 "parse.y"
 {
-  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy198);
+  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy384);
 }
-#line 3220 "parse.c"
+#line 3080 "parse.c"
         break;
-      case 308:
-#line 1060 "parse.y"
+      case 292:
+#line 1053 "parse.y"
 {
-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy151);
+  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy285);
 }
-#line 3227 "parse.c"
+#line 3087 "parse.c"
         break;
   };
   yygoto = yyRuleInfo[yyruleno].lhs;
@@ -3288,7 +3147,7 @@
       sqlite3ErrorMsg(pParse, "incomplete SQL statement");
     }
   }
-#line 3294 "parse.c"
+#line 3154 "parse.c"
   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
 }
 

Modified: packages/libdbd-sqlite3-perl/trunk/parse.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/parse.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/parse.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -1,145 +1,151 @@
-#define TK_END_OF_FILE                     1
-#define TK_ILLEGAL                         2
-#define TK_SPACE                           3
-#define TK_UNCLOSED_STRING                 4
-#define TK_COMMENT                         5
-#define TK_FUNCTION                        6
-#define TK_COLUMN                          7
-#define TK_AGG_FUNCTION                    8
-#define TK_AGG_COLUMN                      9
-#define TK_CONST_FUNC                     10
-#define TK_SEMI                           11
-#define TK_EXPLAIN                        12
-#define TK_QUERY                          13
-#define TK_PLAN                           14
-#define TK_BEGIN                          15
-#define TK_TRANSACTION                    16
-#define TK_DEFERRED                       17
-#define TK_IMMEDIATE                      18
-#define TK_EXCLUSIVE                      19
-#define TK_COMMIT                         20
-#define TK_END                            21
-#define TK_ROLLBACK                       22
-#define TK_CREATE                         23
-#define TK_TABLE                          24
-#define TK_TEMP                           25
-#define TK_LP                             26
-#define TK_RP                             27
-#define TK_AS                             28
-#define TK_COMMA                          29
-#define TK_ID                             30
-#define TK_ABORT                          31
-#define TK_AFTER                          32
-#define TK_ANALYZE                        33
-#define TK_ASC                            34
-#define TK_ATTACH                         35
-#define TK_BEFORE                         36
-#define TK_CASCADE                        37
-#define TK_CAST                           38
-#define TK_CONFLICT                       39
-#define TK_DATABASE                       40
-#define TK_DESC                           41
-#define TK_DETACH                         42
-#define TK_EACH                           43
-#define TK_FAIL                           44
-#define TK_FOR                            45
-#define TK_IGNORE                         46
-#define TK_INITIALLY                      47
-#define TK_INSTEAD                        48
-#define TK_LIKE_KW                        49
-#define TK_MATCH                          50
-#define TK_KEY                            51
-#define TK_OF                             52
-#define TK_OFFSET                         53
-#define TK_PRAGMA                         54
-#define TK_RAISE                          55
-#define TK_REPLACE                        56
-#define TK_RESTRICT                       57
-#define TK_ROW                            58
-#define TK_STATEMENT                      59
-#define TK_TRIGGER                        60
-#define TK_VACUUM                         61
-#define TK_VIEW                           62
-#define TK_REINDEX                        63
-#define TK_RENAME                         64
-#define TK_CTIME_KW                       65
-#define TK_ALTER                          66
-#define TK_OR                             67
-#define TK_AND                            68
-#define TK_NOT                            69
-#define TK_IS                             70
-#define TK_BETWEEN                        71
-#define TK_IN                             72
-#define TK_ISNULL                         73
-#define TK_NOTNULL                        74
-#define TK_NE                             75
-#define TK_EQ                             76
-#define TK_GT                             77
-#define TK_LE                             78
-#define TK_LT                             79
-#define TK_GE                             80
-#define TK_ESCAPE                         81
-#define TK_BITAND                         82
-#define TK_BITOR                          83
-#define TK_LSHIFT                         84
-#define TK_RSHIFT                         85
-#define TK_PLUS                           86
-#define TK_MINUS                          87
-#define TK_STAR                           88
-#define TK_SLASH                          89
-#define TK_REM                            90
-#define TK_CONCAT                         91
-#define TK_UMINUS                         92
-#define TK_UPLUS                          93
-#define TK_BITNOT                         94
-#define TK_STRING                         95
-#define TK_JOIN_KW                        96
-#define TK_CONSTRAINT                     97
-#define TK_DEFAULT                        98
-#define TK_NULL                           99
-#define TK_PRIMARY                        100
-#define TK_UNIQUE                         101
-#define TK_CHECK                          102
-#define TK_REFERENCES                     103
-#define TK_COLLATE                        104
-#define TK_AUTOINCR                       105
-#define TK_ON                             106
-#define TK_DELETE                         107
-#define TK_UPDATE                         108
-#define TK_INSERT                         109
-#define TK_SET                            110
-#define TK_DEFERRABLE                     111
-#define TK_FOREIGN                        112
-#define TK_DROP                           113
-#define TK_UNION                          114
-#define TK_ALL                            115
-#define TK_INTERSECT                      116
-#define TK_EXCEPT                         117
-#define TK_SELECT                         118
-#define TK_DISTINCT                       119
-#define TK_DOT                            120
-#define TK_FROM                           121
-#define TK_JOIN                           122
-#define TK_USING                          123
-#define TK_ORDER                          124
-#define TK_BY                             125
-#define TK_GROUP                          126
-#define TK_HAVING                         127
-#define TK_LIMIT                          128
-#define TK_WHERE                          129
-#define TK_INTO                           130
-#define TK_VALUES                         131
-#define TK_INTEGER                        132
-#define TK_FLOAT                          133
-#define TK_BLOB                           134
-#define TK_REGISTER                       135
-#define TK_VARIABLE                       136
-#define TK_EXISTS                         137
-#define TK_CASE                           138
-#define TK_WHEN                           139
-#define TK_THEN                           140
-#define TK_ELSE                           141
-#define TK_INDEX                          142
-#define TK_TO                             143
-#define TK_ADD                            144
-#define TK_COLUMNKW                       145
+#define TK_SEMI                            1
+#define TK_EXPLAIN                         2
+#define TK_QUERY                           3
+#define TK_PLAN                            4
+#define TK_BEGIN                           5
+#define TK_TRANSACTION                     6
+#define TK_DEFERRED                        7
+#define TK_IMMEDIATE                       8
+#define TK_EXCLUSIVE                       9
+#define TK_COMMIT                         10
+#define TK_END                            11
+#define TK_ROLLBACK                       12
+#define TK_CREATE                         13
+#define TK_TABLE                          14
+#define TK_IF                             15
+#define TK_NOT                            16
+#define TK_EXISTS                         17
+#define TK_TEMP                           18
+#define TK_LP                             19
+#define TK_RP                             20
+#define TK_AS                             21
+#define TK_COMMA                          22
+#define TK_ID                             23
+#define TK_ABORT                          24
+#define TK_AFTER                          25
+#define TK_ANALYZE                        26
+#define TK_ASC                            27
+#define TK_ATTACH                         28
+#define TK_BEFORE                         29
+#define TK_CASCADE                        30
+#define TK_CAST                           31
+#define TK_CONFLICT                       32
+#define TK_DATABASE                       33
+#define TK_DESC                           34
+#define TK_DETACH                         35
+#define TK_EACH                           36
+#define TK_FAIL                           37
+#define TK_FOR                            38
+#define TK_IGNORE                         39
+#define TK_INITIALLY                      40
+#define TK_INSTEAD                        41
+#define TK_LIKE_KW                        42
+#define TK_MATCH                          43
+#define TK_KEY                            44
+#define TK_OF                             45
+#define TK_OFFSET                         46
+#define TK_PRAGMA                         47
+#define TK_RAISE                          48
+#define TK_REPLACE                        49
+#define TK_RESTRICT                       50
+#define TK_ROW                            51
+#define TK_STATEMENT                      52
+#define TK_TRIGGER                        53
+#define TK_VACUUM                         54
+#define TK_VIEW                           55
+#define TK_REINDEX                        56
+#define TK_RENAME                         57
+#define TK_CTIME_KW                       58
+#define TK_OR                             59
+#define TK_AND                            60
+#define TK_IS                             61
+#define TK_BETWEEN                        62
+#define TK_IN                             63
+#define TK_ISNULL                         64
+#define TK_NOTNULL                        65
+#define TK_NE                             66
+#define TK_EQ                             67
+#define TK_GT                             68
+#define TK_LE                             69
+#define TK_LT                             70
+#define TK_GE                             71
+#define TK_ESCAPE                         72
+#define TK_BITAND                         73
+#define TK_BITOR                          74
+#define TK_LSHIFT                         75
+#define TK_RSHIFT                         76
+#define TK_PLUS                           77
+#define TK_MINUS                          78
+#define TK_STAR                           79
+#define TK_SLASH                          80
+#define TK_REM                            81
+#define TK_CONCAT                         82
+#define TK_UMINUS                         83
+#define TK_UPLUS                          84
+#define TK_BITNOT                         85
+#define TK_STRING                         86
+#define TK_JOIN_KW                        87
+#define TK_CONSTRAINT                     88
+#define TK_DEFAULT                        89
+#define TK_NULL                           90
+#define TK_PRIMARY                        91
+#define TK_UNIQUE                         92
+#define TK_CHECK                          93
+#define TK_REFERENCES                     94
+#define TK_COLLATE                        95
+#define TK_AUTOINCR                       96
+#define TK_ON                             97
+#define TK_DELETE                         98
+#define TK_UPDATE                         99
+#define TK_INSERT                         100
+#define TK_SET                            101
+#define TK_DEFERRABLE                     102
+#define TK_FOREIGN                        103
+#define TK_DROP                           104
+#define TK_UNION                          105
+#define TK_ALL                            106
+#define TK_EXCEPT                         107
+#define TK_INTERSECT                      108
+#define TK_SELECT                         109
+#define TK_DISTINCT                       110
+#define TK_DOT                            111
+#define TK_FROM                           112
+#define TK_JOIN                           113
+#define TK_USING                          114
+#define TK_ORDER                          115
+#define TK_BY                             116
+#define TK_GROUP                          117
+#define TK_HAVING                         118
+#define TK_LIMIT                          119
+#define TK_WHERE                          120
+#define TK_INTO                           121
+#define TK_VALUES                         122
+#define TK_INTEGER                        123
+#define TK_FLOAT                          124
+#define TK_BLOB                           125
+#define TK_REGISTER                       126
+#define TK_VARIABLE                       127
+#define TK_CASE                           128
+#define TK_WHEN                           129
+#define TK_THEN                           130
+#define TK_ELSE                           131
+#define TK_INDEX                          132
+#define TK_ALTER                          133
+#define TK_TO                             134
+#define TK_ADD                            135
+#define TK_COLUMNKW                       136
+#define TK_TO_TEXT                        137
+#define TK_TO_BLOB                        138
+#define TK_TO_NUMERIC                     139
+#define TK_TO_INT                         140
+#define TK_TO_REAL                        141
+#define TK_END_OF_FILE                    142
+#define TK_ILLEGAL                        143
+#define TK_SPACE                          144
+#define TK_UNCLOSED_STRING                145
+#define TK_COMMENT                        146
+#define TK_FUNCTION                       147
+#define TK_COLUMN                         148
+#define TK_AGG_FUNCTION                   149
+#define TK_AGG_COLUMN                     150
+#define TK_CONST_FUNC                     151

Modified: packages/libdbd-sqlite3-perl/trunk/pragma.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/pragma.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/pragma.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.100 2005/09/20 17:42:23 drh Exp $
+** $Id: pragma.c,v 1.120 2006/03/03 21:20:17 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -36,7 +36,7 @@
 ** to support legacy SQL code.  The safety level used to be boolean
 ** and older scripts may have used numbers 0 for OFF and 1 for ON.
 */
-static int getSafetyLevel(const u8 *z){
+static int getSafetyLevel(const char *z){
                              /* 123456789 123456789 */
   static const char zText[] = "onoffalseyestruefull";
   static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
@@ -58,7 +58,7 @@
 /*
 ** Interpret the given string as a boolean value.
 */
-static int getBoolean(const u8 *z){
+static int getBoolean(const char *z){
   return getSafetyLevel(z)&1;
 }
 
@@ -128,7 +128,7 @@
   sqlite3VdbeAddOp(v, OP_Integer, value, 0);
   if( pParse->explain==0 ){
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC);
   }
   sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
 }
@@ -151,9 +151,18 @@
     { "short_column_names",       SQLITE_ShortColNames },
     { "count_changes",            SQLITE_CountRows     },
     { "empty_result_callbacks",   SQLITE_NullCallback  },
+    { "legacy_file_format",       SQLITE_LegacyFileFmt },
+    { "fullfsync",                SQLITE_FullFSync     },
+#ifndef SQLITE_OMIT_CHECK
+    { "ignore_check_constraints", SQLITE_IgnoreChecks  },
+#endif
     /* The following is VERY experimental */
     { "writable_schema",          SQLITE_WriteSchema   },
     { "omit_readlock",            SQLITE_NoReadlock    },
+
+    /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
+    ** flag if there are any active statements. */
+    { "read_uncommitted",         SQLITE_ReadUncommitted },
   };
   int i;
   const struct sPragmaType *p;
@@ -172,10 +181,6 @@
             db->flags &= ~p->mask;
           }
         }
-        /* If one of these pragmas is executed, any prepared statements
-        ** need to be recompiled.
-        */
-        sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
       }
       return 1;
     }
@@ -222,6 +227,13 @@
   if( iDb<0 ) return;
   pDb = &db->aDb[iDb];
 
+  /* If the temp database has been explicitly named as part of the 
+  ** pragma, make sure it is open. 
+  */
+  if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){
+    return;
+  }
+
   zLeft = sqlite3NameFromToken(pId);
   if( !zLeft ) return;
   if( minusFlag ){
@@ -266,7 +278,7 @@
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     if( !zRight ){
       sqlite3VdbeSetNumCols(v, 1);
-      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC);
       addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
       sqlite3VdbeChangeP1(v, addr, iDb);
       sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
@@ -280,8 +292,8 @@
       sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
       sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
       sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
-      pDb->cache_size = size;
-      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
+      pDb->pSchema->cache_size = size;
+      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
     }
   }else
 
@@ -342,12 +354,12 @@
   if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     if( !zRight ){
-      returnSingleInt(pParse, "cache_size", pDb->cache_size);
+      returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
     }else{
       int size = atoi(zRight);
       if( size<0 ) size = -size;
-      pDb->cache_size = size;
-      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
+      pDb->pSchema->cache_size = size;
+      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
     }
   }else
 
@@ -384,7 +396,8 @@
     if( !zRight ){
       if( sqlite3_temp_directory ){
         sqlite3VdbeSetNumCols(v, 1);
-        sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
+            "temp_store_directory", P3_STATIC);
         sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
         sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
       }
@@ -428,7 +441,6 @@
             "Safety level may not be changed inside a transaction");
       }else{
         pDb->safety_level = getSafetyLevel(zRight)+1;
-        sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
       }
     }
   }else
@@ -460,22 +472,23 @@
     pTab = sqlite3FindTable(db, zRight, zDb);
     if( pTab ){
       int i;
+      Column *pCol;
       sqlite3VdbeSetNumCols(v, 6);
-      sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
-      sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
-      sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
-      sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
-      sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
-      sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC);
+      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC);
+      sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC);
+      sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC);
+      sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC);
       sqlite3ViewGetColumnNames(pParse, pTab);
-      for(i=0; i<pTab->nCol; i++){
+      for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
         sqlite3VdbeAddOp(v, OP_Integer, i, 0);
-        sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zName, 0);
+        sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0);
         sqlite3VdbeOp3(v, OP_String8, 0, 0,
-           pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
-        sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
-        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
-        sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
+           pCol->zType ? pCol->zType : "", 0);
+        sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0);
+        sqlite3ExprCode(pParse, pCol->pDflt);
+        sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0);
         sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
       }
     }
@@ -490,9 +503,9 @@
       int i;
       pTab = pIdx->pTable;
       sqlite3VdbeSetNumCols(v, 3);
-      sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
-      sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
-      sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC);
+      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC);
+      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC);
       for(i=0; i<pIdx->nColumn; i++){
         int cnum = pIdx->aiColumn[i];
         sqlite3VdbeAddOp(v, OP_Integer, i, 0);
@@ -515,9 +528,9 @@
       if( pIdx ){
         int i = 0; 
         sqlite3VdbeSetNumCols(v, 3);
-        sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
-        sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
-        sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+        sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+        sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC);
         while(pIdx){
           sqlite3VdbeAddOp(v, OP_Integer, i, 0);
           sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
@@ -534,9 +547,9 @@
     int i;
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     sqlite3VdbeSetNumCols(v, 3);
-    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
-    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
-    sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC);
     for(i=0; i<db->nDb; i++){
       if( db->aDb[i].pBt==0 ) continue;
       assert( db->aDb[i].zName!=0 );
@@ -552,8 +565,8 @@
     int i = 0;
     HashElem *p;
     sqlite3VdbeSetNumCols(v, 2);
-    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
-    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
     for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
       CollSeq *pColl = (CollSeq *)sqliteHashData(p);
       sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
@@ -575,11 +588,11 @@
       if( pFK ){
         int i = 0; 
         sqlite3VdbeSetNumCols(v, 5);
-        sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
-        sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
-        sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
-        sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
-        sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC);
+        sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC);
+        sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC);
+        sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC);
+        sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC);
         while(pFK){
           int j;
           for(j=0; j<pFK->nCol; j++){
@@ -641,12 +654,13 @@
     /* Initialize the VDBE program */
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC);
     sqlite3VdbeAddOp(v, OP_MemInt, 0, 0);  /* Initialize error count to 0 */
 
     /* Do an integrity check on each database file */
     for(i=0; i<db->nDb; i++){
       HashElem *x;
+      Hash *pTbls;
       int cnt = 0;
 
       if( OMIT_TEMPDB && i==1 ) continue;
@@ -655,13 +669,13 @@
 
       /* Do an integrity check of the B-Tree
       */
-      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
+      pTbls = &db->aDb[i].pSchema->tblHash;
+      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
         Table *pTab = sqliteHashData(x);
         Index *pIdx;
         sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
         cnt++;
         for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-          if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
           sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
           cnt++;
         }
@@ -670,18 +684,19 @@
       sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
       sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
       addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
-      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
+      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+7);
       sqlite3VdbeOp3(v, OP_String8, 0, 0,
          sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
          P3_DYNAMIC);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
       sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
       sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+      sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
 
       /* Make sure all the indices are constructed correctly.
       */
       sqlite3CodeVerifySchema(pParse, i);
-      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
+      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
         Table *pTab = sqliteHashData(x);
         Index *pIdx;
         int loopTop;
@@ -690,11 +705,11 @@
         sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
         sqlite3VdbeAddOp(v, OP_MemInt, 0, 1);
         loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
-        sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
+        sqlite3VdbeAddOp(v, OP_MemIncr, 1, 1);
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
           int jmp2;
           static const VdbeOpList idxErr[] = {
-            { OP_MemIncr,     0,  0,  0},
+            { OP_MemIncr,     1,  0,  0},
             { OP_String8,     0,  0,  "rowid "},
             { OP_Rowid,       1,  0,  0},
             { OP_String8,     0,  0,  " missing from index "},
@@ -714,12 +729,12 @@
           static const VdbeOpList cntIdx[] = {
              { OP_MemInt,       0,  2,  0},
              { OP_Rewind,       0,  0,  0},  /* 1 */
-             { OP_MemIncr,      2,  0,  0},
+             { OP_MemIncr,      1,  2,  0},
              { OP_Next,         0,  0,  0},  /* 3 */
              { OP_MemLoad,      1,  0,  0},
              { OP_MemLoad,      2,  0,  0},
              { OP_Eq,           0,  0,  0},  /* 6 */
-             { OP_MemIncr,      0,  0,  0},
+             { OP_MemIncr,      1,  0,  0},
              { OP_String8,      0,  0,  "wrong # of entries in index "},
              { OP_String8,      0,  0,  0},  /* 9 */
              { OP_Concat,       0,  0,  0},
@@ -784,10 +799,10 @@
     if( !zRight ){    /* "PRAGMA encoding" */
       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
       sqlite3VdbeSetNumCols(v, 1);
-      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC);
       sqlite3VdbeAddOp(v, OP_String8, 0, 0);
       for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
-        if( pEnc->enc==pParse->db->enc ){
+        if( pEnc->enc==ENC(pParse->db) ){
           sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
           break;
         }
@@ -799,10 +814,13 @@
       ** will be overwritten when the schema is next loaded. If it does not
       ** already exists, it will be created to use the new encoding value.
       */
-      if( !(pParse->db->flags&SQLITE_Initialized) ){
+      if( 
+        !(DbHasProperty(db, 0, DB_SchemaLoaded)) || 
+        DbHasProperty(db, 0, DB_Empty) 
+      ){
         for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
           if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
-            pParse->db->enc = pEnc->enc;
+            ENC(pParse->db) = pEnc->enc;
             break;
           }
         }
@@ -887,8 +905,8 @@
     int i;
     Vdbe *v = sqlite3GetVdbe(pParse);
     sqlite3VdbeSetNumCols(v, 2);
-    sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
-    sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC);
+    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC);
     for(i=0; i<db->nDb; i++){
       Btree *pBt;
       Pager *pPager;
@@ -918,6 +936,12 @@
   }else
 #endif
 
+#if SQLITE_HAS_CODEC
+  if( sqlite3StrICmp(zLeft, "key")==0 ){
+    sqlite3_key(db, zRight, strlen(zRight));
+  }else
+#endif
+
   {}
 
   if( v ){
@@ -926,6 +950,17 @@
     ** are only valid for a single execution.
     */
     sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
+
+    /*
+    ** Reset the safety level, in case the fullfsync flag or synchronous
+    ** setting changed.
+    */
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+    if( db->autoCommit ){
+      sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
+                 (db->flags&SQLITE_FullFSync)!=0);
+    }
+#endif
   }
 pragma_out:
   sqliteFree(zLeft);

Modified: packages/libdbd-sqlite3-perl/trunk/prepare.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/prepare.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/prepare.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.4 2005/09/10 16:46:13 drh Exp $
+** $Id: prepare.c,v 1.33 2006/03/13 15:06:07 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -24,7 +24,7 @@
 ** that the database is corrupt.
 */
 static void corruptSchema(InitData *pData, const char *zExtra){
-  if( !sqlite3_malloc_failed ){
+  if( !sqlite3MallocFailed() ){
     sqlite3SetString(pData->pzErrMsg, "malformed database schema",
        zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
   }
@@ -49,6 +49,10 @@
   sqlite3 *db = pData->db;
   int iDb;
 
+  if( sqlite3MallocFailed() ){
+    return SQLITE_NOMEM;
+  }
+
   assert( argc==4 );
   if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
   if( argv[1]==0 || argv[3]==0 ){
@@ -70,8 +74,13 @@
     db->init.newTnum = atoi(argv[1]);
     rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
     db->init.iDb = 0;
+    assert( rc!=SQLITE_OK || zErr==0 );
     if( SQLITE_OK!=rc ){
-      corruptSchema(pData, zErr);
+      if( rc==SQLITE_NOMEM ){
+        sqlite3FailedMalloc();
+      }else{
+        corruptSchema(pData, zErr);
+      }
       sqlite3_free(zErr);
       return rc;
     }
@@ -111,6 +120,7 @@
   BtCursor *curMain;
   int size;
   Table *pTab;
+  Db *pDb;
   char const *azArg[5];
   char zDbNum[30];
   int meta[10];
@@ -145,6 +155,7 @@
 #endif
 
   assert( iDb>=0 && iDb<db->nDb );
+  assert( db->aDb[iDb].pSchema );
 
   /* zMasterSchema and zInitScript are set to point at the master schema
   ** and initialisation script appropriate for the database being
@@ -180,11 +191,14 @@
 
   /* Create a cursor to hold the database open
   */
-  if( db->aDb[iDb].pBt==0 ){
-    if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
+  pDb = &db->aDb[iDb];
+  if( pDb->pBt==0 ){
+    if( !OMIT_TEMPDB && iDb==1 ){
+      DbSetProperty(db, 1, DB_SchemaLoaded);
+    }
     return SQLITE_OK;
   }
-  rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
+  rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain);
   if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
     sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
     return rc;
@@ -204,13 +218,13 @@
   **    meta[8]
   **    meta[9]
   **
-  ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
+  ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
   ** the possible values of meta[4].
   */
   if( rc==SQLITE_OK ){
     int i;
     for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
-      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, (u32 *)&meta[i]);
+      rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
     }
     if( rc ){
       sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
@@ -220,7 +234,7 @@
   }else{
     memset(meta, 0, sizeof(meta));
   }
-  db->aDb[iDb].schema_cookie = meta[0];
+  pDb->pSchema->schema_cookie = meta[0];
 
   /* If opening a non-empty database, check the text encoding. For the
   ** main database, set sqlite3.enc to the encoding of the main database.
@@ -229,55 +243,44 @@
   */
   if( meta[4] ){  /* text encoding */
     if( iDb==0 ){
-      /* If opening the main database, set db->enc. */
-      db->enc = (u8)meta[4];
-      db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0);
+      /* If opening the main database, set ENC(db). */
+      ENC(db) = (u8)meta[4];
+      db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
     }else{
-      /* If opening an attached database, the encoding much match db->enc */
-      if( meta[4]!=db->enc ){
+      /* If opening an attached database, the encoding much match ENC(db) */
+      if( meta[4]!=ENC(db) ){
         sqlite3BtreeCloseCursor(curMain);
         sqlite3SetString(pzErrMsg, "attached databases must use the same"
             " text encoding as main database", (char*)0);
         return SQLITE_ERROR;
       }
     }
+  }else{
+    DbSetProperty(db, iDb, DB_Empty);
   }
+  pDb->pSchema->enc = ENC(db);
 
   size = meta[2];
   if( size==0 ){ size = MAX_PAGES; }
-  db->aDb[iDb].cache_size = size;
+  pDb->pSchema->cache_size = size;
+  sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
 
-  if( iDb==0 ){
-    db->file_format = meta[1];
-    if( db->file_format==0 ){
-      /* This happens if the database was initially empty */
-      db->file_format = 1;
-    }
-
-    if( db->file_format==2 || db->file_format==3 ){
-      /* File format 2 is treated exactly as file format 1. New 
-      ** databases are created with file format 1.
-      */ 
-      db->file_format = 1;
-    }
-  }
-
   /*
   ** file_format==1    Version 3.0.0.
-  ** file_format==2    Version 3.1.3.
-  ** file_format==3    Version 3.1.4.
-  **
-  ** Version 3.0 can only use files with file_format==1. Version 3.1.3
-  ** can read and write files with file_format==1 or file_format==2.
-  ** Version 3.1.4 can read and write file formats 1, 2 and 3.
+  ** file_format==2    Version 3.1.3.  // ALTER TABLE ADD COLUMN
+  ** file_format==3    Version 3.1.4.  // ditto but with non-NULL defaults
+  ** file_format==4    Version 3.3.0.  // DESC indices.  Boolean constants
   */
-  if( meta[1]>3 ){
+  pDb->pSchema->file_format = meta[1];
+  if( pDb->pSchema->file_format==0 ){
+    pDb->pSchema->file_format = 1;
+  }
+  if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
     sqlite3BtreeCloseCursor(curMain);
     sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
     return SQLITE_ERROR;
   }
 
-  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
 
   /* Read the schema information out of the schema tables
   */
@@ -301,8 +304,8 @@
 #endif
     sqlite3BtreeCloseCursor(curMain);
   }
-  if( sqlite3_malloc_failed ){
-    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
+  if( sqlite3MallocFailed() ){
+    /* sqlite3SetString(pzErrMsg, "out of memory", (char*)0); */
     rc = SQLITE_NOMEM;
     sqlite3ResetInternalSchema(db, 0);
   }
@@ -320,14 +323,15 @@
 ** created using ATTACH statements.  Return a success code.  If an
 ** error occurs, write an error message into *pzErrMsg.
 **
-** After the database is initialized, the SQLITE_Initialized
-** bit is set in the flags field of the sqlite structure. 
+** After a database is initialized, the DB_SchemaLoaded bit is set
+** bit is set in the flags field of the Db structure. If the database
+** file was of zero-length, then the DB_Empty flag is also set.
 */
 int sqlite3Init(sqlite3 *db, char **pzErrMsg){
   int i, rc;
+  int called_initone = 0;
   
   if( db->init.busy ) return SQLITE_OK;
-  assert( (db->flags & SQLITE_Initialized)==0 );
   rc = SQLITE_OK;
   db->init.busy = 1;
   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
@@ -336,6 +340,7 @@
     if( rc ){
       sqlite3ResetInternalSchema(db, i);
     }
+    called_initone = 1;
   }
 
   /* Once all the other databases have been initialised, load the schema
@@ -348,19 +353,16 @@
     if( rc ){
       sqlite3ResetInternalSchema(db, 1);
     }
+    called_initone = 1;
   }
 #endif
 
   db->init.busy = 0;
-  if( rc==SQLITE_OK ){
-    db->flags |= SQLITE_Initialized;
+  if( rc==SQLITE_OK && called_initone ){
     sqlite3CommitInternalChanges(db);
   }
 
-  if( rc!=SQLITE_OK ){
-    db->flags &= ~SQLITE_Initialized;
-  }
-  return rc;
+  return rc; 
 }
 
 /*
@@ -371,11 +373,8 @@
   int rc = SQLITE_OK;
   sqlite3 *db = pParse->db;
   if( !db->init.busy ){
-    if( (db->flags & SQLITE_Initialized)==0 ){
-      rc = sqlite3Init(db, &pParse->zErrMsg);
-    }
+    rc = sqlite3Init(db, &pParse->zErrMsg);
   }
-  assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized) || db->init.busy );
   if( rc!=SQLITE_OK ){
     pParse->rc = rc;
     pParse->nErr++;
@@ -402,7 +401,7 @@
     rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp);
     if( rc==SQLITE_OK ){
       rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
-      if( rc==SQLITE_OK && cookie!=db->aDb[iDb].schema_cookie ){
+      if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){
         allOk = 0;
       }
       sqlite3BtreeCloseCursor(curTemp);
@@ -412,6 +411,37 @@
 }
 
 /*
+** Convert a schema pointer into the iDb index that indicates
+** which database file in db->aDb[] the schema refers to.
+**
+** If the same database is attached more than once, the first
+** attached database is returned.
+*/
+int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
+  int i = -1000000;
+
+  /* If pSchema is NULL, then return -1000000. This happens when code in 
+  ** expr.c is trying to resolve a reference to a transient table (i.e. one
+  ** created by a sub-select). In this case the return value of this 
+  ** function should never be used.
+  **
+  ** We return -1000000 instead of the more usual -1 simply because using
+  ** -1000000 as incorrectly using -1000000 index into db->aDb[] is much 
+  ** more likely to cause a segfault than -1 (of course there are assert()
+  ** statements too, but it never hurts to play the odds).
+  */
+  if( pSchema ){
+    for(i=0; i<db->nDb; i++){
+      if( db->aDb[i].pSchema==pSchema ){
+        break;
+      }
+    }
+    assert( i>=0 &&i>=0 &&  i<db->nDb );
+  }
+  return i;
+}
+
+/*
 ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
 */
 int sqlite3_prepare(
@@ -424,10 +454,10 @@
   Parse sParse;
   char *zErrMsg = 0;
   int rc = SQLITE_OK;
+  int i;
 
-  if( sqlite3_malloc_failed ){
-    return SQLITE_NOMEM;
-  }
+  /* Assert that malloc() has not failed */
+  assert( !sqlite3MallocFailed() );
 
   assert( ppStmt );
   *ppStmt = 0;
@@ -435,19 +465,35 @@
     return SQLITE_MISUSE;
   }
 
+  /* If any attached database schemas are locked, do not proceed with
+  ** compilation. Instead return SQLITE_LOCKED immediately.
+  */
+  for(i=0; i<db->nDb; i++) {
+    Btree *pBt = db->aDb[i].pBt;
+    if( pBt && sqlite3BtreeSchemaLocked(pBt) ){
+      const char *zDb = db->aDb[i].zName;
+      sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb);
+      sqlite3SafetyOff(db);
+      return SQLITE_LOCKED;
+    }
+  }
+  
   memset(&sParse, 0, sizeof(sParse));
   sParse.db = db;
-  sqlite3RunParser(&sParse, zSql, &zErrMsg);
+  if( nBytes>=0 && zSql[nBytes]!=0 ){
+    char *zSqlCopy = sqlite3StrNDup(zSql, nBytes);
+    sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
+    sParse.zTail += zSql - zSqlCopy;
+    sqliteFree(zSqlCopy);
+  }else{
+    sqlite3RunParser(&sParse, zSql, &zErrMsg);
+  }
 
-  if( sqlite3_malloc_failed ){
-    rc = SQLITE_NOMEM;
-    sqlite3RollbackAll(db);
-    sqlite3ResetInternalSchema(db, 0);
-    db->flags &= ~SQLITE_InTrans;
-    goto prepare_out;
+  if( sqlite3MallocFailed() ){
+    sParse.rc = SQLITE_NOMEM;
   }
   if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
-  if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
+  if( sParse.checkSchema && !schemaIsValid(db) ){
     sParse.rc = SQLITE_SCHEMA;
   }
   if( sParse.rc==SQLITE_SCHEMA ){
@@ -460,21 +506,20 @@
   if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
     if( sParse.explain==2 ){
       sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
-      sqlite3VdbeSetColName(sParse.pVdbe, 0, "order", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 1, "from", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 2, "detail", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P3_STATIC);
     }else{
       sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
-      sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC);
     }
   } 
 #endif
 
-prepare_out:
   if( sqlite3SafetyOff(db) ){
     rc = SQLITE_MISUSE;
   }
@@ -490,6 +535,9 @@
   }else{
     sqlite3Error(db, rc, 0);
   }
+
+  rc = sqlite3ApiExit(db, rc);
+  sqlite3ReleaseThreadData();
   return rc;
 }
 
@@ -508,22 +556,17 @@
   ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
   ** tricky bit is figuring out the pointer to return in *pzTail.
   */
-  char const *zSql8 = 0;
-  char const *zTail8 = 0;
-  int rc;
-  sqlite3_value *pTmp;
+  char *zSql8;
+  const char *zTail8 = 0;
+  int rc = SQLITE_OK;
 
   if( sqlite3SafetyCheck(db) ){
     return SQLITE_MISUSE;
   }
-  pTmp = sqlite3GetTransientValue(db);
-  sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
-  zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
-  if( !zSql8 ){
-    sqlite3Error(db, SQLITE_NOMEM, 0);
-    return SQLITE_NOMEM;
+  zSql8 = sqlite3utf16to8(zSql, nBytes);
+  if( zSql8 ){
+    rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);
   }
-  rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);
 
   if( zTail8 && pzTail ){
     /* If sqlite3_prepare returns a tail pointer, we calculate the
@@ -534,7 +577,7 @@
     int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
     *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
   }
- 
-  return rc;
+  sqliteFree(zSql8); 
+  return sqlite3ApiExit(db, rc);
 }
 #endif /* SQLITE_OMIT_UTF16 */

Modified: packages/libdbd-sqlite3-perl/trunk/printf.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/printf.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/printf.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -65,15 +65,14 @@
 #define etDYNSTRING   7 /* Dynamically allocated strings. %z */
 #define etPERCENT     8 /* Percent symbol. %% */
 #define etCHARX       9 /* Characters. %c */
-#define etERROR      10 /* Used to indicate no such conversion type */
 /* The rest are extensions, not normally found in printf() */
-#define etCHARLIT    11 /* Literal characters.  %' */
-#define etSQLESCAPE  12 /* Strings with '\'' doubled.  %q */
-#define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
+#define etCHARLIT    10 /* Literal characters.  %' */
+#define etSQLESCAPE  11 /* Strings with '\'' doubled.  %q */
+#define etSQLESCAPE2 12 /* Strings with '\'' doubled and enclosed in '',
                           NULL pointers replaced by SQL NULL.  %Q */
-#define etTOKEN      14 /* a pointer to a Token structure */
-#define etSRCLIST    15 /* a pointer to a SrcList */
-#define etPOINTER    16 /* The %p conversion */
+#define etTOKEN      13 /* a pointer to a Token structure */
+#define etSRCLIST    14 /* a pointer to a SrcList */
+#define etPOINTER    15 /* The %p conversion */
 
 
 /*
@@ -120,10 +119,12 @@
   {  'u', 10, 0, etRADIX,      0,  0 },
   {  'x', 16, 0, etRADIX,      16, 1 },
   {  'X', 16, 0, etRADIX,      0,  4 },
+#ifndef SQLITE_OMIT_FLOATING_POINT
   {  'f',  0, 1, etFLOAT,      0,  0 },
   {  'e',  0, 1, etEXP,        30, 0 },
   {  'E',  0, 1, etEXP,        14, 0 },
   {  'G',  0, 1, etGENERIC,    14, 0 },
+#endif
   {  'i', 10, 1, etRADIX,      0,  0 },
   {  'n',  0, 0, etSIZE,       0,  0 },
   {  '%',  0, 0, etPERCENT,    0,  0 },
@@ -134,10 +135,10 @@
 #define etNINFO  (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
 
 /*
-** If NOFLOATINGPOINT is defined, then none of the floating point
+** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
 ** conversions will work.
 */
-#ifndef etNOFLOATINGPOINT
+#ifndef SQLITE_OMIT_FLOATING_POINT
 /*
 ** "*val" is a double such that 0.1 <= *val < 10.0
 ** Return the ascii code for the leading digit of *val, then
@@ -161,7 +162,7 @@
   *val = (*val - d)*10.0;
   return digit;
 }
-#endif
+#endif /* SQLITE_OMIT_FLOATING_POINT */
 
 /*
 ** On machines with a small stack size, you can redefine the
@@ -223,7 +224,7 @@
   etByte flag_long;          /* True if "l" flag is present */
   etByte flag_longlong;      /* True if the "ll" flag is present */
   etByte done;               /* Loop termination flag */
-  UINT64_TYPE longvalue;     /* Value for integer types */
+  sqlite_uint64 longvalue;   /* Value for integer types */
   LONGDOUBLE_TYPE realvalue; /* Value for real types */
   const et_info *infop;      /* Pointer to the appropriate info structure */
   char buf[etBUFSIZE];       /* Conversion buffer */
@@ -234,7 +235,7 @@
   static const char spaces[] =
    "                                                                         ";
 #define etSPACESIZE (sizeof(spaces)-1)
-#ifndef etNOFLOATINGPOINT
+#ifndef SQLITE_OMIT_FLOATING_POINT
   int  exp, e2;              /* exponent of real numbers */
   double rounder;            /* Used for rounding floating point values */
   etByte flag_dp;            /* True if decimal point should be shown */
@@ -327,7 +328,6 @@
     }
     /* Fetch the info entry for the field */
     infop = 0;
-    xtype = etERROR;
     for(idx=0; idx<etNINFO; idx++){
       if( c==fmtinfo[idx].fmttype ){
         infop = &fmtinfo[idx];
@@ -338,7 +338,11 @@
       }
     }
     zExtra = 0;
+    if( infop==0 ){
+      return -1;
+    }
 
+
     /* Limit the precision to prevent overflowing buf[] during conversion */
     if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
       precision = etBUFSIZE-40;
@@ -425,7 +429,7 @@
       case etEXP:
       case etGENERIC:
         realvalue = va_arg(ap,double);
-#ifndef etNOFLOATINGPOINT
+#ifndef SQLITE_OMIT_FLOATING_POINT
         if( precision<0 ) precision = 6;         /* Set default precision */
         if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
         if( realvalue<0.0 ){
@@ -442,7 +446,7 @@
         for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
 #else
         /* It makes more sense to use 0.5 */
-        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
+        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
 #endif
         if( xtype==etFLOAT ) realvalue += rounder;
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
@@ -594,13 +598,13 @@
         break;
       case etSQLESCAPE:
       case etSQLESCAPE2: {
-        int i, j, n, c, isnull;
+        int i, j, n, ch, isnull;
         int needQuote;
-        char *arg = va_arg(ap,char*);
-        isnull = arg==0;
-        if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
-        for(i=n=0; (c=arg[i])!=0; i++){
-          if( c=='\'' )  n++;
+        char *escarg = va_arg(ap,char*);
+        isnull = escarg==0;
+        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
+        for(i=n=0; (ch=escarg[i])!=0; i++){
+          if( ch=='\'' )  n++;
         }
         needQuote = !isnull && xtype==etSQLESCAPE2;
         n += i + 1 + needQuote*2;
@@ -612,20 +616,21 @@
         }
         j = 0;
         if( needQuote ) bufpt[j++] = '\'';
-        for(i=0; (c=arg[i])!=0; i++){
-          bufpt[j++] = c;
-          if( c=='\'' ) bufpt[j++] = c;
+        for(i=0; (ch=escarg[i])!=0; i++){
+          bufpt[j++] = ch;
+          if( ch=='\'' ) bufpt[j++] = ch;
         }
         if( needQuote ) bufpt[j++] = '\'';
         bufpt[j] = 0;
         length = j;
-        if( precision>=0 && precision<length ) length = precision;
+        /* The precision is ignored on %q and %Q */
+        /* if( precision>=0 && precision<length ) length = precision; */
         break;
       }
       case etTOKEN: {
         Token *pToken = va_arg(ap, Token*);
         if( pToken && pToken->z ){
-          (*func)(arg, pToken->z, pToken->n);
+          (*func)(arg, (char*)pToken->z, pToken->n);
         }
         length = width = 0;
         break;
@@ -643,15 +648,6 @@
         length = width = 0;
         break;
       }
-      case etERROR:
-        buf[0] = '%';
-        buf[1] = c;
-        errorflag = 0;
-        idx = 1+(c!=0);
-        (*func)(arg,"%",idx);
-        count += idx;
-        if( c==0 ) fmt--;
-        break;
     }/* End switch over the format type */
     /*
     ** The text of the conversion is pointed to by "bufpt" and is

Modified: packages/libdbd-sqlite3-perl/trunk/random.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/random.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/random.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -15,7 +15,7 @@
 ** Random numbers are used by some of the database backends in order
 ** to generate random integer keys for tables or random filenames.
 **
-** $Id: random.c,v 1.13 2005/06/12 21:35:52 drh Exp $
+** $Id: random.c,v 1.15 2006/01/06 14:32:20 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"

Modified: packages/libdbd-sqlite3-perl/trunk/select.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/select.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/select.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,12 +12,29 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.276 2005/09/20 18:13:24 drh Exp $
+** $Id: select.c,v 1.310 2006/03/26 01:21:23 drh Exp $
 */
 #include "sqliteInt.h"
 
 
 /*
+** Delete all the content of a Select structure but do not deallocate
+** the select structure itself.
+*/
+static void clearSelect(Select *p){
+  sqlite3ExprListDelete(p->pEList);
+  sqlite3SrcListDelete(p->pSrc);
+  sqlite3ExprDelete(p->pWhere);
+  sqlite3ExprListDelete(p->pGroupBy);
+  sqlite3ExprDelete(p->pHaving);
+  sqlite3ExprListDelete(p->pOrderBy);
+  sqlite3SelectDelete(p->pPrior);
+  sqlite3ExprDelete(p->pLimit);
+  sqlite3ExprDelete(p->pOffset);
+}
+
+
+/*
 ** Allocate a new Select structure and return a pointer to that
 ** structure.
 */
@@ -33,41 +50,49 @@
   Expr *pOffset         /* OFFSET value.  NULL means no offset */
 ){
   Select *pNew;
+  Select standin;
   pNew = sqliteMalloc( sizeof(*pNew) );
   assert( !pOffset || pLimit );   /* Can't have OFFSET without LIMIT. */
   if( pNew==0 ){
-    sqlite3ExprListDelete(pEList);
-    sqlite3SrcListDelete(pSrc);
-    sqlite3ExprDelete(pWhere);
-    sqlite3ExprListDelete(pGroupBy);
-    sqlite3ExprDelete(pHaving);
-    sqlite3ExprListDelete(pOrderBy);
-    sqlite3ExprDelete(pLimit);
-    sqlite3ExprDelete(pOffset);
-  }else{
-    if( pEList==0 ){
-      pEList = sqlite3ExprListAppend(0, sqlite3Expr(TK_ALL,0,0,0), 0);
-    }
-    pNew->pEList = pEList;
-    pNew->pSrc = pSrc;
-    pNew->pWhere = pWhere;
-    pNew->pGroupBy = pGroupBy;
-    pNew->pHaving = pHaving;
-    pNew->pOrderBy = pOrderBy;
-    pNew->isDistinct = isDistinct;
-    pNew->op = TK_SELECT;
-    pNew->pLimit = pLimit;
-    pNew->pOffset = pOffset;
-    pNew->iLimit = -1;
-    pNew->iOffset = -1;
-    pNew->addrOpenVirt[0] = -1;
-    pNew->addrOpenVirt[1] = -1;
-    pNew->addrOpenVirt[2] = -1;
+    pNew = &standin;
+    memset(pNew, 0, sizeof(*pNew));
   }
+  if( pEList==0 ){
+    pEList = sqlite3ExprListAppend(0, sqlite3Expr(TK_ALL,0,0,0), 0);
+  }
+  pNew->pEList = pEList;
+  pNew->pSrc = pSrc;
+  pNew->pWhere = pWhere;
+  pNew->pGroupBy = pGroupBy;
+  pNew->pHaving = pHaving;
+  pNew->pOrderBy = pOrderBy;
+  pNew->isDistinct = isDistinct;
+  pNew->op = TK_SELECT;
+  pNew->pLimit = pLimit;
+  pNew->pOffset = pOffset;
+  pNew->iLimit = -1;
+  pNew->iOffset = -1;
+  pNew->addrOpenVirt[0] = -1;
+  pNew->addrOpenVirt[1] = -1;
+  pNew->addrOpenVirt[2] = -1;
+  if( pNew==&standin) {
+    clearSelect(pNew);
+    pNew = 0;
+  }
   return pNew;
 }
 
 /*
+** Delete the given Select structure and all of its substructures.
+*/
+void sqlite3SelectDelete(Select *p){
+  if( p ){
+    clearSelect(p);
+    sqliteFree(p);
+  }
+}
+
+/*
 ** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
 ** type of join.  Return an integer constant that expresses that type
 ** in terms of the following bit values:
@@ -109,7 +134,7 @@
     p = apAll[i];
     for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
       if( p->n==keywords[j].nChar 
-          && sqlite3StrNICmp(p->z, keywords[j].zKeyword, p->n)==0 ){
+          && sqlite3StrNICmp((char*)p->z, keywords[j].zKeyword, p->n)==0 ){
         jointype |= keywords[j].code;
         break;
       }
@@ -154,8 +179,8 @@
 ** Set the value of a token to a '\000'-terminated string.
 */
 static void setToken(Token *p, const char *z){
-  p->z = z;
-  p->n = strlen(z);
+  p->z = (u8*)z;
+  p->n = z ? strlen(z) : 0;
   p->dyn = 0;
 }
 
@@ -331,59 +356,53 @@
 }
 
 /*
-** Delete the given Select structure and all of its substructures.
-*/
-void sqlite3SelectDelete(Select *p){
-  if( p==0 ) return;
-  sqlite3ExprListDelete(p->pEList);
-  sqlite3SrcListDelete(p->pSrc);
-  sqlite3ExprDelete(p->pWhere);
-  sqlite3ExprListDelete(p->pGroupBy);
-  sqlite3ExprDelete(p->pHaving);
-  sqlite3ExprListDelete(p->pOrderBy);
-  sqlite3SelectDelete(p->pPrior);
-  sqlite3ExprDelete(p->pLimit);
-  sqlite3ExprDelete(p->pOffset);
-  sqliteFree(p);
-}
-
-/*
 ** Insert code into "v" that will push the record on the top of the
 ** stack into the sorter.
 */
-static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
+static void pushOntoSorter(
+  Parse *pParse,         /* Parser context */
+  ExprList *pOrderBy,    /* The ORDER BY clause */
+  Select *pSelect        /* The whole SELECT statement */
+){
+  Vdbe *v = pParse->pVdbe;
   sqlite3ExprCodeExprList(pParse, pOrderBy);
   sqlite3VdbeAddOp(v, OP_Sequence, pOrderBy->iECursor, 0);
   sqlite3VdbeAddOp(v, OP_Pull, pOrderBy->nExpr + 1, 0);
   sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0);
   sqlite3VdbeAddOp(v, OP_IdxInsert, pOrderBy->iECursor, 0);
+  if( pSelect->iLimit>=0 ){
+    int addr1, addr2;
+    addr1 = sqlite3VdbeAddOp(v, OP_IfMemZero, pSelect->iLimit+1, 0);
+    sqlite3VdbeAddOp(v, OP_MemIncr, -1, pSelect->iLimit+1);
+    addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
+    sqlite3VdbeJumpHere(v, addr1);
+    sqlite3VdbeAddOp(v, OP_Last, pOrderBy->iECursor, 0);
+    sqlite3VdbeAddOp(v, OP_Delete, pOrderBy->iECursor, 0);
+    sqlite3VdbeJumpHere(v, addr2);
+    pSelect->iLimit = -1;
+  }
 }
 
 /*
-** Add code to implement the OFFSET and LIMIT
+** Add code to implement the OFFSET
 */
-static void codeLimiter(
+static void codeOffset(
   Vdbe *v,          /* Generate code into this VM */
   Select *p,        /* The SELECT statement being coded */
   int iContinue,    /* Jump here to skip the current record */
-  int iBreak,       /* Jump here to end the loop */
   int nPop          /* Number of times to pop stack when jumping */
 ){
   if( p->iOffset>=0 && iContinue!=0 ){
-    int addr = sqlite3VdbeCurrentAddr(v) + 3;
-    if( nPop>0 ) addr++;
-    sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, 0);
-    sqlite3VdbeAddOp(v, OP_IfMemPos, p->iOffset, addr);
+    int addr;
+    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iOffset);
+    addr = sqlite3VdbeAddOp(v, OP_IfMemNeg, p->iOffset, 0);
     if( nPop>0 ){
       sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
     }
     sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
     VdbeComment((v, "# skip OFFSET records"));
+    sqlite3VdbeJumpHere(v, addr);
   }
-  if( p->iLimit>=0 && iBreak!=0 ){
-    sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
-    VdbeComment((v, "# exit when LIMIT reached"));
-  }
 }
 
 /*
@@ -392,22 +411,18 @@
 ** seen combinations of the N values.  A new entry is made in iTab
 ** if the current N values are new.
 **
-** A jump to addrRepeat is made and the K values are popped from the
+** A jump to addrRepeat is made and the N+1 values are popped from the
 ** stack if the top N elements are not distinct.
 */
 static void codeDistinct(
   Vdbe *v,           /* Generate code into this VM */
   int iTab,          /* A sorting index used to test for distinctness */
   int addrRepeat,    /* Jump to here if not distinct */
-  int N,             /* The top N elements of the stack must be distinct */
-  int K              /* Pop K elements from the stack if indistinct */
+  int N              /* The top N elements of the stack must be distinct */
 ){
-#if NULL_ALWAYS_DISTINCT
-  sqlite3VdbeAddOp(v, OP_IsNull, -N, sqlite3VdbeCurrentAddr(v)+6);
-#endif
   sqlite3VdbeAddOp(v, OP_MakeRecord, -N, 0);
   sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
-  sqlite3VdbeAddOp(v, OP_Pop, K, 0);
+  sqlite3VdbeAddOp(v, OP_Pop, N+1, 0);
   sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat);
   VdbeComment((v, "# skip indistinct records"));
   sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
@@ -447,9 +462,9 @@
   /* If there was a LIMIT clause on the SELECT statement, then do the check
   ** to see if this row should be output.
   */
-  hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
+  hasDistinct = distinct>=0 && pEList->nExpr>0;
   if( pOrderBy==0 && !hasDistinct ){
-    codeLimiter(v, p, iContinue, iBreak, 0);
+    codeOffset(v, p, iContinue, 0);
   }
 
   /* Pull the requested columns.
@@ -468,10 +483,11 @@
   ** part of the result.
   */
   if( hasDistinct ){
-    int n = pEList->nExpr;
-    codeDistinct(v, distinct, iContinue, n, n+1);
+    assert( pEList!=0 );
+    assert( pEList->nExpr==nColumn );
+    codeDistinct(v, distinct, iContinue, nColumn);
     if( pOrderBy==0 ){
-      codeLimiter(v, p, iContinue, iBreak, nColumn);
+      codeOffset(v, p, iContinue, nColumn);
     }
   }
 
@@ -481,7 +497,7 @@
     */
 #ifndef SQLITE_OMIT_COMPOUND_SELECT
     case SRT_Union: {
-      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
+      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
       if( aff ){
         sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
       }
@@ -495,7 +511,7 @@
     */
     case SRT_Except: {
       int addr;
-      addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
+      addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
       sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
       sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
       sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
@@ -509,7 +525,7 @@
     case SRT_VirtualTab: {
       sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
       if( pOrderBy ){
-        pushOntoSorter(pParse, v, pOrderBy);
+        pushOntoSorter(pParse, pOrderBy, p);
       }else{
         sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
         sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
@@ -536,29 +552,37 @@
         ** ORDER BY in this case since the order of entries in the set
         ** does not matter.  But there might be a LIMIT clause, in which
         ** case the order does matter */
-        pushOntoSorter(pParse, v, pOrderBy);
+        pushOntoSorter(pParse, pOrderBy, p);
       }else{
-        char aff = (iParm>>16)&0xFF;
-        aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
-        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
+        char affinity = (iParm>>16)&0xFF;
+        affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, affinity);
+        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
         sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
       }
       sqlite3VdbeJumpHere(v, addr2);
       break;
     }
 
+    /* If any row exist in the result set, record that fact and abort.
+    */
+    case SRT_Exists: {
+      sqlite3VdbeAddOp(v, OP_MemInt, 1, iParm);
+      sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
+      /* The LIMIT clause will terminate the loop for us */
+      break;
+    }
+
     /* If this is a scalar select that is part of an expression, then
     ** store the results in the appropriate memory cell and break out
     ** of the scan loop.
     */
-    case SRT_Exists:
     case SRT_Mem: {
       assert( nColumn==1 );
       if( pOrderBy ){
-        pushOntoSorter(pParse, v, pOrderBy);
+        pushOntoSorter(pParse, pOrderBy, p);
       }else{
         sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
-        sqlite3VdbeAddOp(v, OP_Goto, 0, iBreak);
+        /* The LIMIT clause will jump out of the loop for us */
       }
       break;
     }
@@ -572,7 +596,7 @@
     case SRT_Callback: {
       if( pOrderBy ){
         sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
-        pushOntoSorter(pParse, v, pOrderBy);
+        pushOntoSorter(pParse, pOrderBy, p);
       }else if( eDest==SRT_Subroutine ){
         sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
       }else{
@@ -594,6 +618,13 @@
     }
 #endif
   }
+
+  /* Jump to the end of the loop if the LIMIT is reached.
+  */
+  if( p->iLimit>=0 && pOrderBy==0 ){
+    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
+    sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, iBreak);
+  }
   return 0;
 }
 
@@ -622,9 +653,9 @@
   nExpr = pList->nExpr;
   pInfo = sqliteMalloc( sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
   if( pInfo ){
-    pInfo->aSortOrder = (char*)&pInfo->aColl[nExpr];
+    pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
     pInfo->nField = nExpr;
-    pInfo->enc = db->enc;
+    pInfo->enc = ENC(db);
     for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
       CollSeq *pColl;
       pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
@@ -646,7 +677,7 @@
 ** routine generates the code needed to do that.
 */
 static void generateSortTail(
-  Parse *pParse,   /* The parsing context */
+  Parse *pParse,   /* Parsing context */
   Select *p,       /* The SELECT statement */
   Vdbe *v,         /* Generate code into this VDBE */
   int nColumn,     /* Number of columns of data */
@@ -657,11 +688,20 @@
   int cont = sqlite3VdbeMakeLabel(v);
   int addr;
   int iTab;
+  int pseudoTab;
   ExprList *pOrderBy = p->pOrderBy;
 
   iTab = pOrderBy->iECursor;
+  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
+    pseudoTab = pParse->nTab++;
+    sqlite3VdbeAddOp(v, OP_OpenPseudo, pseudoTab, 0);
+    sqlite3VdbeAddOp(v, OP_SetNumColumns, pseudoTab, nColumn);
+  }
   addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk);
-  codeLimiter(v, p, cont, brk, 0);
+  codeOffset(v, p, cont, 0);
+  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
+    sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
+  }
   sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1);
   switch( eDest ){
     case SRT_Table:
@@ -677,32 +717,29 @@
       sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
       sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
       sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
-      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
+      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "c", P3_STATIC);
       sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
       break;
     }
-    case SRT_Exists:
     case SRT_Mem: {
       assert( nColumn==1 );
       sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
-      sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
+      /* The LIMIT clause will terminate the loop for us */
       break;
     }
 #endif
     case SRT_Callback:
     case SRT_Subroutine: {
       int i;
-      sqlite3VdbeAddOp(v, OP_Integer, p->pEList->nExpr, 0);
-      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, pseudoTab, 0);
       for(i=0; i<nColumn; i++){
-        sqlite3VdbeAddOp(v, OP_Column, -1-i, i);
+        sqlite3VdbeAddOp(v, OP_Column, pseudoTab, i);
       }
       if( eDest==SRT_Callback ){
         sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
       }else{
         sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
       }
-      sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
       break;
     }
     default: {
@@ -710,23 +747,54 @@
       break;
     }
   }
+
+  /* Jump to the end of the loop when the LIMIT is reached
+  */
+  if( p->iLimit>=0 ){
+    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
+    sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, brk);
+  }
+
+  /* The bottom of the loop
+  */
   sqlite3VdbeResolveLabel(v, cont);
   sqlite3VdbeAddOp(v, OP_Next, iTab, addr);
   sqlite3VdbeResolveLabel(v, brk);
+  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
+    sqlite3VdbeAddOp(v, OP_Close, pseudoTab, 0);
+  }
+
 }
 
 /*
 ** Return a pointer to a string containing the 'declaration type' of the
 ** expression pExpr. The string may be treated as static by the caller.
 **
-** If the declaration type is the exact datatype definition extracted from
-** the original CREATE TABLE statement if the expression is a column.
+** The declaration type is the exact datatype definition extracted from the
+** original CREATE TABLE statement if the expression is a column. The
+** declaration type for a ROWID field is INTEGER. Exactly when an expression
+** is considered a column can be complex in the presence of subqueries. The
+** result-set expression in all of the following SELECT statements is 
+** considered a column by this function.
+**
+**   SELECT col FROM tbl;
+**   SELECT (SELECT col FROM tbl;
+**   SELECT (SELECT col FROM tbl);
+**   SELECT abc FROM (SELECT col AS abc FROM tbl);
 ** 
-** The declaration type for an expression is either TEXT, NUMERIC or ANY.
-** The declaration type for a ROWID field is INTEGER.
+** The declaration type for any expression other than a column is NULL.
 */
-static const char *columnType(NameContext *pNC, Expr *pExpr){
-  char const *zType;
+static const char *columnType(
+  NameContext *pNC, 
+  Expr *pExpr,
+  const char **pzOriginDb,
+  const char **pzOriginTab,
+  const char **pzOriginCol
+){
+  char const *zType = 0;
+  char const *zOriginDb = 0;
+  char const *zOriginTab = 0;
+  char const *zOriginCol = 0;
   int j;
   if( pExpr==0 || pNC->pSrcList==0 ) return 0;
 
@@ -738,17 +806,24 @@
 
   switch( pExpr->op ){
     case TK_COLUMN: {
-      Table *pTab = 0;
-      int iCol = pExpr->iColumn;
+      /* The expression is a column. Locate the table the column is being
+      ** extracted from in NameContext.pSrcList. This table may be real
+      ** database table or a subquery.
+      */
+      Table *pTab = 0;            /* Table structure column is extracted from */
+      Select *pS = 0;             /* Select the column is extracted from */
+      int iCol = pExpr->iColumn;  /* Index of column in pTab */
       while( pNC && !pTab ){
         SrcList *pTabList = pNC->pSrcList;
         for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
         if( j<pTabList->nSrc ){
           pTab = pTabList->a[j].pTab;
+          pS = pTabList->a[j].pSelect;
         }else{
           pNC = pNC->pNext;
         }
       }
+
       if( pTab==0 ){
         /* FIX ME:
         ** This can occurs if you have something like "SELECT new.x;" inside
@@ -763,30 +838,72 @@
         zType = "TEXT";
         break;
       }
+
       assert( pTab );
-      if( iCol<0 ) iCol = pTab->iPKey;
-      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
-      if( iCol<0 ){
-        zType = "INTEGER";
-      }else{
-        zType = pTab->aCol[iCol].zType;
+#ifndef SQLITE_OMIT_SUBQUERY
+      if( pS ){
+        /* The "table" is actually a sub-select or a view in the FROM clause
+        ** of the SELECT statement. Return the declaration type and origin
+        ** data for the result-set column of the sub-select.
+        */
+        if( iCol>=0 && iCol<pS->pEList->nExpr ){
+          /* If iCol is less than zero, then the expression requests the
+          ** rowid of the sub-select or view. This expression is legal (see 
+          ** test case misc2.2.2) - it always evaluates to NULL.
+          */
+          NameContext sNC;
+          Expr *p = pS->pEList->a[iCol].pExpr;
+          sNC.pSrcList = pS->pSrc;
+          sNC.pNext = 0;
+          sNC.pParse = pNC->pParse;
+          zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
+        }
+      }else
+#endif
+      if( pTab->pSchema ){
+        /* A real table */
+        assert( !pS );
+        if( iCol<0 ) iCol = pTab->iPKey;
+        assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+        if( iCol<0 ){
+          zType = "INTEGER";
+          zOriginCol = "rowid";
+        }else{
+          zType = pTab->aCol[iCol].zType;
+          zOriginCol = pTab->aCol[iCol].zName;
+        }
+        zOriginTab = pTab->zName;
+        if( pNC->pParse ){
+          int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
+          zOriginDb = pNC->pParse->db->aDb[iDb].zName;
+        }
       }
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
     case TK_SELECT: {
+      /* The expression is a sub-select. Return the declaration type and
+      ** origin info for the single column in the result set of the SELECT
+      ** statement.
+      */
       NameContext sNC;
       Select *pS = pExpr->pSelect;
-      sNC.pSrcList = pExpr->pSelect->pSrc;
+      Expr *p = pS->pEList->a[0].pExpr;
+      sNC.pSrcList = pS->pSrc;
       sNC.pNext = pNC;
-      zType = columnType(&sNC, pS->pEList->a[0].pExpr); 
+      sNC.pParse = pNC->pParse;
+      zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
       break;
     }
 #endif
-    default:
-      zType = 0;
   }
   
+  if( pzOriginDb ){
+    assert( pzOriginTab && pzOriginCol );
+    *pzOriginDb = zOriginDb;
+    *pzOriginTab = zOriginTab;
+    *pzOriginCol = zOriginCol;
+  }
   return zType;
 }
 
@@ -803,14 +920,22 @@
   int i;
   NameContext sNC;
   sNC.pSrcList = pTabList;
+  sNC.pParse = pParse;
   for(i=0; i<pEList->nExpr; i++){
     Expr *p = pEList->a[i].pExpr;
-    const char *zType = columnType(&sNC, p);
-    if( zType==0 ) continue;
-    /* The vdbe must make it's own copy of the column-type, in case the 
-    ** schema is reset before this virtual machine is deleted.
+    const char *zOrigDb = 0;
+    const char *zOrigTab = 0;
+    const char *zOrigCol = 0;
+    const char *zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
+
+    /* The vdbe must make it's own copy of the column-type and other 
+    ** column specific strings, in case the schema is reset before this
+    ** virtual machine is deleted.
     */
-    sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, strlen(zType));
+    sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P3_TRANSIENT);
+    sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P3_TRANSIENT);
+    sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P3_TRANSIENT);
+    sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P3_TRANSIENT);
   }
 }
 
@@ -837,7 +962,7 @@
 #endif
 
   assert( v!=0 );
-  if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;
+  if( pParse->colNamesSet || v==0 || sqlite3MallocFailed() ) return;
   pParse->colNamesSet = 1;
   fullNames = (db->flags & SQLITE_FullColNames)!=0;
   shortNames = (db->flags & SQLITE_ShortColNames)!=0;
@@ -848,7 +973,7 @@
     if( p==0 ) continue;
     if( pEList->a[i].zName ){
       char *zName = pEList->a[i].zName;
-      sqlite3VdbeSetColName(v, i, zName, strlen(zName));
+      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));
       continue;
     }
     if( p->op==TK_COLUMN && pTabList ){
@@ -866,26 +991,26 @@
         zCol = pTab->aCol[iCol].zName;
       }
       if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
-        sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
+        sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
       }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
         char *zName = 0;
         char *zTab;
  
         zTab = pTabList->a[j].zAlias;
         if( fullNames || zTab==0 ) zTab = pTab->zName;
-        sqlite3SetString(&zName, zTab, ".", zCol, 0);
-        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
+        sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
+        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P3_DYNAMIC);
       }else{
-        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
+        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
       }
     }else if( p->span.z && p->span.z[0] ){
-      sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
+      sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
       /* sqlite3VdbeCompressSpace(v, addr); */
     }else{
       char zName[30];
       assert( p->op!=TK_COLUMN || pTabList==0 );
       sprintf(zName, "column%d", i+1);
-      sqlite3VdbeSetColName(v, i, zName, 0);
+      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, 0);
     }
   }
   generateColumnTypes(pParse, pTabList, pEList);
@@ -922,6 +1047,7 @@
   ExprList *pEList;
   Column *aCol, *pCol;
 
+  while( pSelect->pPrior ) pSelect = pSelect->pPrior;
   if( prepSelectStmt(pParse, pSelect) ){
     return 0;
   }
@@ -943,6 +1069,7 @@
     char *zType;
     char *zName;
     char *zBasename;
+    CollSeq *pColl;
     int cnt;
     NameContext sNC;
     
@@ -965,7 +1092,7 @@
       zName = sqlite3MPrintf("column%d", i+1);
     }
     sqlite3Dequote(zName);
-    if( sqlite3_malloc_failed ){
+    if( sqlite3MallocFailed() ){
       sqliteFree(zName);
       sqlite3DeleteTable(0, pTab);
       return 0;
@@ -992,12 +1119,12 @@
     */
     memset(&sNC, 0, sizeof(sNC));
     sNC.pSrcList = pSelect->pSrc;
-    zType = sqliteStrDup(columnType(&sNC, p));
+    zType = sqliteStrDup(columnType(&sNC, p, 0, 0, 0));
     pCol->zType = zType;
     pCol->affinity = sqlite3ExprAffinity(p);
-    pCol->pColl = sqlite3ExprCollSeq(pParse, p);
-    if( !pCol->pColl ){
-      pCol->pColl = pParse->db->pDfltColl;
+    pColl = sqlite3ExprCollSeq(pParse, p);
+    if( pColl ){
+      pCol->zColl = sqliteStrDup(pColl->zName);
     }
   }
   pTab->iPKey = -1;
@@ -1034,10 +1161,11 @@
   int i, j, k, rc;
   SrcList *pTabList;
   ExprList *pEList;
-  Table *pTab;
   struct SrcList_item *pFrom;
 
-  if( p==0 || p->pSrc==0 || sqlite3_malloc_failed ) return 1;
+  if( p==0 || p->pSrc==0 || sqlite3MallocFailed() ){
+    return 1;
+  }
   pTabList = p->pSrc;
   pEList = p->pEList;
 
@@ -1051,6 +1179,7 @@
   ** then create a transient table structure to describe the subquery.
   */
   for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+    Table *pTab;
     if( pFrom->pTab!=0 ){
       /* This statement has already been prepared.  There is no need
       ** to go further. */
@@ -1145,7 +1274,11 @@
         /* This particular expression does not need to be expanded.
         */
         pNew = sqlite3ExprListAppend(pNew, a[k].pExpr, 0);
-        pNew->a[pNew->nExpr-1].zName = a[k].zName;
+        if( pNew ){
+          pNew->a[pNew->nExpr-1].zName = a[k].zName;
+        }else{
+          rc = 1;
+        }
         a[k].pExpr = 0;
         a[k].zName = 0;
       }else{
@@ -1170,7 +1303,7 @@
           }
           tableSeen = 1;
           for(j=0; j<pTab->nCol; j++){
-            Expr *pExpr, *pLeft, *pRight;
+            Expr *pExpr, *pRight;
             char *zName = pTab->aCol[j].zName;
 
             if( i>0 ){
@@ -1191,7 +1324,7 @@
             if( pRight==0 ) break;
             setToken(&pRight->token, zName);
             if( zTabName && (longNames || pTabList->nSrc>1) ){
-              pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
+              Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
               pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0);
               if( pExpr==0 ) break;
               setToken(&pLeft->token, zTabName);
@@ -1326,25 +1459,31 @@
   return v;
 }
 
+
 /*
 ** Compute the iLimit and iOffset fields of the SELECT based on the
-** pLimit and pOffset expressions.  nLimit and nOffset hold the expressions
+** pLimit and pOffset expressions.  pLimit and pOffset hold the expressions
 ** that appear in the original SQL statement after the LIMIT and OFFSET
 ** keywords.  Or NULL if those keywords are omitted. iLimit and iOffset 
 ** are the integer memory register numbers for counters used to compute 
 ** the limit and offset.  If there is no limit and/or offset, then 
 ** iLimit and iOffset are negative.
 **
-** This routine changes the values if iLimit and iOffset only if
-** a limit or offset is defined by nLimit and nOffset.  iLimit and
+** This routine changes the values of iLimit and iOffset only if
+** a limit or offset is defined by pLimit and pOffset.  iLimit and
 ** iOffset should have been preset to appropriate default values
 ** (usually but not always -1) prior to calling this routine.
-** Only if nLimit>=0 or nOffset>0 do the limit registers get
+** Only if pLimit!=0 or pOffset!=0 do the limit registers get
 ** redefined.  The UNION ALL operator uses this property to force
 ** the reuse of the same limit and offset registers across multiple
 ** SELECT statements.
 */
-static void computeLimitRegisters(Parse *pParse, Select *p){
+static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
+  Vdbe *v = 0;
+  int iLimit = 0;
+  int iOffset;
+  int addr1, addr2;
+
   /* 
   ** "LIMIT -1" always shows all rows.  There is some
   ** contraversy about what the correct behavior should be.
@@ -1352,27 +1491,42 @@
   ** no rows.
   */
   if( p->pLimit ){
-    int iMem = pParse->nMem++;
-    Vdbe *v = sqlite3GetVdbe(pParse);
+    p->iLimit = iLimit = pParse->nMem;
+    pParse->nMem += 2;
+    v = sqlite3GetVdbe(pParse);
     if( v==0 ) return;
     sqlite3ExprCode(pParse, p->pLimit);
     sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
-    sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
-    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
+    sqlite3VdbeAddOp(v, OP_MemStore, iLimit, 0);
     VdbeComment((v, "# LIMIT counter"));
-    p->iLimit = iMem;
+    sqlite3VdbeAddOp(v, OP_IfMemZero, iLimit, iBreak);
   }
   if( p->pOffset ){
-    int iMem = pParse->nMem++;
-    Vdbe *v = sqlite3GetVdbe(pParse);
+    p->iOffset = iOffset = pParse->nMem++;
+    v = sqlite3GetVdbe(pParse);
     if( v==0 ) return;
     sqlite3ExprCode(pParse, p->pOffset);
     sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
-    sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
-    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
+    sqlite3VdbeAddOp(v, OP_MemStore, iOffset, p->pLimit==0);
     VdbeComment((v, "# OFFSET counter"));
-    p->iOffset = iMem;
+    addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iOffset, 0);
+    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+    sqlite3VdbeJumpHere(v, addr1);
+    if( p->pLimit ){
+      sqlite3VdbeAddOp(v, OP_Add, 0, 0);
+    }
   }
+  if( p->pLimit ){
+    addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iLimit, 0);
+    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+    sqlite3VdbeAddOp(v, OP_MemInt, -1, iLimit+1);
+    addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
+    sqlite3VdbeJumpHere(v, addr1);
+    sqlite3VdbeAddOp(v, OP_MemStore, iLimit+1, 1);
+    VdbeComment((v, "# LIMIT+OFFSET"));
+    sqlite3VdbeJumpHere(v, addr2);
+  }
 }
 
 /*
@@ -1390,20 +1544,6 @@
   }
 }
 
-/*
-** The opcode at addr is an OP_OpenVirtual that created a sorting
-** index tha we ended up not needing.  This routine changes that
-** opcode to OP_Noop.
-*/
-static void uncreateSortingIndex(Parse *pParse, int addr){
-  Vdbe *v = pParse->pVdbe;
-  VdbeOp *pOp = sqlite3VdbeGetOp(v, addr);
-  sqlite3VdbeChangeP3(v, addr, 0, 0);
-  pOp->opcode = OP_Noop;
-  pOp->p1 = 0;
-  pOp->p2 = 0;
-}
-
 #ifndef SQLITE_OMIT_COMPOUND_SELECT
 /*
 ** Return the appropriate collating sequence for the iCol-th column of
@@ -1519,23 +1659,31 @@
   switch( p->op ){
     case TK_ALL: {
       if( pOrderBy==0 ){
+        int addr = 0;
         assert( !pPrior->pLimit );
         pPrior->pLimit = p->pLimit;
         pPrior->pOffset = p->pOffset;
         rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff);
+        p->pLimit = 0;
+        p->pOffset = 0;
         if( rc ){
           goto multi_select_end;
         }
         p->pPrior = 0;
         p->iLimit = pPrior->iLimit;
         p->iOffset = pPrior->iOffset;
-        p->pLimit = 0;
-        p->pOffset = 0;
+        if( p->iLimit>=0 ){
+          addr = sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, 0);
+          VdbeComment((v, "# Jump ahead if LIMIT reached"));
+        }
         rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
         p->pPrior = pPrior;
         if( rc ){
           goto multi_select_end;
         }
+        if( addr ){
+          sqlite3VdbeJumpHere(v, addr);
+        }
         break;
       }
       /* For UNION ALL ... ORDER BY fall through to the next case */
@@ -1618,12 +1766,14 @@
         int iCont, iBreak, iStart;
         assert( p->pEList );
         if( eDest==SRT_Callback ){
-          generateColumnNames(pParse, 0, p->pEList);
+          Select *pFirst = p;
+          while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+          generateColumnNames(pParse, 0, pFirst->pEList);
         }
         iBreak = sqlite3VdbeMakeLabel(v);
         iCont = sqlite3VdbeMakeLabel(v);
+        computeLimitRegisters(pParse, p, iBreak);
         sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
-        computeLimitRegisters(pParse, p);
         iStart = sqlite3VdbeCurrentAddr(v);
         rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
                              pOrderBy, -1, eDest, iParm, 
@@ -1694,12 +1844,14 @@
       */
       assert( p->pEList );
       if( eDest==SRT_Callback ){
-        generateColumnNames(pParse, 0, p->pEList);
+        Select *pFirst = p;
+        while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+        generateColumnNames(pParse, 0, pFirst->pEList);
       }
       iBreak = sqlite3VdbeMakeLabel(v);
       iCont = sqlite3VdbeMakeLabel(v);
+      computeLimitRegisters(pParse, p, iBreak);
       sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
-      computeLimitRegisters(pParse, p);
       iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0);
       sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
       rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
@@ -1760,7 +1912,7 @@
       goto multi_select_end;
     }
 
-    pKeyInfo->enc = pParse->db->enc;
+    pKeyInfo->enc = ENC(pParse->db);
     pKeyInfo->nField = nCol;
 
     for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
@@ -1786,15 +1938,15 @@
 
     if( pOrderBy ){
       struct ExprList_item *pOTerm = pOrderBy->a;
-      int nExpr = pOrderBy->nExpr;
+      int nOrderByExpr = pOrderBy->nExpr;
       int addr;
       u8 *pSortOrder;
 
-      aCopy = (CollSeq**)&pKeyInfo[1];
-      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nExpr];
+      aCopy = &pKeyInfo->aColl[nCol];
+      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol];
       memcpy(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));
       apColl = pKeyInfo->aColl;
-      for(i=0; i<pOrderBy->nExpr; i++, pOTerm++, apColl++, pSortOrder++){
+      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
         Expr *pExpr = pOTerm->pExpr;
         char *zName = pOTerm->zName;
         assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );
@@ -1809,7 +1961,7 @@
       assert( p->addrOpenVirt[2]>=0 );
       addr = p->addrOpenVirt[2];
       sqlite3VdbeChangeP2(v, addr, p->pEList->nExpr+2);
-      pKeyInfo->nField = pOrderBy->nExpr;
+      pKeyInfo->nField = nOrderByExpr;
       sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
       pKeyInfo = 0;
       generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm);
@@ -1949,6 +2101,10 @@
 **  (12)  The subquery is not the right term of a LEFT OUTER JOIN or the
 **        subquery has no WHERE clause.  (added by ticket #350)
 **
+**  (13)  The subquery and outer query do not both use LIMIT
+**
+**  (14)  The subquery does not use OFFSET
+**
 ** In this routine, the "p" parameter is a pointer to the outer query.
 ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
 ** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
@@ -1960,7 +2116,6 @@
 ** the subquery before this routine runs.
 */
 static int flattenSubquery(
-  Parse *pParse,       /* The parsing context */
   Select *p,           /* The parent or outer SELECT statement */
   int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
   int isAgg,           /* True if outer SELECT uses aggregate functions */
@@ -1983,18 +2138,26 @@
   pSubitem = &pSrc->a[iFrom];
   pSub = pSubitem->pSelect;
   assert( pSub!=0 );
-  if( isAgg && subqueryIsAgg ) return 0;
-  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
+  if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
+  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;          /* Restriction (2)  */
   pSubSrc = pSub->pSrc;
   assert( pSubSrc );
-  if( (pSub->pLimit && p->pLimit) || pSub->pOffset || 
-      (pSub->pLimit && isAgg) ) return 0;
-  if( pSubSrc->nSrc==0 ) return 0;
-  if( pSub->isDistinct && (pSrc->nSrc>1 || isAgg) ){
-     return 0;
+  /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
+  ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
+  ** because they could be computed at compile-time.  But when LIMIT and OFFSET
+  ** became arbitrary expressions, we were forced to add restrictions (13)
+  ** and (14). */
+  if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
+  if( pSub->pOffset ) return 0;                          /* Restriction (14) */
+  if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
+  if( (pSub->isDistinct || pSub->pLimit) 
+         && (pSrc->nSrc>1 || isAgg) ){          /* Restrictions (4)(5)(8)(9) */
+     return 0;       
   }
-  if( p->isDistinct && subqueryIsAgg ) return 0;
-  if( (p->disallowOrderBy || p->pOrderBy) && pSub->pOrderBy ) return 0;
+  if( p->isDistinct && subqueryIsAgg ) return 0;         /* Restriction (6)  */
+  if( (p->disallowOrderBy || p->pOrderBy) && pSub->pOrderBy ){
+     return 0;                                           /* Restriction (11) */
+  }
 
   /* Restriction 3:  If the subquery is a join, make sure the subquery is 
   ** not used as the right operand of an outer join.  Examples of why this
@@ -2080,14 +2243,14 @@
   ** We look at every expression in the outer query and every place we see
   ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
   */
-  substExprList(p->pEList, iParent, pSub->pEList);
   pList = p->pEList;
   for(i=0; i<pList->nExpr; i++){
     Expr *pExpr;
     if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
-      pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
+      pList->a[i].zName = sqliteStrNDup((char*)pExpr->span.z, pExpr->span.n);
     }
   }
+  substExprList(p->pEList, iParent, pSub->pEList);
   if( isAgg ){
     substExprList(p->pGroupBy, iParent, pSub->pEList);
     substExpr(p->pHaving, iParent, pSub->pEList);
@@ -2124,6 +2287,9 @@
 
   /*
   ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
+  **
+  ** One is tempted to try to add a and b to combine the limits.  But this
+  ** does not work if either limit is negative.
   */
   if( pSub->pLimit ){
     p->pLimit = pSub->pLimit;
@@ -2166,10 +2332,11 @@
   int base;
   Vdbe *v;
   int seekOp;
-  int cont;
   ExprList *pEList, *pList, eList;
   struct ExprList_item eListItem;
   SrcList *pSrc;
+  int brk;
+  int iDb;
 
   /* Check to see if this query is a simple min() or max() query.  Return
   ** zero if it is  not.
@@ -2184,9 +2351,9 @@
   pList = pExpr->pList;
   if( pList==0 || pList->nExpr!=1 ) return 0;
   if( pExpr->token.n!=3 ) return 0;
-  if( sqlite3StrNICmp(pExpr->token.z,"min",3)==0 ){
+  if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){
     seekOp = OP_Rewind;
-  }else if( sqlite3StrNICmp(pExpr->token.z,"max",3)==0 ){
+  }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){
     seekOp = OP_Last;
   }else{
     return 0;
@@ -2196,6 +2363,7 @@
   iCol = pExpr->iColumn;
   pTab = pSrc->a[0].pTab;
 
+
   /* If we get to here, it means the query is of the correct form.
   ** Check to make sure we have an index and make pIdx point to the
   ** appropriate index.  If the min() or max() is on an INTEGER PRIMARY
@@ -2208,7 +2376,10 @@
     CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
       assert( pIdx->nColumn>=1 );
-      if( pIdx->aiColumn[0]==iCol && pIdx->keyInfo.aColl[0]==pColl ) break;
+      if( pIdx->aiColumn[0]==iCol && 
+          0==sqlite3StrICmp(pIdx->azColl[0], pColl->zName) ){
+        break;
+      }
     }
     if( pIdx==0 ) return 0;
   }
@@ -2231,13 +2402,16 @@
   ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
   ** or last entry in the main table.
   */
-  sqlite3CodeVerifySchema(pParse, pTab->iDb);
+  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+  assert( iDb>=0 || pTab->isTransient );
+  sqlite3CodeVerifySchema(pParse, iDb);
+  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
   base = pSrc->a[0].iCursor;
-  computeLimitRegisters(pParse, p);
+  brk = sqlite3VdbeMakeLabel(v);
+  computeLimitRegisters(pParse, p, brk);
   if( pSrc->a[0].pSelect==0 ){
-    sqlite3OpenTableForReading(v, base, pTab);
+    sqlite3OpenTable(pParse, base, iDb, pTab, OP_OpenRead);
   }
-  cont = sqlite3VdbeMakeLabel(v);
   if( pIdx==0 ){
     sqlite3VdbeAddOp(v, seekOp, base, 0);
   }else{
@@ -2248,10 +2422,12 @@
     ** "INSERT INTO x SELECT max() FROM x".
     */
     int iIdx;
+    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
     iIdx = pParse->nTab++;
-    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
-    sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
-                   (char*)&pIdx->keyInfo, P3_KEYINFO);
+    assert( pIdx->pSchema==pTab->pSchema );
+    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
+    sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, 
+        (char*)pKey, P3_KEYINFO_HANDOFF);
     if( seekOp==OP_Rewind ){
       sqlite3VdbeAddOp(v, OP_Null, 0, 0);
       sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
@@ -2266,8 +2442,8 @@
   memset(&eListItem, 0, sizeof(eListItem));
   eList.a = &eListItem;
   eList.a[0].pExpr = pExpr;
-  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont, 0);
-  sqlite3VdbeResolveLabel(v, cont);
+  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, brk, brk, 0);
+  sqlite3VdbeResolveLabel(v, brk);
   sqlite3VdbeAddOp(v, OP_Close, base, 0);
   
   return 1;
@@ -2356,14 +2532,8 @@
   /* Resolve the expressions in the LIMIT and OFFSET clauses. These
   ** are not allowed to refer to any names, so pass an empty NameContext.
   */
+  memset(&sNC, 0, sizeof(sNC));
   sNC.pParse = pParse;
-  sNC.hasAgg = 0;
-  sNC.nErr = 0;
-  sNC.nRef = 0;
-  sNC.pEList = 0;
-  sNC.allowAgg = 0;
-  sNC.pSrcList = 0;
-  sNC.pNext = 0;
   if( sqlite3ExprResolveNames(&sNC, p->pLimit) ||
       sqlite3ExprResolveNames(&sNC, p->pOffset) ){
     return SQLITE_ERROR;
@@ -2511,13 +2681,14 @@
     if( pF->iDistinct>=0 ){
       addrNext = sqlite3VdbeMakeLabel(v);
       assert( nArg==1 );
-      codeDistinct(v, pF->iDistinct, addrNext, 1, 2);
+      codeDistinct(v, pF->iDistinct, addrNext, 1);
     }
     if( pF->pFunc->needCollSeq ){
       CollSeq *pColl = 0;
       struct ExprList_item *pItem;
       int j;
-      for(j=0, pItem=pList->a; !pColl && j<pList->nExpr; j++, pItem++){
+      assert( pList!=0 );  /* pList!=0 if pF->pFunc->needCollSeq is true */
+      for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
         pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
       }
       if( !pColl ){
@@ -2615,8 +2786,11 @@
   int rc = 1;            /* Value to return from this function */
   int addrSortIndex;     /* Address of an OP_OpenVirtual instruction */
   AggInfo sAggInfo;      /* Information used by aggregate queries */
+  int iEnd;              /* Address of the end of the query */
 
-  if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1;
+  if( p==0 || sqlite3MallocFailed() || pParse->nErr ){
+    return 1;
+  }
   if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
   memset(&sAggInfo, 0, sizeof(sAggInfo));
 
@@ -2663,7 +2837,6 @@
   /* If writing to memory or generating a set
   ** only a single column may be output.
   */
-  assert( eDest!=SRT_Exists || pEList->nExpr==1 );
 #ifndef SQLITE_OMIT_SUBQUERY
   if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
     sqlite3ErrorMsg(pParse, "only a single result allowed for "
@@ -2683,13 +2856,6 @@
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto select_end;
 
-  /* Identify column names if we will be using them in a callback.  This
-  ** step is skipped if the output is going to some other destination.
-  */
-  if( eDest==SRT_Callback ){
-    generateColumnNames(pParse, pTabList, pEList);
-  }
-
   /* Generate code for all sub-queries in the FROM clause
   */
 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
@@ -2698,7 +2864,7 @@
     int needRestoreContext;
     struct SrcList_item *pItem = &pTabList->a[i];
 
-    if( pItem->pSelect==0 ) continue;
+    if( pItem->pSelect==0 || pItem->isPopulated ) continue;
     if( pItem->zName!=0 ){
       zSavedAuthContext = pParse->zAuthContext;
       pParse->zAuthContext = pItem->zName;
@@ -2735,7 +2901,7 @@
   */
 #ifndef SQLITE_OMIT_VIEW
   if( pParent && pParentAgg &&
-      flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
+      flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){
     if( isAgg ) *pParentAgg = 1;
     goto select_end;
   }
@@ -2772,7 +2938,8 @@
 
   /* Set the limiter.
   */
-  computeLimitRegisters(pParse, p);
+  iEnd = sqlite3VdbeMakeLabel(v);
+  computeLimitRegisters(pParse, p, iEnd);
 
   /* If the output is destined for a temporary table, open that table.
   */
@@ -2780,15 +2947,6 @@
     sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, pEList->nExpr);
   }
 
-
-  /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
-  */
-  if( eDest==SRT_Mem ){
-    sqlite3VdbeAddOp(v, OP_MemNull, iParm, 0);
-  }else if( eDest==SRT_Exists ){
-    sqlite3VdbeAddOp(v, OP_MemInt, 0, iParm);
-  }
-
   /* Open a virtual index to use for the distinct set.
   */
   if( isDistinct ){
@@ -2814,7 +2972,7 @@
     ** into an OP_Noop.
     */
     if( addrSortIndex>=0 && pOrderBy==0 ){
-      uncreateSortingIndex(pParse, addrSortIndex);
+      sqlite3VdbeChangeToNoop(v, addrSortIndex, 1);
       p->addrOpenVirt[2] = -1;
     }
 
@@ -2879,7 +3037,7 @@
         goto select_end;
       }
     }
-    if( sqlite3_malloc_failed ) goto select_end;
+    if( sqlite3MallocFailed() ) goto select_end;
 
     /* Processing for aggregates with GROUP BY is very different and
     ** much more complex tha aggregates without a GROUP BY.
@@ -3060,7 +3218,7 @@
         sqlite3VdbeAddOp(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
       }else{
         sqlite3WhereEnd(pWInfo);
-        uncreateSortingIndex(pParse, addrSortingIdx);
+        sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1);
       }
 
       /* Output the final row of result
@@ -3100,18 +3258,21 @@
 
 #ifndef SQLITE_OMIT_SUBQUERY
   /* If this was a subquery, we have now converted the subquery into a
-  ** temporary table.  So delete the subquery structure from the parent
-  ** to prevent this subquery from being evaluated again and to force the
-  ** the use of the temporary table.
+  ** temporary table.  So set the SrcList_item.isPopulated flag to prevent
+  ** this subquery from being evaluated again and to force the use of
+  ** the temporary table.
   */
   if( pParent ){
     assert( pParent->pSrc->nSrc>parentTab );
     assert( pParent->pSrc->a[parentTab].pSelect==p );
-    sqlite3SelectDelete(p);
-    pParent->pSrc->a[parentTab].pSelect = 0;
+    pParent->pSrc->a[parentTab].isPopulated = 1;
   }
 #endif
 
+  /* Jump here to skip this query
+  */
+  sqlite3VdbeResolveLabel(v, iEnd);
+
   /* The SELECT was successfully coded.   Set the return code to 0
   ** to indicate no errors.
   */
@@ -3121,6 +3282,14 @@
   ** successful coding of the SELECT.
   */
 select_end:
+
+  /* Identify column names if we will be using them in a callback.  This
+  ** step is skipped if the output is going to some other destination.
+  */
+  if( rc==SQLITE_OK && eDest==SRT_Callback ){
+    generateColumnNames(pParse, pTabList, pEList);
+  }
+
   sqliteFree(sAggInfo.aCol);
   sqliteFree(sAggInfo.aFunc);
   return rc;

Modified: packages/libdbd-sqlite3-perl/trunk/sqlite3.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/sqlite3.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/sqlite3.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.141 2005/09/08 10:58:52 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.165 2006/04/04 01:54:55 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -31,7 +31,7 @@
 #ifdef SQLITE_VERSION
 # undef SQLITE_VERSION
 #endif
-#define SQLITE_VERSION         "3.2.7"
+#define SQLITE_VERSION         "3.3.5"
 
 /*
 ** The format of the version string is "X.Y.Z<trailing string>", where
@@ -48,7 +48,7 @@
 #ifdef SQLITE_VERSION_NUMBER
 # undef SQLITE_VERSION_NUMBER
 #endif
-#define SQLITE_VERSION_NUMBER 3002007
+#define SQLITE_VERSION_NUMBER 3003005
 
 /*
 ** The version string is also compiled into the library so that a program
@@ -78,7 +78,10 @@
 ** to do a typedef that for 64-bit integers that depends on what compiler
 ** is being used.
 */
-#if defined(_MSC_VER) || defined(__BORLANDC__)
+#ifdef SQLITE_INT64_TYPE
+  typedef SQLITE_INT64_TYPE sqlite_int64;
+  typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
   typedef __int64 sqlite_int64;
   typedef unsigned __int64 sqlite_uint64;
 #else
@@ -86,6 +89,13 @@
   typedef unsigned long long int sqlite_uint64;
 #endif
 
+/*
+** If compiling for a processor that lacks floating point support,
+** substitute integer for floating-point
+*/
+#ifdef SQLITE_OMIT_FLOATING_POINT
+# define double sqlite_int64
+#endif
 
 /*
 ** A function to close the database.
@@ -157,6 +167,7 @@
 ** Return values for sqlite3_exec() and sqlite3_step()
 */
 #define SQLITE_OK           0   /* Successful result */
+/* beginning-of-error-codes */
 #define SQLITE_ERROR        1   /* SQL error or missing database */
 #define SQLITE_INTERNAL     2   /* NOT USED. Internal logic error in SQLite */
 #define SQLITE_PERM         3   /* Access permission denied */
@@ -185,6 +196,7 @@
 #define SQLITE_NOTADB      26   /* File opened that is not a database file */
 #define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
 #define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
+/* end-of-error-codes */
 
 /*
 ** Each entry in an SQLite table has a unique integer key.  (The key is
@@ -717,6 +729,30 @@
 const void *sqlite3_column_name16(sqlite3_stmt*,int);
 
 /*
+** The first parameter to the following calls is a compiled SQL statement.
+** These functions return information about the Nth column returned by 
+** the statement, where N is the second function argument.
+**
+** If the Nth column returned by the statement is not a column value,
+** then all of the functions return NULL. Otherwise, the return the 
+** name of the attached database, table and column that the expression
+** extracts a value from.
+**
+** As with all other SQLite APIs, those postfixed with "16" return UTF-16
+** encoded strings, the other functions return UTF-8. The memory containing
+** the returned strings is valid until the statement handle is finalized().
+**
+** These APIs are only available if the library was compiled with the 
+** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+*/
+const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+
+/*
 ** The first parameter is a compiled SQL statement. If this statement
 ** is a SELECT statement, the Nth column of the returned result set 
 ** of the SELECT is a table column then the declared type of the table
@@ -728,7 +764,7 @@
 **
 ** And the following statement compiled:
 **
-** SELECT c1 + 1, 0 FROM t1;
+** SELECT c1 + 1, c1 FROM t1;
 **
 ** Then this routine would return the string "VARIANT" for the second
 ** result column (i==1), and a NULL pointer for the first result column
@@ -748,7 +784,7 @@
 **
 ** And the following statement compiled:
 **
-** SELECT c1 + 1, 0 FROM t1;
+** SELECT c1 + 1, c1 FROM t1;
 **
 ** Then this routine would return the string "INTEGER" for the second
 ** result column (i==1), and a NULL pointer for the first result column
@@ -889,6 +925,7 @@
 const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
 const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
 int sqlite3_column_type(sqlite3_stmt*, int iCol);
+int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol);
 
 /*
 ** The sqlite3_finalize() function is called to delete a compiled
@@ -972,9 +1009,8 @@
 );
 
 /*
-** The next routine returns the number of calls to xStep for a particular
-** aggregate function instance.  The current call to xStep counts so this
-** routine always returns at least 1.
+** This function is deprecated.  Do not use it.  It continues to exist
+** so as not to break legacy code.  But new code should avoid using it.
 */
 int sqlite3_aggregate_count(sqlite3_context*);
 
@@ -997,6 +1033,7 @@
 const void *sqlite3_value_text16le(sqlite3_value*);
 const void *sqlite3_value_text16be(sqlite3_value*);
 int sqlite3_value_type(sqlite3_value*);
+int sqlite3_value_numeric_type(sqlite3_value*);
 
 /*
 ** Aggregate functions use the following routine to allocate
@@ -1080,11 +1117,12 @@
 ** These are the allowed values for the eTextRep argument to
 ** sqlite3_create_collation and sqlite3_create_function.
 */
-#define SQLITE_UTF8    1
-#define SQLITE_UTF16LE 2
-#define SQLITE_UTF16BE 3
-#define SQLITE_UTF16   4    /* Use native byte order */
-#define SQLITE_ANY     5    /* sqlite3_create_function only */
+#define SQLITE_UTF8           1
+#define SQLITE_UTF16LE        2
+#define SQLITE_UTF16BE        3
+#define SQLITE_UTF16          4    /* Use native byte order */
+#define SQLITE_ANY            5    /* sqlite3_create_function only */
+#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */
 
 /*
 ** These two functions are used to add new collation sequences to the
@@ -1251,7 +1289,7 @@
 ** This functionality can be omitted from a build by defining the 
 ** SQLITE_OMIT_GLOBALRECOVER at compile time.
 */
-int sqlite3_global_recover();
+int sqlite3_global_recover(void);
 
 /*
 ** Test to see whether or not the database connection is in autocommit
@@ -1269,6 +1307,175 @@
 */
 sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 
+/*
+** Register a callback function with the database connection identified by the 
+** first argument to be invoked whenever a row is updated, inserted or deleted.
+** Any callback set by a previous call to this function for the same 
+** database connection is overridden.
+**
+** The second argument is a pointer to the function to invoke when a 
+** row is updated, inserted or deleted. The first argument to the callback is
+** a copy of the third argument to sqlite3_update_hook. The second callback 
+** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending
+** on the operation that caused the callback to be invoked. The third and 
+** fourth arguments to the callback contain pointers to the database and 
+** table name containing the affected row. The final callback parameter is 
+** the rowid of the row. In the case of an update, this is the rowid after 
+** the update takes place.
+**
+** The update hook is not invoked when internal system tables are
+** modified (i.e. sqlite_master and sqlite_sequence).
+**
+** If another function was previously registered, its pArg value is returned.
+** Otherwise NULL is returned.
+*/
+void *sqlite3_update_hook(
+  sqlite3*, 
+  void(*)(void *,int ,char const *,char const *,sqlite_int64),
+  void*
+);
+
+/*
+** Register a callback to be invoked whenever a transaction is rolled
+** back. 
+**
+** The new callback function overrides any existing rollback-hook
+** callback. If there was an existing callback, then it's pArg value 
+** (the third argument to sqlite3_rollback_hook() when it was registered) 
+** is returned. Otherwise, NULL is returned.
+**
+** For the purposes of this API, a transaction is said to have been 
+** rolled back if an explicit "ROLLBACK" statement is executed, or
+** an error or constraint causes an implicit rollback to occur. The 
+** callback is not invoked if a transaction is automatically rolled
+** back because the database connection is closed.
+*/
+void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+
+/*
+** This function is only available if the library is compiled without
+** the SQLITE_OMIT_SHARED_CACHE macro defined. It is used to enable or
+** disable (if the argument is true or false, respectively) the 
+** "shared pager" feature.
+*/
+int sqlite3_enable_shared_cache(int);
+
+/*
+** Attempt to free N bytes of heap memory by deallocating non-essential
+** memory allocations held by the database library (example: memory 
+** used to cache database pages to improve performance).
+**
+** This function is not a part of standard builds.  It is only created
+** if SQLite is compiled with the SQLITE_ENABLE_MEMORY_MANAGEMENT macro.
+*/
+int sqlite3_release_memory(int);
+
+/*
+** Place a "soft" limit on the amount of heap memory that may be allocated by
+** SQLite within the current thread. If an internal allocation is requested 
+** that would exceed the specified limit, sqlite3_release_memory() is invoked
+** one or more times to free up some space before the allocation is made.
+**
+** The limit is called "soft", because if sqlite3_release_memory() cannot free
+** sufficient memory to prevent the limit from being exceeded, the memory is
+** allocated anyway and the current operation proceeds.
+**
+** This function is only available if the library was compiled with the 
+** SQLITE_ENABLE_MEMORY_MANAGEMENT option set.
+** memory-management has been enabled.
+*/
+void sqlite3_soft_heap_limit(int);
+
+/*
+** This routine makes sure that all thread-local storage has been
+** deallocated for the current thread.
+**
+** This routine is not technically necessary.  All thread-local storage
+** will be automatically deallocated once memory-management and
+** shared-cache are disabled and the soft heap limit has been set
+** to zero.  This routine is provided as a convenience for users who
+** want to make absolutely sure they have not forgotten something
+** prior to killing off a thread.
+*/
+void sqlite3_thread_cleanup(void);
+
+/*
+** Return meta information about a specific column of a specific database
+** table accessible using the connection handle passed as the first function 
+** argument.
+**
+** The column is identified by the second, third and fourth parameters to 
+** this function. The second parameter is either the name of the database
+** (i.e. "main", "temp" or an attached database) containing the specified
+** table or NULL. If it is NULL, then all attached databases are searched
+** for the table using the same algorithm as the database engine uses to 
+** resolve unqualified table references.
+**
+** The third and fourth parameters to this function are the table and column 
+** name of the desired column, respectively. Neither of these parameters 
+** may be NULL.
+**
+** Meta information is returned by writing to the memory locations passed as
+** the 5th and subsequent parameters to this function. Any of these 
+** arguments may be NULL, in which case the corresponding element of meta 
+** information is ommitted.
+**
+** Parameter     Output Type      Description
+** -----------------------------------
+**
+**   5th         const char*      Data type
+**   6th         const char*      Name of the default collation sequence 
+**   7th         int              True if the column has a NOT NULL constraint
+**   8th         int              True if the column is part of the PRIMARY KEY
+**   9th         int              True if the column is AUTOINCREMENT
+**
+**
+** The memory pointed to by the character pointers returned for the 
+** declaration type and collation sequence is valid only until the next 
+** call to any sqlite API function.
+**
+** If the specified table is actually a view, then an error is returned.
+**
+** If the specified column is "rowid", "oid" or "_rowid_" and an 
+** INTEGER PRIMARY KEY column has been explicitly declared, then the output 
+** parameters are set for the explicitly declared column. If there is no
+** explicitly declared IPK column, then the output parameters are set as 
+** follows:
+**
+**     data type: "INTEGER"
+**     collation sequence: "BINARY"
+**     not null: 0
+**     primary key: 1
+**     auto increment: 0
+**
+** This function may load one or more schemas from database files. If an
+** error occurs during this process, or if the requested table or column
+** cannot be found, an SQLITE error code is returned and an error message
+** left in the database handle (to be retrieved using sqlite3_errmsg()).
+**
+** This API is only available if the library was compiled with the
+** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+*/
+int sqlite3_table_column_metadata(
+  sqlite3 *db,                /* Connection handle */
+  const char *zDbName,        /* Database name or NULL */
+  const char *zTableName,     /* Table name */
+  const char *zColumnName,    /* Column name */
+  char const **pzDataType,    /* OUTPUT: Declared data type */
+  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
+  int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
+  int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
+  int *pAutoinc               /* OUTPUT: True if colums is auto-increment */
+);
+
+/*
+** Undo the hack that converts floating point types to integer for
+** builds on processors without floating point support.
+*/
+#ifdef SQLITE_OMIT_FLOATING_POINT
+# undef double
+#endif
+
 #ifdef __cplusplus
 }  /* End of the 'extern "C"' block */
 #endif

Modified: packages/libdbd-sqlite3-perl/trunk/sqliteInt.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/sqliteInt.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/sqliteInt.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -11,19 +11,26 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.421 2005/09/19 21:05:49 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.493 2006/04/04 01:54:55 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
 
 /*
+** Extra interface definitions for those who need them
+*/
+#ifdef SQLITE_EXTRA
+# include "sqliteExtra.h"
+#endif
+
+/*
 ** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
 ** Setting NDEBUG makes the code smaller and run faster.  So the following
 ** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1
 ** option is set.  Thus NDEBUG becomes an opt-in rather than an opt-out
 ** feature.
 */
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
 # define NDEBUG 1
 #endif
 
@@ -60,6 +67,23 @@
 #include <stddef.h>
 
 /*
+** If compiling for a processor that lacks floating point support,
+** substitute integer for floating-point
+*/
+#ifdef SQLITE_OMIT_FLOATING_POINT
+# define double sqlite_int64
+# define LONGDOUBLE_TYPE sqlite_int64
+# ifndef SQLITE_BIG_DBL
+#   define SQLITE_BIG_DBL (0x7fffffffffffffff)
+# endif
+# define SQLITE_OMIT_DATETIME_FUNCS 1
+# define SQLITE_OMIT_TRACE 1
+#endif
+#ifndef SQLITE_BIG_DBL
+# define SQLITE_BIG_DBL (1e99)
+#endif
+
+/*
 ** The maximum number of in-memory pages to use for the main database
 ** table and for temporary tables. Internally, the MAX_PAGES and 
 ** TEMP_PAGES macros are used. To override the default values at
@@ -90,18 +114,6 @@
 
 /*
 ** If the following macro is set to 1, then NULL values are considered
-** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
-** compound queries.  No other SQL database engine (among those tested) 
-** works this way except for OCELOT.  But the SQL92 spec implies that
-** this is how things should work.
-**
-** If the following macro is set to 0, then NULLs are indistinct for
-** SELECT DISTINCT and for UNION.
-*/
-#define NULL_ALWAYS_DISTINCT 0
-
-/*
-** If the following macro is set to 1, then NULL values are considered
 ** distinct when determining whether or not two entries are the same
 ** in a UNIQUE index.  This is the way PostgreSQL, Oracle, DB2, MySQL,
 ** OCELOT, and Firebird all work.  The SQL92 spec explicitly says this
@@ -129,18 +141,15 @@
 #define SQLITE_MAX_VARIABLE_NUMBER 999
 
 /*
-** When building SQLite for embedded systems where memory is scarce,
-** you can define one or more of the following macros to omit extra
-** features of the library and thus keep the size of the library to
-** a minimum.
+** The "file format" number is an integer that is incremented whenever
+** the VDBE-level file format changes.  The following macros define the
+** the default file format for new databases and the maximum file format
+** that the library can read.
 */
-/* #define SQLITE_OMIT_AUTHORIZATION  1 */
-/* #define SQLITE_OMIT_MEMORYDB     1 */
-/* #define SQLITE_OMIT_VACUUM         1 */
-/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */
-/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */
-/* #define SQLITE_OMIT_AUTOVACUUM */
-/* #define SQLITE_OMIT_ALTERTABLE */
+#define SQLITE_MAX_FILE_FORMAT 4
+#ifndef SQLITE_DEFAULT_FILE_FORMAT
+# define SQLITE_DEFAULT_FILE_FORMAT 4
+#endif
 
 /*
 ** Provide a default value for TEMP_STORE in case it is not specified
@@ -159,19 +168,22 @@
 #endif
 
 /*
+** Check to see if this machine uses EBCDIC.  (Yes, believe it or
+** not, there are still machines out there that use EBCDIC.)
+*/
+#if 'A' == '\301'
+# define SQLITE_EBCDIC 1
+#else
+# define SQLITE_ASCII 1
+#endif
+
+/*
 ** Integers of known sizes.  These typedefs might change for architectures
 ** where the sizes very.  Preprocessor macros are available so that the
 ** types can be conveniently redefined at compile-type.  Like this:
 **
 **         cc '-DUINTPTR_TYPE=long long int' ...
 */
-#ifndef UINT64_TYPE
-# if defined(_MSC_VER) || defined(__BORLANDC__)
-#   define UINT64_TYPE unsigned __int64
-# else
-#   define UINT64_TYPE unsigned long long int
-# endif
-#endif
 #ifndef UINT32_TYPE
 # define UINT32_TYPE unsigned int
 #endif
@@ -191,7 +203,7 @@
 # define LONGDOUBLE_TYPE long double
 #endif
 typedef sqlite_int64 i64;          /* 8-byte signed integer */
-typedef UINT64_TYPE u64;           /* 8-byte unsigned integer */
+typedef sqlite_uint64 u64;         /* 8-byte unsigned integer */
 typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
 typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
 typedef INT16_TYPE i16;            /* 2-byte signed integer */
@@ -228,60 +240,68 @@
 */
 #include "vdbe.h"
 #include "btree.h"
+#include "pager.h"
 
+#ifdef SQLITE_MEMDEBUG
 /*
-** This macro casts a pointer to an integer.  Useful for doing
-** pointer arithmetic.
+** The following global variables are used for testing and debugging
+** only.  They only work if SQLITE_MEMDEBUG is defined.
 */
-#define Addr(X)  ((uptr)X)
+extern int sqlite3_nMalloc;      /* Number of sqliteMalloc() calls */
+extern int sqlite3_nFree;        /* Number of sqliteFree() calls */
+extern int sqlite3_iMallocFail;  /* Fail sqliteMalloc() after this many calls */
+extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
 
-/*
-** If memory allocation problems are found, recompile with
-**
-**      -DSQLITE_DEBUG=1
-**
-** to enable some sanity checking on malloc() and free().  To
-** check for memory leaks, recompile with
-**
-**      -DSQLITE_DEBUG=2
-**
-** and a line of text will be written to standard error for
-** each malloc() and free().  This output can be analyzed
-** by an AWK script to determine if there are any leaks.
-*/
-#ifdef SQLITE_MEMDEBUG
-# define sqliteMalloc(X)    sqlite3Malloc_(X,1,__FILE__,__LINE__)
-# define sqliteMallocRaw(X) sqlite3Malloc_(X,0,__FILE__,__LINE__)
-# define sqliteFree(X)      sqlite3Free_(X,__FILE__,__LINE__)
-# define sqliteRealloc(X,Y) sqlite3Realloc_(X,Y,__FILE__,__LINE__)
-# define sqliteStrDup(X)    sqlite3StrDup_(X,__FILE__,__LINE__)
-# define sqliteStrNDup(X,Y) sqlite3StrNDup_(X,Y,__FILE__,__LINE__)
+extern void *sqlite3_pFirst;         /* Pointer to linked list of allocations */
+extern int sqlite3_nMaxAlloc;        /* High water mark of ThreadData.nAlloc */
+extern int sqlite3_mallocDisallowed; /* assert() in sqlite3Malloc() if set */
+extern int sqlite3_isFail;           /* True if all malloc calls should fail */
+extern const char *sqlite3_zFile;    /* Filename to associate debug info with */
+extern int sqlite3_iLine;            /* Line number for debug info */
+
+#define ENTER_MALLOC (sqlite3_zFile = __FILE__, sqlite3_iLine = __LINE__)
+#define sqliteMalloc(x)          (ENTER_MALLOC, sqlite3Malloc(x,1))
+#define sqliteMallocRaw(x)       (ENTER_MALLOC, sqlite3MallocRaw(x,1))
+#define sqliteRealloc(x,y)       (ENTER_MALLOC, sqlite3Realloc(x,y))
+#define sqliteStrDup(x)          (ENTER_MALLOC, sqlite3StrDup(x))
+#define sqliteStrNDup(x,y)       (ENTER_MALLOC, sqlite3StrNDup(x,y))
+#define sqliteReallocOrFree(x,y) (ENTER_MALLOC, sqlite3ReallocOrFree(x,y))
+
 #else
-# define sqliteFree          sqlite3FreeX
-# define sqliteMalloc        sqlite3Malloc
-# define sqliteMallocRaw     sqlite3MallocRaw
-# define sqliteRealloc       sqlite3Realloc
-# define sqliteStrDup        sqlite3StrDup
-# define sqliteStrNDup       sqlite3StrNDup
+
+#define ENTER_MALLOC 0
+#define sqliteMalloc(x)          sqlite3Malloc(x,1)
+#define sqliteMallocRaw(x)       sqlite3MallocRaw(x,1)
+#define sqliteRealloc(x,y)       sqlite3Realloc(x,y)
+#define sqliteStrDup(x)          sqlite3StrDup(x)
+#define sqliteStrNDup(x,y)       sqlite3StrNDup(x,y)
+#define sqliteReallocOrFree(x,y) sqlite3ReallocOrFree(x,y)
+
 #endif
 
+#define sqliteFree(x)          sqlite3FreeX(x)
+#define sqliteAllocSize(x)     sqlite3AllocSize(x)
+
+
 /*
-** This variable gets set if malloc() ever fails.  After it gets set,
-** the SQLite library shuts down permanently.
+** An instance of this structure might be allocated to store information
+** specific to a single thread.
 */
-extern int sqlite3_malloc_failed;
+struct ThreadData {
+  int dummy;               /* So that this structure is never empty */
 
-/*
-** The following global variables are used for testing and debugging
-** only.  They only work if SQLITE_DEBUG is defined.
-*/
-#ifdef SQLITE_MEMDEBUG
-extern int sqlite3_nMalloc;      /* Number of sqliteMalloc() calls */
-extern int sqlite3_nFree;        /* Number of sqliteFree() calls */
-extern int sqlite3_iMallocFail;  /* Fail sqliteMalloc() after this many calls */
-extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  int nSoftHeapLimit;      /* Suggested max mem allocation.  No limit if <0 */
+  int nAlloc;              /* Number of bytes currently allocated */
+  Pager *pPager;           /* Linked list of all pagers in this thread */
 #endif
 
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  u8 useSharedData;        /* True if shared pagers and schemas are enabled */
+  BtShared *pBtree;        /* Linked list of all currently open BTrees */
+#endif
+};
+
 /*
 ** Name of the master database table.  The master database table
 ** is a special table that holds the names and attributes of all
@@ -314,6 +334,7 @@
 typedef struct CollSeq CollSeq;
 typedef struct Column Column;
 typedef struct Db Db;
+typedef struct Schema Schema;
 typedef struct Expr Expr;
 typedef struct ExprList ExprList;
 typedef struct FKey FKey;
@@ -326,7 +347,9 @@
 typedef struct Parse Parse;
 typedef struct Select Select;
 typedef struct SrcList SrcList;
+typedef struct ThreadData ThreadData;
 typedef struct Table Table;
+typedef struct TableLock TableLock;
 typedef struct Token Token;
 typedef struct TriggerStack TriggerStack;
 typedef struct TriggerStep TriggerStep;
@@ -344,28 +367,37 @@
 struct Db {
   char *zName;         /* Name of this database */
   Btree *pBt;          /* The B*Tree structure for this database file */
+  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
+  u8 safety_level;     /* How aggressive at synching data to disk */
+  void *pAux;               /* Auxiliary data.  Usually NULL */
+  void (*xFreeAux)(void*);  /* Routine to free pAux */
+  Schema *pSchema;     /* Pointer to database schema (possibly shared) */
+};
+
+/*
+** An instance of the following structure stores a database schema.
+*/
+struct Schema {
   int schema_cookie;   /* Database schema version number for this file */
   Hash tblHash;        /* All tables indexed by name */
   Hash idxHash;        /* All (named) indices indexed by name */
   Hash trigHash;       /* All triggers indexed by name */
   Hash aFKey;          /* Foreign keys indexed by to-table */
-  u16 flags;           /* Flags associated with this database */
-  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
-  u8 safety_level;     /* How aggressive at synching data to disk */
+  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
+  u8 file_format;      /* Schema format version for this file */
+  u8 enc;              /* Text encoding used by this database */
+  u16 flags;           /* Flags associated with this schema */
   int cache_size;      /* Number of pages to use in the cache */
-  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
-  void *pAux;               /* Auxiliary data.  Usually NULL */
-  void (*xFreeAux)(void*);  /* Routine to free pAux */
 };
 
 /*
 ** These macros can be used to test, set, or clear bits in the 
 ** Db.flags field.
 */
-#define DbHasProperty(D,I,P)     (((D)->aDb[I].flags&(P))==(P))
-#define DbHasAnyProperty(D,I,P)  (((D)->aDb[I].flags&(P))!=0)
-#define DbSetProperty(D,I,P)     (D)->aDb[I].flags|=(P)
-#define DbClearProperty(D,I,P)   (D)->aDb[I].flags&=~(P)
+#define DbHasProperty(D,I,P)     (((D)->aDb[I].pSchema->flags&(P))==(P))
+#define DbHasAnyProperty(D,I,P)  (((D)->aDb[I].pSchema->flags&(P))!=0)
+#define DbSetProperty(D,I,P)     (D)->aDb[I].pSchema->flags|=(P)
+#define DbClearProperty(D,I,P)   (D)->aDb[I].pSchema->flags&=~(P)
 
 /*
 ** Allowed values for the DB.flags field.
@@ -379,6 +411,7 @@
 */
 #define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
 #define DB_UnresetViews    0x0002  /* Some views have defined column names */
+#define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */
 
 #define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
 
@@ -413,9 +446,7 @@
   Db *aDb;                      /* All backends */
   int flags;                    /* Miscellanous flags. See below */
   int errCode;                  /* Most recent error code (SQLITE_*) */
-  u8 enc;                       /* Text encoding for this database. */
   u8 autoCommit;                /* The auto-commit flag. */
-  u8 file_format;               /* What file format version is this database? */
   u8 temp_store;                /* 1: file 2: memory 0: default */
   int nTable;                   /* Number of tables in the database */
   CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
@@ -435,12 +466,15 @@
   void *pTraceArg;                          /* Argument to the trace function */
   void (*xProfile)(void*,const char*,u64);  /* Profiling function */
   void *pProfileArg;                        /* Argument to profile function */
-  void *pCommitArg;             /* Argument to xCommitCallback() */   
-  int (*xCommitCallback)(void*);/* Invoked at every commit. */
+  void *pCommitArg;                 /* Argument to xCommitCallback() */   
+  int (*xCommitCallback)(void*);    /* Invoked at every commit. */
+  void *pRollbackArg;               /* Argument to xRollbackCallback() */   
+  void (*xRollbackCallback)(void*); /* Invoked at every commit. */
+  void *pUpdateArg;
+  void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
   void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
   void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
   void *pCollNeededArg;
-  sqlite3_value *pValue;        /* Value used for transient conversions */
   sqlite3_value *pErr;          /* Most recent error message */
   char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
   char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
@@ -468,6 +502,11 @@
 };
 
 /*
+** A macro to discover the encoding of a database.
+*/
+#define ENC(db) ((db)->aDb[0].pSchema->enc)
+
+/*
 ** Possible values for the sqlite.flags and or Db.flags fields.
 **
 ** On sqlite.flags, the SQLITE_InTrans value means that we have
@@ -475,7 +514,6 @@
 ** transaction is active on that particular database file.
 */
 #define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
-#define SQLITE_Initialized    0x00000002  /* True after initialization */
 #define SQLITE_Interrupt      0x00000004  /* Cancel current operation */
 #define SQLITE_InTrans        0x00000008  /* True if in a transaction */
 #define SQLITE_InternChanges  0x00000010  /* Uncommitted Hash table changes */
@@ -491,6 +529,10 @@
 #define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
 #define SQLITE_NoReadlock     0x00001000  /* Readlocks are omitted when 
                                           ** accessing read-only databases */
+#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
+#define SQLITE_ReadUncommitted 0x00004000  /* For shared-cache mode */
+#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
+#define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
 
 /*
 ** Possible values for the sqlite.magic field.
@@ -535,7 +577,7 @@
   char *zName;     /* Name of this column */
   Expr *pDflt;     /* Default value of this column */
   char *zType;     /* Data type for this column */
-  CollSeq *pColl;  /* Collating sequence.  If NULL, use the default */
+  char *zColl;     /* Collating sequence.  If NULL, use the default */
   u8 notNull;      /* True if there is a NOT NULL constraint */
   u8 isPrimKey;    /* True if this column is part of the PRIMARY KEY */
   char affinity;   /* One of the SQLITE_AFF_... values */
@@ -551,7 +593,7 @@
 ** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
 ** native byte order. When a collation sequence is invoked, SQLite selects
 ** the version that will require the least expensive encoding
-** transalations, if any.
+** translations, if any.
 **
 ** The CollSeq.pUser member variable is an extra parameter that passed in
 ** as the first argument to the UTF-8 comparison function, xCmp.
@@ -586,12 +628,25 @@
 
 /*
 ** Column affinity types.
+**
+** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
+** 't' for SQLITE_AFF_TEXT.  But we can save a little space and improve
+** the speed a little by number the values consecutively.  
+**
+** But rather than start with 0 or 1, we begin with 'a'.  That way,
+** when multiple affinity types are concatenated into a string and
+** used as the P3 operand, they will be more readable.
+**
+** Note also that the numeric types are grouped together so that testing
+** for a numeric type is a single comparison.
 */
-#define SQLITE_AFF_INTEGER  'i'
-#define SQLITE_AFF_NUMERIC  'n'
-#define SQLITE_AFF_TEXT     't'
-#define SQLITE_AFF_NONE     'o'
+#define SQLITE_AFF_TEXT     'a'
+#define SQLITE_AFF_NONE     'b'
+#define SQLITE_AFF_NUMERIC  'c'
+#define SQLITE_AFF_INTEGER  'd'
+#define SQLITE_AFF_REAL     'e'
 
+#define sqlite3IsNumericAffinity(X)  ((X)>=SQLITE_AFF_NUMERIC)
 
 /*
 ** Each SQL table is represented in memory by an instance of the
@@ -632,7 +687,6 @@
   int tnum;        /* Root BTree node for this table (see note above) */
   Select *pSelect; /* NULL for tables.  Points to definition if a view. */
   u8 readOnly;     /* True if this table should not be written by the user */
-  u8 iDb;          /* Index into sqlite.aDb[] of the backend for this table */
   u8 isTransient;  /* True if automatically deleted when VDBE finishes */
   u8 hasPrimKey;   /* True if there exists a primary key */
   u8 keyConf;      /* What to do in case of uniqueness conflict on iPKey */
@@ -641,9 +695,13 @@
   Trigger *pTrigger; /* List of SQL triggers on this table */
   FKey *pFKey;       /* Linked list of all foreign keys in this table */
   char *zColAff;     /* String defining the affinity of each column */
+#ifndef SQLITE_OMIT_CHECK
+  Expr *pCheck;      /* The AND of all CHECK constraints */
+#endif
 #ifndef SQLITE_OMIT_ALTERTABLE
   int addColOffset;  /* Offset in CREATE TABLE statement to add a new column */
 #endif
+  Schema *pSchema;
 };
 
 /*
@@ -779,10 +837,11 @@
   int tnum;        /* Page containing root of this index in database file */
   u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
   u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
-  u8 iDb;          /* Index in sqlite.aDb[] of where this index is stored */
   char *zColAff;   /* String defining the affinity of each column */
   Index *pNext;    /* The next index associated with the same table */
-  KeyInfo keyInfo; /* Info on how to order keys.  MUST BE LAST */
+  Schema *pSchema; /* Schema containing this index */
+  u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
+  char **azColl;   /* Array of collation sequence names for index */
 };
 
 /*
@@ -891,7 +950,6 @@
 struct Expr {
   u8 op;                 /* Operation performed by this node */
   char affinity;         /* The affinity of the column or 0 if not a column */
-  u8 iDb;                /* Database referenced by this expression */
   u8 flags;              /* Various flags.  See below */
   CollSeq *pColl;        /* The collation type of the column or 0 */
   Expr *pLeft, *pRight;  /* Left and right subnodes */
@@ -907,6 +965,7 @@
   Select *pSelect;       /* When the expression is a sub-select.  Also the
                          ** right side of "<expr> IN (<select>)" */
   Table *pTab;           /* Table for OP_Column expressions. */
+  Schema *pSchema;
 };
 
 /*
@@ -999,6 +1058,7 @@
     char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
     Table *pTab;      /* An SQL table corresponding to zName */
     Select *pSelect;  /* A SELECT statement used in place of a table name */
+    u8 isPopulated;   /* Temporary table associated with SELECT is populated */
     u8 jointype;      /* Type of join between this table and the next */
     i16 iCursor;      /* The VDBE cursor number used to access this table */
     Expr *pOn;        /* The ON clause of a join */
@@ -1087,6 +1147,7 @@
   int nErr;            /* Number of errors encountered while resolving names */
   u8 allowAgg;         /* Aggregate functions allowed here */
   u8 hasAgg;           /* True if aggregates are seen */
+  u8 isCheck;          /* True if resolving names in a CHECK constraint */
   int nDepth;          /* Depth of subquery recursion. 1 for no recursion */
   AggInfo *pAggInfo;   /* Information about aggregates at this level */
   NameContext *pNext;  /* Next outer name context.  NULL for outermost */
@@ -1149,7 +1210,7 @@
 #define SRT_Table        7  /* Store result as data with an automatic rowid */
 #define SRT_VirtualTab   8  /* Create virtual table and store like SRT_Table */
 #define SRT_Subroutine   9  /* Call a subroutine to handle results */
-#define SRT_Exists      10  /* Put 0 or 1 in a memory cell */
+#define SRT_Exists      10  /* Store 1 if the result is not empty */
 
 /*
 ** An SQL parser context.  A copy of this structure is passed through
@@ -1160,6 +1221,12 @@
 ** generate call themselves recursively, the first part of the structure
 ** is constant but the second part is reset at the beginning and end of
 ** each recursion.
+**
+** The nTableLock and aTableLock variables are only used if the shared-cache 
+** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
+** used to store the set of table-locks required by the statement being
+** compiled. Function sqlite3TableLock() is used to add entries to the
+** list.
 */
 struct Parse {
   sqlite3 *db;         /* The main database structure */
@@ -1174,10 +1241,15 @@
   int nTab;            /* Number of previously allocated VDBE cursors */
   int nMem;            /* Number of memory cells used so far */
   int nSet;            /* Number of sets used so far */
+  int ckOffset;        /* Stack offset to data used by CHECK constraints */
   u32 writeMask;       /* Start a write transaction on these databases */
   u32 cookieMask;      /* Bitmask of schema verified databases */
   int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
   int cookieValue[MAX_ATTACHED+2];  /* Values of cookies to verify */
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  int nTableLock;        /* Number of locks in aTableLock */
+  TableLock *aTableLock; /* Required table locks for shared-cache mode */
+#endif
 
   /* Above is constant between recursions.  Below is reset before and after
   ** each recursion */
@@ -1212,6 +1284,7 @@
 */
 #define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
 #define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */
+#define OPFLAG_ISUPDATE  4    /* This OP_Insert is an sql UPDATE */
 
 /*
  * Each trigger present in the database schema is stored as an instance of
@@ -1231,8 +1304,6 @@
 struct Trigger {
   char *name;             /* The name of the trigger                        */
   char *table;            /* The table or view to which the trigger applies */
-  u8 iDb;                 /* Database containing this trigger               */
-  u8 iTabDb;              /* Database containing Trigger.table              */
   u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
   u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
   Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
@@ -1240,7 +1311,8 @@
                              the <column-list> is stored here */
   int foreach;            /* One of TK_ROW or TK_STATEMENT */
   Token nameToken;        /* Token containing zName. Use during parsing only */
-
+  Schema *pSchema;        /* Schema containing the trigger */
+  Schema *pTabSchema;     /* Schema containing the table */
   TriggerStep *step_list; /* Link list of trigger program steps             */
   Trigger *pNext;         /* Next trigger associated with the table */
 };
@@ -1305,8 +1377,8 @@
   ExprList *pExprList; /* Valid for UPDATE statements and sometimes 
 			   INSERT steps (when pSelect == 0)         */
   IdList *pIdList;     /* Valid for INSERT statements only */
-
-  TriggerStep * pNext; /* Next in the link-list */
+  TriggerStep *pNext;  /* Next in the link-list */
+  TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
 };
 
 /*
@@ -1398,35 +1470,29 @@
 int sqlite3Compare(const char *, const char *);
 int sqlite3SortCompare(const char *, const char *);
 void sqlite3RealToSortable(double r, char *);
-#ifdef SQLITE_MEMDEBUG
-  void *sqlite3Malloc_(int,int,char*,int);
-  void sqlite3Free_(void*,char*,int);
-  void *sqlite3Realloc_(void*,int,char*,int);
-  char *sqlite3StrDup_(const char*,char*,int);
-  char *sqlite3StrNDup_(const char*, int,char*,int);
-  void sqlite3CheckMemory(void*,int);
-#else
-  void *sqlite3Malloc(int);
-  void *sqlite3MallocRaw(int);
-  void sqlite3Free(void*);
-  void *sqlite3Realloc(void*,int);
-  char *sqlite3StrDup(const char*);
-  char *sqlite3StrNDup(const char*, int);
+
+void *sqlite3Malloc(int,int);
+void *sqlite3MallocRaw(int,int);
+void sqlite3Free(void*);
+void *sqlite3Realloc(void*,int);
+char *sqlite3StrDup(const char*);
+char *sqlite3StrNDup(const char*, int);
 # define sqlite3CheckMemory(a,b)
-# define sqlite3MallocX sqlite3Malloc
-#endif
 void sqlite3ReallocOrFree(void**,int);
 void sqlite3FreeX(void*);
 void *sqlite3MallocX(int);
+int sqlite3AllocSize(void *);
+
 char *sqlite3MPrintf(const char*, ...);
 char *sqlite3VMPrintf(const char*, va_list);
 void sqlite3DebugPrintf(const char*, ...);
 void *sqlite3TextToPtr(const char*);
 void sqlite3SetString(char **, ...);
 void sqlite3ErrorMsg(Parse*, const char*, ...);
+void sqlite3ErrorClear(Parse*);
 void sqlite3Dequote(char*);
 void sqlite3DequoteExpr(Expr*);
-int sqlite3KeywordCode(const char*, int);
+int sqlite3KeywordCode(const unsigned char*, int);
 int sqlite3RunParser(Parse*, const char*, char **);
 void sqlite3FinishCoding(Parse*);
 Expr *sqlite3Expr(int, Expr*, Expr*, const Token*);
@@ -1446,11 +1512,12 @@
 void sqlite3RollbackInternalChanges(sqlite3*);
 void sqlite3CommitInternalChanges(sqlite3*);
 Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
-void sqlite3OpenMasterTable(Vdbe *v, int);
-void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
+void sqlite3OpenMasterTable(Parse *, int);
+void sqlite3StartTable(Parse*,Token*,Token*,int,int,int);
 void sqlite3AddColumn(Parse*,Token*);
 void sqlite3AddNotNull(Parse*, int);
-void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int);
+void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
+void sqlite3AddCheckConstraint(Parse*, Expr*);
 void sqlite3AddColumnType(Parse*,Token*);
 void sqlite3AddDefaultValue(Parse*,Expr*);
 void sqlite3AddCollateType(Parse*, const char*, int);
@@ -1463,7 +1530,7 @@
 # define sqlite3ViewGetColumnNames(A,B) 0
 #endif
 
-void sqlite3DropTable(Parse*, SrcList*, int);
+void sqlite3DropTable(Parse*, SrcList*, int, int);
 void sqlite3DeleteTable(sqlite3*, Table*);
 void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
 int sqlite3ArrayAllocate(void**,int,int);
@@ -1475,8 +1542,8 @@
 void sqlite3IdListDelete(IdList*);
 void sqlite3SrcListDelete(SrcList*);
 void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
-                        Token*);
-void sqlite3DropIndex(Parse*, SrcList*);
+                        Token*, int, int);
+void sqlite3DropIndex(Parse*, SrcList*, int);
 void sqlite3AddKeyType(Vdbe*, ExprList*);
 void sqlite3AddIdxKeyType(Vdbe*, Index*);
 int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
@@ -1486,8 +1553,7 @@
 void sqlite3SelectUnbind(Select*);
 Table *sqlite3SrcListLookup(Parse*, SrcList*);
 int sqlite3IsReadOnly(Parse*, Table*, int);
-void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*);
-void sqlite3OpenTable(Vdbe*, int iCur, Table*, int);
+void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
 void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
 void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
 WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
@@ -1503,7 +1569,7 @@
 Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
 void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
 void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
-void sqlite3Vacuum(Parse*, Token*);
+void sqlite3Vacuum(Parse*);
 int sqlite3RunVacuum(char**, sqlite3*);
 char *sqlite3NameFromToken(Token*);
 int sqlite3ExprCheck(Parse*, Expr*, int, int*);
@@ -1524,7 +1590,7 @@
 int sqlite3ExprIsInteger(Expr*, int*);
 int sqlite3IsRowid(const char*);
 void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
-void sqlite3GenerateRowIndexDelete(sqlite3*, Vdbe*, Table*, int, char*);
+void sqlite3GenerateRowIndexDelete(Vdbe*, Table*, int, char*);
 void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
 void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
@@ -1549,7 +1615,7 @@
                            int,Expr*,int);
   void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
   void sqlite3DropTrigger(Parse*, SrcList*);
-  void sqlite3DropTriggerPtr(Parse*, Trigger*, int);
+  void sqlite3DropTriggerPtr(Parse*, Trigger*);
   int sqlite3TriggersExist(Parse*, Table*, int, ExprList*);
   int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, 
                            int, int);
@@ -1564,7 +1630,7 @@
 #else
 # define sqlite3TriggersExist(A,B,C,D,E,F) 0
 # define sqlite3DeleteTrigger(A)
-# define sqlite3DropTriggerPtr(A,B,C)
+# define sqlite3DropTriggerPtr(A,B)
 # define sqlite3UnlinkAndDeleteTrigger(A,B,C)
 # define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) 0
 #endif
@@ -1583,8 +1649,8 @@
 # define sqlite3AuthContextPush(a,b,c)
 # define sqlite3AuthContextPop(a)  ((void)(a))
 #endif
-void sqlite3Attach(Parse*, Token*, Token*, int, Token*);
-void sqlite3Detach(Parse*, Token*);
+void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
+void sqlite3Detach(Parse*, Expr*);
 int sqlite3BtreeFactory(const sqlite3 *db, const char *zFilename,
                        int omitJournal, int nCache, Btree **ppBtree);
 int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
@@ -1630,7 +1696,7 @@
 void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*));
 void sqlite3ValueFree(sqlite3_value*);
 sqlite3_value *sqlite3ValueNew(void);
-sqlite3_value *sqlite3GetTransientValue(sqlite3*db);
+char *sqlite3utf16to8(const void*, int);
 int sqlite3ValueFromExpr(Expr *, u8, u8, sqlite3_value **);
 void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
 extern const unsigned char sqlite3UpperToLower[];
@@ -1656,7 +1722,48 @@
 void sqlite3DefaultRowEst(Index*);
 void sqlite3RegisterLikeFunctions(sqlite3*, int);
 int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
+ThreadData *sqlite3ThreadData(void);
+const ThreadData *sqlite3ThreadDataReadOnly(void);
+void sqlite3ReleaseThreadData(void);
+void sqlite3AttachFunctions(sqlite3 *);
+void sqlite3MinimumFileFormat(Parse*, int, int);
+void sqlite3SchemaFree(void *);
+Schema *sqlite3SchemaGet(Btree *);
+int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
+KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
+int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
+  void (*)(sqlite3_context*,int,sqlite3_value **),
+  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
+int sqlite3ApiExit(sqlite3 *db, int);
+int sqlite3MallocFailed(void);
+void sqlite3FailedMalloc(void);
+void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *);
+int sqlite3OpenTempDatabase(Parse *);
 
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  void sqlite3TableLock(Parse *, int, int, u8, const char *);
+#else
+  #define sqlite3TableLock(v,w,x,y,z)
+#endif
+
+#ifdef SQLITE_MEMDEBUG
+  void sqlite3MallocDisallow(void);
+  void sqlite3MallocAllow(void);
+  int sqlite3TestMallocFail(void);
+#else
+  #define sqlite3TestMallocFail() 0
+  #define sqlite3MallocDisallow()
+  #define sqlite3MallocAllow()
+#endif
+
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  void *sqlite3ThreadSafeMalloc(int);
+  void sqlite3ThreadSafeFree(void *);
+#else
+  #define sqlite3ThreadSafeMalloc sqlite3MallocX
+  #define sqlite3ThreadSafeFree sqlite3FreeX
+#endif
+
 #ifdef SQLITE_SSE
 #include "sseInt.h"
 #endif

Copied: packages/libdbd-sqlite3-perl/trunk/t/._04select.t (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/t/._04select.t)

Copied: packages/libdbd-sqlite3-perl/trunk/t/._05tran.t (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/t/._05tran.t)

Copied: packages/libdbd-sqlite3-perl/trunk/t/._40blobtext.t (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/t/._40blobtext.t)

Copied: packages/libdbd-sqlite3-perl/trunk/t/07busy.t (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/t/07busy.t)

Copied: packages/libdbd-sqlite3-perl/trunk/t/11unicode.t (from rev 2604, packages/libdbd-sqlite3-perl/branches/upstream/current/t/11unicode.t)

Modified: packages/libdbd-sqlite3-perl/trunk/table.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/table.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/table.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -16,10 +16,12 @@
 ** These routines are in a separate files so that they will not be linked
 ** if they are not used.
 */
+#include "sqliteInt.h"
 #include <stdlib.h>
 #include <string.h>
-#include "sqliteInt.h"
 
+#ifndef SQLITE_OMIT_GET_TABLE
+
 /*
 ** This structure is used to pass data from sqlite3_get_table() through
 ** to the callback function is uses to build the result.
@@ -143,6 +145,7 @@
   res.azResult[0] = 0;
   rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
   if( res.azResult ){
+    assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
     res.azResult[0] = (char*)res.nData;
   }
   if( rc==SQLITE_ABORT ){
@@ -193,3 +196,5 @@
     free(azResult);
   }
 }
+
+#endif /* SQLITE_OMIT_GET_TABLE */

Modified: packages/libdbd-sqlite3-perl/trunk/tokenize.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/tokenize.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/tokenize.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -15,7 +15,7 @@
 ** individual tokens and sends those tokens one-by-one over to the
 ** parser for analysis.
 **
-** $Id: tokenize.c,v 1.107 2005/08/23 11:31:26 drh Exp $
+** $Id: tokenize.c,v 1.118 2006/04/04 01:54:55 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -23,6 +23,39 @@
 #include <stdlib.h>
 
 /*
+** The charMap() macro maps alphabetic characters into their
+** lower-case ASCII equivalent.  On ASCII machines, this is just
+** an upper-to-lower case map.  On EBCDIC machines we also need
+** to adjust the encoding.  Only alphabetic characters and underscores
+** need to be translated.
+*/
+#ifdef SQLITE_ASCII
+# define charMap(X) sqlite3UpperToLower[(unsigned char)X]
+#endif
+#ifdef SQLITE_EBCDIC
+# define charMap(X) ebcdicToAscii[(unsigned char)X]
+const unsigned char ebcdicToAscii[] = {
+/* 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 0x */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 1x */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 2x */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 3x */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 4x */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 5x */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 95,  0,  0,  /* 6x */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 7x */
+   0, 97, 98, 99,100,101,102,103,104,105,  0,  0,  0,  0,  0,  0,  /* 8x */
+   0,106,107,108,109,110,111,112,113,114,  0,  0,  0,  0,  0,  0,  /* 9x */
+   0,  0,115,116,117,118,119,120,121,122,  0,  0,  0,  0,  0,  0,  /* Ax */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* Bx */
+   0, 97, 98, 99,100,101,102,103,104,105,  0,  0,  0,  0,  0,  0,  /* Cx */
+   0,106,107,108,109,110,111,112,113,114,  0,  0,  0,  0,  0,  0,  /* Dx */
+   0,  0,115,116,117,118,119,120,121,122,  0,  0,  0,  0,  0,  0,  /* Ex */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* Fx */
+};
+#endif
+
+/*
 ** The sqlite3KeywordCode function looks up an identifier to determine if
 ** it is a keyword.  If it is a keyword, the token code of that keyword is 
 ** returned.  If the input is not a keyword, TK_ID is returned.
@@ -37,24 +70,22 @@
 
 
 /*
-** If X is a character that can be used in an identifier and
-** X&0x80==0 then sqlite3IsIdChar[X] will be 1.  If X&0x80==0x80 then
-** X is always an identifier character.  (Hence all UTF-8
-** characters can be part of an identifier).  sqlite3IsIdChar[X] will
-** be 0 for every character in the lower 128 ASCII characters
-** that cannot be used as part of an identifier.
+** If X is a character that can be used in an identifier then
+** IdChar(X) will be true.  Otherwise it is false.
 **
-** In this implementation, an identifier can be a string of
-** alphabetic characters, digits, and "_" plus any character
-** with the high-order bit set.  The latter rule means that
-** any sequence of UTF-8 characters or characters taken from
-** an extended ISO8859 character set can form an identifier.
+** For ASCII, any character with the high-order bit set is
+** allowed in an identifier.  For 7-bit characters, 
+** sqlite3IsIdChar[X] must be 1.
 **
+** For EBCDIC, the rules are more complex but have the same
+** end result.
+**
 ** Ticket #1066.  the SQL standard does not allow '$' in the
 ** middle of identfiers.  But many SQL implementations do. 
 ** SQLite will allow '$' in identifiers for compatibility.
 ** But the feature is undocumented.
 */
+#ifdef SQLITE_ASCII
 const char sqlite3IsIdChar[] = {
 /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
@@ -64,9 +95,28 @@
     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
 };
-
 #define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20]))
+#endif
+#ifdef SQLITE_EBCDIC
+const char sqlite3IsIdChar[] = {
+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 4x */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0,  /* 5x */
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0,  /* 6x */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,  /* 7x */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0,  /* 8x */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0,  /* 9x */
+    1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0,  /* Ax */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* Bx */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Cx */
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Dx */
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Ex */
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,  /* Fx */
+};
+#define IdChar(C)  (((c=C)>=0x42 && sqlite3IsIdChar[c-0x40]))
+#endif
 
+
 /*
 ** Return the length of the token that begins at z[0]. 
 ** Store the token type in *tokenType before returning.
@@ -196,9 +246,13 @@
           }
         }
       }
-      if( c ) i++;
-      *tokenType = TK_STRING;
-      return i;
+      if( c ){
+        *tokenType = TK_STRING;
+        return i+1;
+      }else{
+        *tokenType = TK_ILLEGAL;
+        return i;
+      }
     }
     case '.': {
 #ifndef SQLITE_OMIT_FLOATING_POINT
@@ -257,6 +311,7 @@
 #ifndef SQLITE_OMIT_TCL_VARIABLE
     case '$':
 #endif
+    case '@':  /* For compatibility with MS SQL Server */
     case ':': {
       int n = 0;
       *tokenType = TK_VARIABLE;
@@ -344,7 +399,6 @@
   i = 0;
   pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX);
   if( pEngine==0 ){
-    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
     return SQLITE_NOMEM;
   }
   assert( pParse->sLastToken.dyn==0 );
@@ -355,9 +409,9 @@
   assert( pParse->nVarExprAlloc==0 );
   assert( pParse->apVarExpr==0 );
   pParse->zTail = pParse->zSql = zSql;
-  while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
+  while( !sqlite3MallocFailed() && zSql[i]!=0 ){
     assert( i>=0 );
-    pParse->sLastToken.z = &zSql[i];
+    pParse->sLastToken.z = (u8*)&zSql[i];
     assert( pParse->sLastToken.dyn==0 );
     pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
     i += pParse->sLastToken.n;
@@ -403,12 +457,11 @@
     sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
   }
   sqlite3ParserFree(pEngine, sqlite3FreeX);
-  if( sqlite3_malloc_failed ){
+  if( sqlite3MallocFailed() ){
     pParse->rc = SQLITE_NOMEM;
   }
   if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
-    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc),
-                    (char*)0);
+    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
   }
   if( pParse->zErrMsg ){
     if( pzErrMsg && *pzErrMsg==0 ){
@@ -423,6 +476,13 @@
     sqlite3VdbeDelete(pParse->pVdbe);
     pParse->pVdbe = 0;
   }
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  if( pParse->nested==0 ){
+    sqliteFree(pParse->aTableLock);
+    pParse->aTableLock = 0;
+    pParse->nTableLock = 0;
+  }
+#endif
   sqlite3DeleteTable(pParse->db, pParse->pNewTable);
   sqlite3DeleteTrigger(pParse->pNewTrigger);
   sqliteFree(pParse->apVarExpr);

Modified: packages/libdbd-sqlite3-perl/trunk/trigger.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/trigger.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/trigger.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -58,10 +58,13 @@
   int iDb;                /* The database to store the trigger in */
   Token *pName;           /* The unqualified db name */
   DbFixer sFix;
+  int iTabDb;
 
+  assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
+  assert( pName2!=0 );
   if( isTemp ){
     /* If TEMP was specified, then the trigger name may not be qualified. */
-    if( pName2 && pName2->n>0 ){
+    if( pName2->n>0 ){
       sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
       goto trigger_cleanup;
     }
@@ -80,14 +83,16 @@
   ** If sqlite3SrcListLookup() returns 0, indicating the table does not
   ** exist, the error is caught by the block below.
   */
-  if( !pTableName || sqlite3_malloc_failed ) goto trigger_cleanup;
+  if( !pTableName || sqlite3MallocFailed() ){
+    goto trigger_cleanup;
+  }
   pTab = sqlite3SrcListLookup(pParse, pTableName);
-  if( pName2->n==0 && pTab && pTab->iDb==1 ){
+  if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
     iDb = 1;
   }
 
   /* Ensure the table name matches database name and that the table exists */
-  if( sqlite3_malloc_failed ) goto trigger_cleanup;
+  if( sqlite3MallocFailed() ) goto trigger_cleanup;
   assert( pTableName->nSrc==1 );
   if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
       sqlite3FixSrcList(&sFix, pTableName) ){
@@ -105,7 +110,7 @@
   if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
     goto trigger_cleanup;
   }
-  if( sqlite3HashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
+  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
     sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
     goto trigger_cleanup;
   }
@@ -130,17 +135,18 @@
         " trigger on table: %S", pTableName, 0);
     goto trigger_cleanup;
   }
+  iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
 
 #ifndef SQLITE_OMIT_AUTHORIZATION
   {
     int code = SQLITE_CREATE_TRIGGER;
-    const char *zDb = db->aDb[pTab->iDb].zName;
+    const char *zDb = db->aDb[iTabDb].zName;
     const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
-    if( pTab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
+    if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
     if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
       goto trigger_cleanup;
     }
-    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(pTab->iDb),0,zDb)){
+    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
       goto trigger_cleanup;
     }
   }
@@ -161,8 +167,8 @@
   pTrigger->name = zName;
   zName = 0;
   pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
-  pTrigger->iDb = iDb;
-  pTrigger->iTabDb = pTab->iDb;
+  pTrigger->pSchema = db->aDb[iDb].pSchema;
+  pTrigger->pTabSchema = pTab->pSchema;
   pTrigger->op = op;
   pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
   pTrigger->pWhen = sqlite3ExprDup(pWhen);
@@ -196,16 +202,18 @@
   Trigger *pTrig = 0;     /* The trigger whose construction is finishing up */
   sqlite3 *db = pParse->db;  /* The database */
   DbFixer sFix;
+  int iDb;                   /* Database containing the trigger */
 
   pTrig = pParse->pNewTrigger;
   pParse->pNewTrigger = 0;
-  if( pParse->nErr || pTrig==0 ) goto triggerfinish_cleanup;
+  if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
+  iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
   pTrig->step_list = pStepList;
   while( pStepList ){
     pStepList->pTrig = pTrig;
     pStepList = pStepList->pNext;
   }
-  if( sqlite3FixInit(&sFix, pParse, pTrig->iDb, "trigger", &pTrig->nameToken) 
+  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &pTrig->nameToken) 
           && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
     goto triggerfinish_cleanup;
   }
@@ -223,7 +231,7 @@
       { OP_String8,    0, 0,  "CREATE TRIGGER "},
       { OP_String8,    0, 0,  0          },  /* 6: SQL */
       { OP_Concat,     0, 0,  0          }, 
-      { OP_MakeRecord, 5, 0,  "tttit"    },
+      { OP_MakeRecord, 5, 0,  "aaada"    },
       { OP_Insert,     0, 0,  0          },
     };
     int addr;
@@ -232,28 +240,30 @@
     /* Make an entry in the sqlite_master table */
     v = sqlite3GetVdbe(pParse);
     if( v==0 ) goto triggerfinish_cleanup;
-    sqlite3BeginWriteOperation(pParse, 0, pTrig->iDb);
-    sqlite3OpenMasterTable(v, pTrig->iDb);
+    sqlite3BeginWriteOperation(pParse, 0, iDb);
+    sqlite3OpenMasterTable(pParse, iDb);
     addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
     sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0); 
     sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0); 
-    sqlite3VdbeChangeP3(v, addr+6, pAll->z, pAll->n);
-    sqlite3ChangeCookie(db, v, pTrig->iDb);
+    sqlite3VdbeChangeP3(v, addr+6, (char*)pAll->z, pAll->n);
+    sqlite3ChangeCookie(db, v, iDb);
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
-    sqlite3VdbeOp3(v, OP_ParseSchema, pTrig->iDb, 0, 
+    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, 
        sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC);
   }
 
   if( db->init.busy ){
+    int n;
     Table *pTab;
     Trigger *pDel;
-    pDel = sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash, 
-                     pTrig->name, strlen(pTrig->name)+1, pTrig);
+    pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, 
+                     pTrig->name, strlen(pTrig->name), pTrig);
     if( pDel ){
-      assert( sqlite3_malloc_failed && pDel==pTrig );
+      assert( sqlite3MallocFailed() && pDel==pTrig );
       goto triggerfinish_cleanup;
     }
-    pTab = sqlite3LocateTable(pParse,pTrig->table,db->aDb[pTrig->iTabDb].zName);
+    n = strlen(pTrig->table) + 1;
+    pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
     assert( pTab!=0 );
     pTrig->pNext = pTab->pTrigger;
     pTab->pTrigger = pTrig;
@@ -278,7 +288,7 @@
 */
 static void sqlitePersistTriggerStep(TriggerStep *p){
   if( p->target.z ){
-    p->target.z = sqliteStrNDup(p->target.z, p->target.n);
+    p->target.z = (u8*)sqliteStrNDup((char*)p->target.z, p->target.n);
     p->target.dyn = 1;
   }
   if( p->pSelect ){
@@ -312,7 +322,10 @@
 */
 TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
   TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
-  if( pTriggerStep==0 ) return 0;
+  if( pTriggerStep==0 ) {
+    sqlite3SelectDelete(pSelect);
+    return 0;
+  }
 
   pTriggerStep->op = TK_SELECT;
   pTriggerStep->pSelect = pSelect;
@@ -430,7 +443,7 @@
   int nName;
   sqlite3 *db = pParse->db;
 
-  if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
+  if( sqlite3MallocFailed() ) goto drop_trigger_cleanup;
   if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
     goto drop_trigger_cleanup;
   }
@@ -442,14 +455,14 @@
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
     if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
-    pTrigger = sqlite3HashFind(&(db->aDb[j].trigHash), zName, nName+1);
+    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
     if( pTrigger ) break;
   }
   if( !pTrigger ){
     sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
     goto drop_trigger_cleanup;
   }
-  sqlite3DropTriggerPtr(pParse, pTrigger, 0);
+  sqlite3DropTriggerPtr(pParse, pTrigger);
 
 drop_trigger_cleanup:
   sqlite3SrcListDelete(pName);
@@ -459,27 +472,26 @@
 ** Return a pointer to the Table structure for the table that a trigger
 ** is set on.
 */
-static Table *tableOfTrigger(sqlite3 *db, Trigger *pTrigger){
-  return sqlite3FindTable(db,pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
+static Table *tableOfTrigger(Trigger *pTrigger){
+  int n = strlen(pTrigger->table) + 1;
+  return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
 }
 
 
 /*
-** Drop a trigger given a pointer to that trigger.  If nested is false,
-** then also generate code to remove the trigger from the SQLITE_MASTER
-** table.
+** Drop a trigger given a pointer to that trigger. 
 */
-void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
+void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
   Table   *pTable;
   Vdbe *v;
   sqlite3 *db = pParse->db;
   int iDb;
 
-  iDb = pTrigger->iDb;
+  iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
   assert( iDb>=0 && iDb<db->nDb );
-  pTable = tableOfTrigger(db, pTrigger);
-  assert(pTable);
-  assert( pTable->iDb==iDb || iDb==1 );
+  pTable = tableOfTrigger(pTrigger);
+  assert( pTable );
+  assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
 #ifndef SQLITE_OMIT_AUTHORIZATION
   {
     int code = SQLITE_DROP_TRIGGER;
@@ -495,7 +507,8 @@
 
   /* Generate code to destroy the database record of the trigger.
   */
-  if( pTable!=0 && (v = sqlite3GetVdbe(pParse))!=0 ){
+  assert( pTable!=0 );
+  if( (v = sqlite3GetVdbe(pParse))!=0 ){
     int base;
     static const VdbeOpList dropTrigger[] = {
       { OP_Rewind,     0, ADDR(9),  0},
@@ -510,7 +523,7 @@
     };
 
     sqlite3BeginWriteOperation(pParse, 0, iDb);
-    sqlite3OpenMasterTable(v, iDb);
+    sqlite3OpenMasterTable(pParse, iDb);
     base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
     sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
     sqlite3ChangeCookie(db, v, iDb);
@@ -525,9 +538,10 @@
 void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
   Trigger *pTrigger;
   int nName = strlen(zName);
-  pTrigger = sqlite3HashInsert(&(db->aDb[iDb].trigHash), zName, nName+1, 0);
+  pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash),
+                               zName, nName, 0);
   if( pTrigger ){
-    Table *pTable = tableOfTrigger(db, pTrigger);
+    Table *pTable = tableOfTrigger(pTrigger);
     assert( pTable!=0 );
     if( pTable->pTrigger == pTrigger ){
       pTable->pTrigger = pTrigger->pNext;
@@ -585,14 +599,7 @@
 
   while( pTrigger ){
     if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
-      TriggerStack *ss;
-      ss = pParse->trigStack;
-      while( ss && ss->pTrigger!=pTab->pTrigger ){
-	ss = ss->pNext;
-      }
-      if( ss==0 ){
-        mask |= pTrigger->tr_tm;
-      }
+      mask |= pTrigger->tr_tm;
     }
     pTrigger = pTrigger->pNext;
   }
@@ -617,11 +624,11 @@
   int iDb;             /* Index of the database to use */
   SrcList *pSrc;       /* SrcList to be returned */
 
-  iDb = pStep->pTrig->iDb;
+  iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
   if( iDb==0 || iDb>=2 ){
     assert( iDb<pParse->db->nDb );
-    sDb.z = pParse->db->aDb[iDb].zName;
-    sDb.n = strlen(sDb.z);
+    sDb.z = (u8*)pParse->db->aDb[iDb].zName;
+    sDb.n = strlen((char*)sDb.z);
     pSrc = sqlite3SrcListAppend(0, &sDb, &pStep->target);
   } else {
     pSrc = sqlite3SrcListAppend(0, &pStep->target, 0);
@@ -730,8 +737,7 @@
   int orconf,          /* ON CONFLICT policy */
   int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
 ){
-  Trigger *pTrigger;
-  TriggerStack *pStack;
+  Trigger *p;
   TriggerStack trigStackEntry;
 
   assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
@@ -739,22 +745,28 @@
 
   assert(newIdx != -1 || oldIdx != -1);
 
-  pTrigger = pTab->pTrigger;
-  while( pTrigger ){
+  for(p=pTab->pTrigger; p; p=p->pNext){
     int fire_this = 0;
 
-    /* determine whether we should code this trigger */
-    if( pTrigger->op == op && pTrigger->tr_tm == tr_tm ){
-      fire_this = 1;
-      for(pStack=pParse->trigStack; pStack; pStack=pStack->pNext){
-        if( pStack->pTrigger==pTrigger ){
-	  fire_this = 0;
-	}
+    /* Determine whether we should code this trigger */
+    if( 
+      p->op==op && 
+      p->tr_tm==tr_tm && 
+      (p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema) &&
+      (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges))
+    ){
+      TriggerStack *pS;      /* Pointer to trigger-stack entry */
+      for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){}
+      if( !pS ){
+        fire_this = 1;
       }
-      if( op == TK_UPDATE && pTrigger->pColumns &&
-          !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
-        fire_this = 0;
+#if 0    /* Give no warning for recursive triggers.  Just do not do them */
+      else{
+        sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)",
+            p->name);
+        return SQLITE_ERROR;
       }
+#endif
     }
  
     if( fire_this ){
@@ -767,18 +779,18 @@
       sNC.pParse = pParse;
 
       /* Push an entry on to the trigger stack */
-      trigStackEntry.pTrigger = pTrigger;
+      trigStackEntry.pTrigger = p;
       trigStackEntry.newIdx = newIdx;
       trigStackEntry.oldIdx = oldIdx;
       trigStackEntry.pTab = pTab;
       trigStackEntry.pNext = pParse->trigStack;
       trigStackEntry.ignoreJump = ignoreJump;
       pParse->trigStack = &trigStackEntry;
-      sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);
+      sqlite3AuthContextPush(pParse, &sContext, p->name);
 
       /* code the WHEN clause */
       endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
-      whenExpr = sqlite3ExprDup(pTrigger->pWhen);
+      whenExpr = sqlite3ExprDup(p->pWhen);
       if( sqlite3ExprResolveNames(&sNC, whenExpr) ){
         pParse->trigStack = trigStackEntry.pNext;
         sqlite3ExprDelete(whenExpr);
@@ -787,7 +799,7 @@
       sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
       sqlite3ExprDelete(whenExpr);
 
-      codeTriggerProgram(pParse, pTrigger->step_list, orconf); 
+      codeTriggerProgram(pParse, p->step_list, orconf); 
 
       /* Pop the entry off the trigger stack */
       pParse->trigStack = trigStackEntry.pNext;
@@ -795,7 +807,6 @@
 
       sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
     }
-    pTrigger = pTrigger->pNext;
   }
   return 0;
 }

Modified: packages/libdbd-sqlite3-perl/trunk/update.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/update.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/update.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,13 +12,13 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.112 2005/09/20 17:42:23 drh Exp $
+** $Id: update.c,v 1.123 2006/02/24 02:53:50 drh Exp $
 */
 #include "sqliteInt.h"
 
 /*
-** The most recently coded instruction was an OP_Column to retrieve column
-** 'i' of table pTab. This routine sets the P3 parameter of the 
+** The most recently coded instruction was an OP_Column to retrieve the
+** i-th column of table pTab. This routine sets the P3 parameter of the 
 ** OP_Column to the default value, if any.
 **
 ** The default value of a column is specified by a DEFAULT clause in the 
@@ -44,7 +44,7 @@
 void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
   if( pTab && !pTab->pSelect ){
     sqlite3_value *pValue;
-    u8 enc = sqlite3VdbeDb(v)->enc;
+    u8 enc = ENC(sqlite3VdbeDb(v));
     Column *pCol = &pTab->aCol[i];
     sqlite3ValueFromExpr(pCol->pDflt, enc, pCol->affinity, &pValue);
     if( pValue ){
@@ -89,6 +89,7 @@
   int openAll = 0;       /* True if all indices need to be opened */
   AuthContext sContext;  /* The authorization context */
   NameContext sNC;       /* The name-context to resolve expressions in */
+  int iDb;               /* Database containing the table being updated */
 
 #ifndef SQLITE_OMIT_TRIGGER
   int isView;                  /* Trying to update a view */
@@ -99,7 +100,9 @@
   int oldIdx      = -1;  /* index of trigger "old" temp table       */
 
   sContext.pParse = 0;
-  if( pParse->nErr || sqlite3_malloc_failed ) goto update_cleanup;
+  if( pParse->nErr || sqlite3MallocFailed() ){
+    goto update_cleanup;
+  }
   db = pParse->db;
   assert( pTabList->nSrc==1 );
 
@@ -107,6 +110,7 @@
   */
   pTab = sqlite3SrcListLookup(pParse, pTabList);
   if( pTab==0 ) goto update_cleanup;
+  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
 
   /* Figure out if we have any triggers and if the table being
   ** updated is a view
@@ -192,7 +196,7 @@
     {
       int rc;
       rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
-                           pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
+                           pTab->aCol[j].zName, db->aDb[iDb].zName);
       if( rc==SQLITE_DENY ){
         goto update_cleanup;
       }else if( rc==SQLITE_IGNORE ){
@@ -231,7 +235,6 @@
       }
     }
     if( i<pIdx->nColumn ){
-      if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto update_cleanup;
       apIdx[nIdx++] = pIdx;
       aIdxUsed[j] = 1;
     }else{
@@ -257,7 +260,7 @@
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto update_cleanup;
   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
-  sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);
+  sqlite3BeginWriteOperation(pParse, 1, iDb);
 
   /* If we are trying to update a view, realize that view into
   ** a ephemeral table.
@@ -307,7 +310,7 @@
       /* Open a cursor and make it point to the record that is
       ** being updated.
       */
-      sqlite3OpenTableForReading(v, iCur, pTab);
+      sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
     }
     sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
 
@@ -362,9 +365,7 @@
     ** action, then we need to open all indices because we might need
     ** to be deleting some records.
     */
-    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
-    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
+    sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); 
     if( onError==OE_Replace ){
       openAll = 1;
     }else{
@@ -378,9 +379,10 @@
     }
     for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
       if( openAll || aIdxUsed[i] ){
-        sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
+        sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
         sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
-                       (char*)&pIdx->keyInfo, P3_KEYINFO);
+                       (char*)pKey, P3_KEYINFO_HANDOFF);
         assert( pParse->nTab>iCur+i+1 );
       }
     }
@@ -429,7 +431,7 @@
 
     /* Delete the old indices for the current record.
     */
-    sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
+    sqlite3GenerateRowIndexDelete(v, pTab, iCur, aIdxUsed);
 
     /* If changing the record number, delete the old record.
     */
@@ -492,7 +494,7 @@
   if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
     sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "rows updated", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
   }
 
 update_cleanup:

Modified: packages/libdbd-sqlite3-perl/trunk/utf.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/utf.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/utf.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -12,7 +12,7 @@
 ** This file contains routines used to translate between UTF-8, 
 ** UTF-16, UTF-16BE, and UTF-16LE.
 **
-** $Id: utf.c,v 1.32 2005/01/28 01:29:08 drh Exp $
+** $Id: utf.c,v 1.38 2006/02/24 02:53:50 drh Exp $
 **
 ** Notes on UTF-8:
 **
@@ -255,7 +255,7 @@
 #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
   {
     char zBuf[100];
-    sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
+    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
     fprintf(stderr, "INPUT:  %s\n", zBuf);
   }
 #endif
@@ -272,7 +272,7 @@
       assert( rc==SQLITE_NOMEM );
       return SQLITE_NOMEM;
     }
-    zIn = pMem->z;
+    zIn = (u8*)pMem->z;
     zTerm = &zIn[pMem->n];
     while( zIn<zTerm ){
       temp = *zIn;
@@ -308,7 +308,7 @@
   ** obtained from malloc(), or Mem.zShort, if it large enough and not in
   ** use, or the zShort array on the stack (see above).
   */
-  zIn = pMem->z;
+  zIn = (u8*)pMem->z;
   zTerm = &zIn[pMem->n];
   if( len>NBFS ){
     zOut = sqliteMallocRaw(len);
@@ -360,18 +360,18 @@
   pMem->enc = desiredEnc;
   if( zOut==zShort ){
     memcpy(pMem->zShort, zOut, len);
-    zOut = pMem->zShort;
+    zOut = (u8*)pMem->zShort;
     pMem->flags |= (MEM_Term|MEM_Short);
   }else{
     pMem->flags |= (MEM_Term|MEM_Dyn);
   }
-  pMem->z = zOut;
+  pMem->z = (char*)zOut;
 
 translate_out:
 #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
   {
     char zBuf[100];
-    sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
+    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
     fprintf(stderr, "OUTPUT: %s\n", zBuf);
   }
 #endif
@@ -451,6 +451,23 @@
 
 #ifndef SQLITE_OMIT_UTF16
 /*
+** Convert a UTF-16 string in the native encoding into a UTF-8 string.
+** Memory to hold the UTF-8 string is obtained from malloc and must be
+** freed by the calling function.
+**
+** NULL is returned if there is an allocation error.
+*/
+char *sqlite3utf16to8(const void *z, int nByte){
+  Mem m;
+  memset(&m, 0, sizeof(m));
+  sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
+  sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
+  assert( m.flags & MEM_Term );
+  assert( m.flags & MEM_Str );
+  return (m.flags & MEM_Dyn)!=0 ? m.z : sqliteStrDup(m.z);
+}
+
+/*
 ** pZ is a UTF-16 encoded unicode string. If nChar is less than zero,
 ** return the number of bytes up to (but not including), the first pair
 ** of consecutive 0x00 bytes in pZ. If nChar is not less than zero,
@@ -462,6 +479,15 @@
   char const *z = zIn;
   int n = 0;
   if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
+    /* Using an "if (SQLITE_UTF16NATIVE==SQLITE_UTF16BE)" construct here
+    ** and in other parts of this file means that at one branch will
+    ** not be covered by coverage testing on any single host. But coverage
+    ** will be complete if the tests are run on both a little-endian and 
+    ** big-endian host. Because both the UTF16NATIVE and SQLITE_UTF16BE
+    ** macros are constant at compile time the compiler can determine
+    ** which branch will be followed. It is therefore assumed that no runtime
+    ** penalty is paid for this "if" statement.
+    */
     while( c && ((nChar<0) || n<nChar) ){
       READ_UTF16BE(z, c);
       n++;

Modified: packages/libdbd-sqlite3-perl/trunk/util.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/util.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/util.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -14,42 +14,178 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.146 2005/09/17 18:34:11 drh Exp $
+** $Id: util.c,v 1.188 2006/04/04 01:54:55 drh Exp $
 */
 #include "sqliteInt.h"
+#include "os.h"
 #include <stdarg.h>
 #include <ctype.h>
 
-#if SQLITE_MEMDEBUG>2 && defined(__GLIBC__)
-#include <execinfo.h>
-void print_stack_trace(){
-  void *bt[30];
-  int i;
-  int n = backtrace(bt, 30);
+/*
+** MALLOC WRAPPER ARCHITECTURE
+**
+** The sqlite code accesses dynamic memory allocation/deallocation by invoking
+** the following six APIs (which may be implemented as macros).
+**
+**     sqlite3Malloc()
+**     sqlite3MallocRaw()
+**     sqlite3Realloc()
+**     sqlite3ReallocOrFree()
+**     sqlite3Free()
+**     sqlite3AllocSize()
+**
+** The function sqlite3FreeX performs the same task as sqlite3Free and is
+** guaranteed to be a real function. The same holds for sqlite3MallocX
+**
+** The above APIs are implemented in terms of the functions provided in the
+** operating-system interface. The OS interface is never accessed directly
+** by code outside of this file.
+**
+**     sqlite3OsMalloc()
+**     sqlite3OsRealloc()
+**     sqlite3OsFree()
+**     sqlite3OsAllocationSize()
+**
+** Functions sqlite3MallocRaw() and sqlite3Realloc() may invoke 
+** sqlite3_release_memory() if a call to sqlite3OsMalloc() or
+** sqlite3OsRealloc() fails (or if the soft-heap-limit for the thread is
+** exceeded). Function sqlite3Malloc() usually invokes
+** sqlite3MallocRaw().
+**
+** MALLOC TEST WRAPPER ARCHITECTURE
+**
+** The test wrapper provides extra test facilities to ensure the library 
+** does not leak memory and handles the failure of the underlying OS level
+** allocation system correctly. It is only present if the library is 
+** compiled with the SQLITE_MEMDEBUG macro set.
+**
+**     * Guardposts to detect overwrites.
+**     * Ability to cause a specific Malloc() or Realloc() to fail.
+**     * Audit outstanding memory allocations (i.e check for leaks).
+*/
 
-  fprintf(stderr, "STACK: ");
-  for(i=0; i<n;i++){
-    fprintf(stderr, "%p ", bt[i]);
+#define MAX(x,y) ((x)>(y)?(x):(y))
+
+#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
+/*
+** Set the soft heap-size limit for the current thread. Passing a negative
+** value indicates no limit.
+*/
+void sqlite3_soft_heap_limit(int n){
+  ThreadData *pTd = sqlite3ThreadData();
+  if( pTd ){
+    pTd->nSoftHeapLimit = n;
   }
-  fprintf(stderr, "\n");
+  sqlite3ReleaseThreadData();
 }
+
+/*
+** Release memory held by SQLite instances created by the current thread.
+*/
+int sqlite3_release_memory(int n){
+  return sqlite3pager_release_memory(n);
+}
 #else
-#define print_stack_trace()
+/* If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, then define a version
+** of sqlite3_release_memory() to be used by other code in this file.
+** This is done for no better reason than to reduce the number of 
+** pre-processor #ifndef statements.
+*/
+#define sqlite3_release_memory(x) 0    /* 0 == no memory freed */
 #endif
 
+#ifdef SQLITE_MEMDEBUG
+/*--------------------------------------------------------------------------
+** Begin code for memory allocation system test layer.
+**
+** Memory debugging is turned on by defining the SQLITE_MEMDEBUG macro.
+**
+** SQLITE_MEMDEBUG==1    -> Fence-posting only (thread safe) 
+** SQLITE_MEMDEBUG==2    -> Fence-posting + linked list of allocations (not ts)
+** SQLITE_MEMDEBUG==3    -> Above + backtraces (not thread safe, req. glibc)
+*/
+
+/* Figure out whether or not to store backtrace() information for each malloc.
+** The backtrace() function is only used if SQLITE_MEMDEBUG is set to 2 or 
+** greater and glibc is in use. If we don't want to use backtrace(), then just
+** define it as an empty macro and set the amount of space reserved to 0.
+*/
+#if defined(__GLIBC__) && SQLITE_MEMDEBUG>2
+  extern int backtrace(void **, int);
+  #define TESTALLOC_STACKSIZE 128
+  #define TESTALLOC_STACKFRAMES ((TESTALLOC_STACKSIZE-8)/sizeof(void*))
+#else
+  #define backtrace(x, y)
+  #define TESTALLOC_STACKSIZE 0
+  #define TESTALLOC_STACKFRAMES 0
+#endif
+
 /*
-** If malloc() ever fails, this global variable gets set to 1.
-** This causes the library to abort and never again function.
+** Number of 32-bit guard words.  This should probably be a multiple of
+** 2 since on 64-bit machines we want the value returned by sqliteMalloc()
+** to be 8-byte aligned.
 */
-int sqlite3_malloc_failed = 0;
+#ifndef TESTALLOC_NGUARD
+# define TESTALLOC_NGUARD 2
+#endif
 
 /*
-** If SQLITE_MEMDEBUG is defined, then use versions of malloc() and
-** free() that track memory usage and check for buffer overruns.
+** Size reserved for storing file-name along with each malloc()ed blob.
 */
-#ifdef SQLITE_MEMDEBUG
+#define TESTALLOC_FILESIZE 64
 
 /*
+** Size reserved for storing the user string. Each time a Malloc() or Realloc()
+** call succeeds, up to TESTALLOC_USERSIZE bytes of the string pointed to by
+** sqlite3_malloc_id are stored along with the other test system metadata.
+*/
+#define TESTALLOC_USERSIZE 64
+const char *sqlite3_malloc_id = 0;
+
+/*
+** Blocks used by the test layer have the following format:
+**
+**        <sizeof(void *) pNext pointer>
+**        <sizeof(void *) pPrev pointer>
+**        <TESTALLOC_NGUARD 32-bit guard words>
+**            <The application level allocation>
+**        <TESTALLOC_NGUARD 32-bit guard words>
+**        <32-bit line number>
+**        <TESTALLOC_FILESIZE bytes containing null-terminated file name>
+**        <TESTALLOC_STACKSIZE bytes of backtrace() output>
+*/ 
+
+#define TESTALLOC_OFFSET_GUARD1(p)    (sizeof(void *) * 2)
+#define TESTALLOC_OFFSET_DATA(p) ( \
+  TESTALLOC_OFFSET_GUARD1(p) + sizeof(u32) * TESTALLOC_NGUARD \
+)
+#define TESTALLOC_OFFSET_GUARD2(p) ( \
+  TESTALLOC_OFFSET_DATA(p) + sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD \
+)
+#define TESTALLOC_OFFSET_LINENUMBER(p) ( \
+  TESTALLOC_OFFSET_GUARD2(p) + sizeof(u32) * TESTALLOC_NGUARD \
+)
+#define TESTALLOC_OFFSET_FILENAME(p) ( \
+  TESTALLOC_OFFSET_LINENUMBER(p) + sizeof(u32) \
+)
+#define TESTALLOC_OFFSET_USER(p) ( \
+  TESTALLOC_OFFSET_FILENAME(p) + TESTALLOC_FILESIZE \
+)
+#define TESTALLOC_OFFSET_STACK(p) ( \
+  TESTALLOC_OFFSET_USER(p) + TESTALLOC_USERSIZE + 8 - \
+  (TESTALLOC_OFFSET_USER(p) % 8) \
+)
+
+#define TESTALLOC_OVERHEAD ( \
+  sizeof(void *)*2 +                   /* pPrev and pNext pointers */   \
+  TESTALLOC_NGUARD*sizeof(u32)*2 +              /* Guard words */       \
+  sizeof(u32) + TESTALLOC_FILESIZE +   /* File and line number */       \
+  TESTALLOC_USERSIZE +                 /* User string */                \
+  TESTALLOC_STACKSIZE                  /* backtrace() stack */          \
+)
+
+
+/*
 ** For keeping track of the number of mallocs and frees.   This
 ** is used to check for memory leaks.  The iMallocFail and iMallocReset
 ** values are used to simulate malloc() failures during testing in 
@@ -58,35 +194,31 @@
 */
 int sqlite3_nMalloc;         /* Number of sqliteMalloc() calls */
 int sqlite3_nFree;           /* Number of sqliteFree() calls */
-int sqlite3_memUsed;         /* Total memory obtained from malloc */
-int sqlite3_memMax;          /* Mem usage high-water mark */
+int sqlite3_memUsed;         /* TODO Total memory obtained from malloc */
+int sqlite3_memMax;          /* TODO Mem usage high-water mark */
 int sqlite3_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
 int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */
-#if SQLITE_MEMDEBUG>1
-static int memcnt = 0;
-#endif
 
-/*
-** Number of 32-bit guard words.  This should probably be a multiple of
-** 2 since on 64-bit machines we want the value returned by sqliteMalloc()
-** to be 8-byte aligned.
-*/
-#define N_GUARD 2
+void *sqlite3_pFirst = 0;         /* Pointer to linked list of allocations */
+int sqlite3_nMaxAlloc = 0;        /* High water mark of ThreadData.nAlloc */
+int sqlite3_mallocDisallowed = 0; /* assert() in sqlite3Malloc() if set */
+int sqlite3_isFail = 0;           /* True if all malloc calls should fail */
+const char *sqlite3_zFile = 0;    /* Filename to associate debug info with */
+int sqlite3_iLine = 0;            /* Line number for debug info */
 
 /*
 ** Check for a simulated memory allocation failure.  Return true if
 ** the failure should be simulated.  Return false to proceed as normal.
 */
-static int simulatedMallocFailure(int n, char *zFile, int line){
+int sqlite3TestMallocFail(){
+  if( sqlite3_isFail ){
+    return 1;
+  }
   if( sqlite3_iMallocFail>=0 ){
     sqlite3_iMallocFail--;
     if( sqlite3_iMallocFail==0 ){
-      sqlite3_malloc_failed++;
-#if SQLITE_MEMDEBUG>1
-      fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
-              n, zFile,line);
-#endif
       sqlite3_iMallocFail = sqlite3_iMallocReset;
+      sqlite3_isFail = 1;
       return 1;
     }
   }
@@ -94,292 +226,517 @@
 }
 
 /*
-** Allocate new memory and set it to zero.  Return NULL if
-** no memory is available.
+** The argument is a pointer returned by sqlite3OsMalloc() or xRealloc().
+** assert() that the first and last (TESTALLOC_NGUARD*4) bytes are set to the
+** values set by the applyGuards() function.
 */
-void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){
-  void *p;
-  int *pi;
-  int i, k;
-  if( n==0 ){
-    return 0;
+static void checkGuards(u32 *p)
+{
+  int i;
+  char *zAlloc = (char *)p;
+  char *z;
+
+  /* First set of guard words */
+  z = &zAlloc[TESTALLOC_OFFSET_GUARD1(p)];
+  for(i=0; i<TESTALLOC_NGUARD; i++){
+    assert(((u32 *)z)[i]==0xdead1122);
   }
-  if( simulatedMallocFailure(n, zFile, line) ){
-    return 0;
+
+  /* Second set of guard words */
+  z = &zAlloc[TESTALLOC_OFFSET_GUARD2(p)];
+  for(i=0; i<TESTALLOC_NGUARD; i++){
+    u32 guard = 0;
+    memcpy(&guard, &z[i*sizeof(u32)], sizeof(u32));
+    assert(guard==0xdead3344);
   }
-  sqlite3_memUsed += n;
-  if( sqlite3_memMax<sqlite3_memUsed ) sqlite3_memMax = sqlite3_memUsed;
-  k = (n+sizeof(int)-1)/sizeof(int);
-  pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
-  if( pi==0 ){
-    if( n>0 ) sqlite3_malloc_failed++;
-    return 0;
+}
+
+/*
+** The argument is a pointer returned by sqlite3OsMalloc() or Realloc(). The
+** first and last (TESTALLOC_NGUARD*4) bytes are set to known values for use as 
+** guard-posts.
+*/
+static void applyGuards(u32 *p)
+{
+  int i;
+  char *z;
+  char *zAlloc = (char *)p;
+
+  /* First set of guard words */
+  z = &zAlloc[TESTALLOC_OFFSET_GUARD1(p)];
+  for(i=0; i<TESTALLOC_NGUARD; i++){
+    ((u32 *)z)[i] = 0xdead1122;
   }
-  sqlite3_nMalloc++;
-  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
-  pi[N_GUARD] = n;
-  for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
-  p = &pi[N_GUARD+1];
-  memset(p, bZero==0, n);
-#if SQLITE_MEMDEBUG>1
-  print_stack_trace();
-  fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
-      ++memcnt, n, (int)p, zFile,line);
-#endif
-  return p;
+
+  /* Second set of guard words */
+  z = &zAlloc[TESTALLOC_OFFSET_GUARD2(p)];
+  for(i=0; i<TESTALLOC_NGUARD; i++){
+    static const int guard = 0xdead3344;
+    memcpy(&z[i*sizeof(u32)], &guard, sizeof(u32));
+  }
+
+  /* Line number */
+  z = &((char *)z)[TESTALLOC_NGUARD*sizeof(u32)];             /* Guard words */
+  z = &zAlloc[TESTALLOC_OFFSET_LINENUMBER(p)];
+  memcpy(z, &sqlite3_iLine, sizeof(u32));
+
+  /* File name */
+  z = &zAlloc[TESTALLOC_OFFSET_FILENAME(p)];
+  strncpy(z, sqlite3_zFile, TESTALLOC_FILESIZE);
+  z[TESTALLOC_FILESIZE - 1] = '\0';
+
+  /* User string */
+  z = &zAlloc[TESTALLOC_OFFSET_USER(p)];
+  z[0] = 0;
+  if( sqlite3_malloc_id ){
+    strncpy(z, sqlite3_malloc_id, TESTALLOC_USERSIZE);
+    z[TESTALLOC_USERSIZE-1] = 0;
+  }
+
+  /* backtrace() stack */
+  z = &zAlloc[TESTALLOC_OFFSET_STACK(p)];
+  backtrace((void **)z, TESTALLOC_STACKFRAMES);
+
+  /* Sanity check to make sure checkGuards() is working */
+  checkGuards(p);
 }
 
 /*
-** This version of malloc is always a real function, never a macro
+** The argument is a malloc()ed pointer as returned by the test-wrapper.
+** Return a pointer to the Os level allocation.
 */
-void *sqlite3MallocX(int n){
-  return sqlite3Malloc_(n, 0, __FILE__, __LINE__);
+static void *getOsPointer(void *p)
+{
+  char *z = (char *)p;
+  return (void *)(&z[-1 * TESTALLOC_OFFSET_DATA(p)]);
 }
 
+
+#if SQLITE_MEMDEBUG>1
 /*
-** Check to see if the given pointer was obtained from sqliteMalloc()
-** and is able to hold at least N bytes.  Raise an exception if this
-** is not the case.
-**
-** This routine is used for testing purposes only.
+** The argument points to an Os level allocation. Link it into the threads list
+** of allocations.
 */
-void sqlite3CheckMemory(void *p, int N){
-  int *pi = p;
-  int n, i, k;
-  pi -= N_GUARD+1;
-  for(i=0; i<N_GUARD; i++){
-    assert( pi[i]==0xdead1122 );
+static void linkAlloc(void *p){
+  void **pp = (void **)p;
+  pp[0] = 0;
+  pp[1] = sqlite3_pFirst;
+  if( sqlite3_pFirst ){
+    ((void **)sqlite3_pFirst)[0] = p;
   }
-  n = pi[N_GUARD];
-  assert( N>=0 && N<n );
-  k = (n+sizeof(int)-1)/sizeof(int);
-  for(i=0; i<N_GUARD; i++){
-    assert( pi[k+N_GUARD+1+i]==0xdead3344 );
-  }
+  sqlite3_pFirst = p;
 }
 
 /*
-** Free memory previously obtained from sqliteMalloc()
+** The argument points to an Os level allocation. Unlinke it from the threads
+** list of allocations.
 */
-void sqlite3Free_(void *p, char *zFile, int line){
-  if( p ){
-    int *pi, i, k, n;
-    pi = p;
-    pi -= N_GUARD+1;
-    sqlite3_nFree++;
-    for(i=0; i<N_GUARD; i++){
-      if( pi[i]!=0xdead1122 ){
-        fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
-        return;
-      }
+static void unlinkAlloc(void *p)
+{
+  void **pp = (void **)p;
+  if( p==sqlite3_pFirst ){
+    assert(!pp[0]);
+    assert(!pp[1] || ((void **)(pp[1]))[0]==p);
+    sqlite3_pFirst = pp[1];
+    if( sqlite3_pFirst ){
+      ((void **)sqlite3_pFirst)[0] = 0;
     }
-    n = pi[N_GUARD];
-    sqlite3_memUsed -= n;
-    k = (n+sizeof(int)-1)/sizeof(int);
-    for(i=0; i<N_GUARD; i++){
-      if( pi[k+N_GUARD+1+i]!=0xdead3344 ){
-        fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
-        return;
-      }
+  }else{
+    void **pprev = pp[0];
+    void **pnext = pp[1];
+    assert(pprev);
+    assert(pprev[1]==p);
+    pprev[1] = (void *)pnext;
+    if( pnext ){
+      assert(pnext[0]==p);
+      pnext[0] = (void *)pprev;
     }
-    memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
-#if SQLITE_MEMDEBUG>1
-    fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
-         ++memcnt, n, (int)p, zFile,line);
-#endif
-    free(pi);
   }
 }
 
 /*
-** Resize a prior allocation.  If p==0, then this routine
-** works just like sqliteMalloc().  If n==0, then this routine
-** works just like sqliteFree().
+** Pointer p is a pointer to an OS level allocation that has just been
+** realloc()ed. Set the list pointers that point to this entry to it's new
+** location.
 */
-void *sqlite3Realloc_(void *oldP, int n, char *zFile, int line){
-  int *oldPi, *pi, i, k, oldN, oldK;
-  void *p;
-  if( oldP==0 ){
-    return sqlite3Malloc_(n,1,zFile,line);
+static void relinkAlloc(void *p)
+{
+  void **pp = (void **)p;
+  if( pp[0] ){
+    ((void **)(pp[0]))[1] = p;
+  }else{
+    sqlite3_pFirst = p;
   }
-  if( n==0 ){
-    sqlite3Free_(oldP,zFile,line);
-    return 0;
+  if( pp[1] ){
+    ((void **)(pp[1]))[0] = p;
   }
-  if( simulatedMallocFailure(n, zFile, line) ){
-    return 0;
-  }
-  oldPi = oldP;
-  oldPi -= N_GUARD+1;
-  if( oldPi[0]!=0xdead1122 ){
-    fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);
-    return 0;
-  }
-  oldN = oldPi[N_GUARD];
-  sqlite3_memUsed -= oldN;
-  oldK = (oldN+sizeof(int)-1)/sizeof(int);
-  for(i=0; i<N_GUARD; i++){
-    if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
-      fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",
-              (int)oldP);
-      return 0;
+}
+#else
+#define linkAlloc(x)
+#define relinkAlloc(x)
+#define unlinkAlloc(x)
+#endif
+
+/*
+** This function sets the result of the Tcl interpreter passed as an argument
+** to a list containing an entry for each currently outstanding call made to 
+** sqliteMalloc and friends by the current thread. Each list entry is itself a
+** list, consisting of the following (in order):
+**
+**     * The number of bytes allocated
+**     * The __FILE__ macro at the time of the sqliteMalloc() call.
+**     * The __LINE__ macro ...
+**     * The value of the sqlite3_malloc_id variable ...
+**     * The output of backtrace() (if available) ...
+**
+** Todo: We could have a version of this function that outputs to stdout, 
+** to debug memory leaks when Tcl is not available.
+*/
+#if defined(TCLSH) && defined(SQLITE_DEBUG) && SQLITE_MEMDEBUG>1
+#include <tcl.h>
+int sqlite3OutstandingMallocs(Tcl_Interp *interp){
+  void *p;
+  Tcl_Obj *pRes = Tcl_NewObj();
+  Tcl_IncrRefCount(pRes);
+
+
+  for(p=sqlite3_pFirst; p; p=((void **)p)[1]){
+    Tcl_Obj *pEntry = Tcl_NewObj();
+    Tcl_Obj *pStack = Tcl_NewObj();
+    char *z;
+    u32 iLine;
+    int nBytes = sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD;
+    char *zAlloc = (char *)p;
+    int i;
+
+    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewIntObj(nBytes));
+
+    z = &zAlloc[TESTALLOC_OFFSET_FILENAME(p)];
+    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewStringObj(z, -1));
+
+    z = &zAlloc[TESTALLOC_OFFSET_LINENUMBER(p)];
+    memcpy(&iLine, z, sizeof(u32));
+    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewIntObj(iLine));
+
+    z = &zAlloc[TESTALLOC_OFFSET_USER(p)];
+    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewStringObj(z, -1));
+
+    z = &zAlloc[TESTALLOC_OFFSET_STACK(p)];
+    for(i=0; i<TESTALLOC_STACKFRAMES; i++){
+      char zHex[128];
+      sprintf(zHex, "%p", ((void **)z)[i]);
+      Tcl_ListObjAppendElement(0, pStack, Tcl_NewStringObj(zHex, -1));
     }
+
+    Tcl_ListObjAppendElement(0, pEntry, pStack);
+    Tcl_ListObjAppendElement(0, pRes, pEntry);
   }
-  k = (n + sizeof(int) - 1)/sizeof(int);
-  pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
-  if( pi==0 ){
-    if( n>0 ) sqlite3_malloc_failed++;
-    return 0;
+
+  Tcl_ResetResult(interp);
+  Tcl_SetObjResult(interp, pRes);
+  Tcl_DecrRefCount(pRes);
+  return TCL_OK;
+}
+#endif
+
+/*
+** This is the test layer's wrapper around sqlite3OsMalloc().
+*/
+static void * OSMALLOC(int n){
+  sqlite3OsEnterMutex();
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  sqlite3_nMaxAlloc = 
+      MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
+#endif
+  assert( !sqlite3_mallocDisallowed );
+  if( !sqlite3TestMallocFail() ){
+    u32 *p;
+    p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD);
+    assert(p);
+    sqlite3_nMalloc++;
+    applyGuards(p);
+    linkAlloc(p);
+    sqlite3OsLeaveMutex();
+    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
   }
-  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
-  pi[N_GUARD] = n;
-  sqlite3_memUsed += n;
-  if( sqlite3_memMax<sqlite3_memUsed ) sqlite3_memMax = sqlite3_memUsed;
-  for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
-  p = &pi[N_GUARD+1];
-  memcpy(p, oldP, n>oldN ? oldN : n);
-  if( n>oldN ){
-    memset(&((char*)p)[oldN], 0x55, n-oldN);
+  sqlite3OsLeaveMutex();
+  return 0;
+}
+
+static int OSSIZEOF(void *p){
+  if( p ){
+    u32 *pOs = (u32 *)getOsPointer(p);
+    return sqlite3OsAllocationSize(pOs) - TESTALLOC_OVERHEAD;
   }
-  memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
-  free(oldPi);
-#if SQLITE_MEMDEBUG>1
-  print_stack_trace();
-  fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
-    ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);
-#endif
-  return p;
+  return 0;
 }
 
 /*
-** Make a copy of a string in memory obtained from sqliteMalloc()
+** This is the test layer's wrapper around sqlite3OsFree(). The argument is a
+** pointer to the space allocated for the application to use.
 */
-char *sqlite3StrDup_(const char *z, char *zFile, int line){
-  char *zNew;
-  if( z==0 ) return 0;
-  zNew = sqlite3Malloc_(strlen(z)+1, 0, zFile, line);
-  if( zNew ) strcpy(zNew, z);
-  return zNew;
+static void OSFREE(void *pFree){
+  sqlite3OsEnterMutex();
+  u32 *p = (u32 *)getOsPointer(pFree);   /* p points to Os level allocation */
+  checkGuards(p);
+  unlinkAlloc(p);
+  memset(pFree, 0x55, OSSIZEOF(pFree));
+  sqlite3OsFree(p);
+  sqlite3_nFree++;
+  sqlite3OsLeaveMutex();
 }
-char *sqlite3StrNDup_(const char *z, int n, char *zFile, int line){
-  char *zNew;
-  if( z==0 ) return 0;
-  zNew = sqlite3Malloc_(n+1, 0, zFile, line);
-  if( zNew ){
-    memcpy(zNew, z, n);
-    zNew[n] = 0;
+
+/*
+** This is the test layer's wrapper around sqlite3OsRealloc().
+*/
+static void * OSREALLOC(void *pRealloc, int n){
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  sqlite3_nMaxAlloc = 
+      MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
+#endif
+  assert( !sqlite3_mallocDisallowed );
+  if( !sqlite3TestMallocFail() ){
+    u32 *p = (u32 *)getOsPointer(pRealloc);
+    checkGuards(p);
+    p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD);
+    applyGuards(p);
+    relinkAlloc(p);
+    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
   }
-  return zNew;
+  return 0;
 }
 
+static void OSMALLOC_FAILED(){
+  sqlite3_isFail = 0;
+}
+
+#else
+/* Define macros to call the sqlite3OsXXX interface directly if 
+** the SQLITE_MEMDEBUG macro is not defined.
+*/
+#define OSMALLOC(x)        sqlite3OsMalloc(x)
+#define OSREALLOC(x,y)     sqlite3OsRealloc(x,y)
+#define OSFREE(x)          sqlite3OsFree(x)
+#define OSSIZEOF(x)        sqlite3OsAllocationSize(x)
+#define OSMALLOC_FAILED()
+
+#endif  /* SQLITE_MEMDEBUG */
 /*
-** A version of sqliteFree that is always a function, not a macro.
-*/
-void sqlite3FreeX(void *p){
-  sqliteFree(p);
+** End code for memory allocation system test layer.
+**--------------------------------------------------------------------------*/
+
+/*
+** This routine is called when we are about to allocate n additional bytes
+** of memory.  If the new allocation will put is over the soft allocation
+** limit, then invoke sqlite3_release_memory() to try to release some
+** memory before continuing with the allocation.
+**
+** This routine also makes sure that the thread-specific-data (TSD) has
+** be allocated.  If it has not and can not be allocated, then return
+** false.  The updateMemoryUsedCount() routine below will deallocate
+** the TSD if it ought to be.
+**
+** If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, this routine is
+** a no-op
+*/ 
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+static int enforceSoftLimit(int n){
+  ThreadData *pTsd = sqlite3ThreadData();
+  if( pTsd==0 ){
+    return 0;
+  }
+  assert( pTsd->nAlloc>=0 );
+  if( n>0 && pTsd->nSoftHeapLimit>0 ){
+    while( pTsd->nAlloc+n>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) ){}
+  }
+  return 1;
 }
-#endif /* SQLITE_MEMDEBUG */
+#else
+# define enforceSoftLimit(X)  1
+#endif
 
 /*
-** The following versions of malloc() and free() are for use in a
-** normal build.
+** Update the count of total outstanding memory that is held in
+** thread-specific-data (TSD).  If after this update the TSD is
+** no longer being used, then deallocate it.
+**
+** If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, this routine is
+** a no-op
 */
-#if !defined(SQLITE_MEMDEBUG)
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+static void updateMemoryUsedCount(int n){
+  ThreadData *pTsd = sqlite3ThreadData();
+  if( pTsd ){
+    pTsd->nAlloc += n;
+    assert( pTsd->nAlloc>=0 );
+    if( pTsd->nAlloc==0 && pTsd->nSoftHeapLimit==0 ){
+      sqlite3ReleaseThreadData();
+    }
+  }
+}
+#else
+#define updateMemoryUsedCount(x)  /* no-op */
+#endif
 
 /*
-** Allocate new memory and set it to zero.  Return NULL if
-** no memory is available.  See also sqliteMallocRaw().
+** Allocate and return N bytes of uninitialised memory by calling
+** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
+** by calling sqlite3_release_memory().
 */
-void *sqlite3Malloc(int n){
-  void *p;
-  if( n==0 ) return 0;
-  if( (p = malloc(n))==0 ){
-    if( n>0 ) sqlite3_malloc_failed++;
-  }else{
-    memset(p, 0, n);
+void *sqlite3MallocRaw(int n, int doMemManage){
+  void *p = 0;
+  if( n>0 && !sqlite3MallocFailed() && (!doMemManage || enforceSoftLimit(n)) ){
+    while( (p = OSMALLOC(n))==0 && sqlite3_release_memory(n) ){}
+    if( !p ){
+      sqlite3FailedMalloc();
+      OSMALLOC_FAILED();
+    }else if( doMemManage ){
+      updateMemoryUsedCount(OSSIZEOF(p));
+    }
   }
   return p;
 }
 
 /*
-** Allocate new memory but do not set it to zero.  Return NULL if
-** no memory is available.  See also sqliteMalloc().
+** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The
+** pointer to the new allocation is returned.  If the Realloc() call fails,
+** attempt to free memory by calling sqlite3_release_memory().
 */
-void *sqlite3MallocRaw(int n){
-  void *p;
-  if( n==0 ) return 0;
-  if( (p = malloc(n))==0 ){
-    if( n>0 ) sqlite3_malloc_failed++;
+void *sqlite3Realloc(void *p, int n){
+  if( sqlite3MallocFailed() ){
+    return 0;
   }
-  return p;
+
+  if( !p ){
+    return sqlite3Malloc(n, 1);
+  }else{
+    void *np = 0;
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+    int origSize = OSSIZEOF(p);
+#endif
+    if( enforceSoftLimit(n - origSize) ){
+      while( (np = OSREALLOC(p, n))==0 && sqlite3_release_memory(n) ){}
+      if( !np ){
+        sqlite3FailedMalloc();
+        OSMALLOC_FAILED();
+      }else{
+        updateMemoryUsedCount(OSSIZEOF(np) - origSize);
+      }
+    }
+    return np;
+  }
 }
 
 /*
-** Free memory previously obtained from sqliteMalloc()
+** Free the memory pointed to by p. p must be either a NULL pointer or a 
+** value returned by a previous call to sqlite3Malloc() or sqlite3Realloc().
 */
 void sqlite3FreeX(void *p){
   if( p ){
-    free(p);
+    updateMemoryUsedCount(0 - OSSIZEOF(p));
+    OSFREE(p);
   }
 }
 
 /*
-** Resize a prior allocation.  If p==0, then this routine
-** works just like sqliteMalloc().  If n==0, then this routine
-** works just like sqliteFree().
+** A version of sqliteMalloc() that is always a function, not a macro.
+** Currently, this is used only to alloc to allocate the parser engine.
 */
-void *sqlite3Realloc(void *p, int n){
-  void *p2;
-  if( p==0 ){
-    return sqliteMalloc(n);
+void *sqlite3MallocX(int n){
+  return sqliteMalloc(n);
+}
+
+/*
+** sqlite3Malloc
+** sqlite3ReallocOrFree
+**
+** These two are implemented as wrappers around sqlite3MallocRaw(), 
+** sqlite3Realloc() and sqlite3Free().
+*/ 
+void *sqlite3Malloc(int n, int doMemManage){
+  void *p = sqlite3MallocRaw(n, doMemManage);
+  if( p ){
+    memset(p, 0, n);
   }
-  if( n==0 ){
-    sqliteFree(p);
-    return 0;
+  return p;
+}
+void sqlite3ReallocOrFree(void **pp, int n){
+  void *p = sqlite3Realloc(*pp, n);
+  if( !p ){
+    sqlite3FreeX(*pp);
   }
-  p2 = realloc(p, n);
-  if( p2==0 ){
-    if( n>0 ) sqlite3_malloc_failed++;
+  *pp = p;
+}
+
+/*
+** sqlite3ThreadSafeMalloc() and sqlite3ThreadSafeFree() are used in those
+** rare scenarios where sqlite may allocate memory in one thread and free
+** it in another. They are exactly the same as sqlite3Malloc() and 
+** sqlite3Free() except that:
+**
+**   * The allocated memory is not included in any calculations with 
+**     respect to the soft-heap-limit, and
+**
+**   * sqlite3ThreadSafeMalloc() must be matched with ThreadSafeFree(),
+**     not sqlite3Free(). Calling sqlite3Free() on memory obtained from
+**     ThreadSafeMalloc() will cause an error somewhere down the line.
+*/
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+void *sqlite3ThreadSafeMalloc(int n){
+  ENTER_MALLOC;
+  return sqlite3Malloc(n, 0);
+}
+void sqlite3ThreadSafeFree(void *p){
+  ENTER_MALLOC;
+  if( p ){
+    OSFREE(p);
   }
-  return p2;
 }
+#endif
 
+
 /*
-** Make a copy of a string in memory obtained from sqliteMalloc()
+** Return the number of bytes allocated at location p. p must be either 
+** a NULL pointer (in which case 0 is returned) or a pointer returned by 
+** sqlite3Malloc(), sqlite3Realloc() or sqlite3ReallocOrFree().
+**
+** The number of bytes allocated does not include any overhead inserted by 
+** any malloc() wrapper functions that may be called. So the value returned
+** is the number of bytes that were available to SQLite using pointer p, 
+** regardless of how much memory was actually allocated.
 */
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+int sqlite3AllocSize(void *p){
+  return OSSIZEOF(p);
+}
+#endif
+
+/*
+** Make a copy of a string in memory obtained from sqliteMalloc(). These 
+** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
+** is because when memory debugging is turned on, these two functions are 
+** called via macros that record the current file and line number in the
+** ThreadData structure.
+*/
 char *sqlite3StrDup(const char *z){
   char *zNew;
   if( z==0 ) return 0;
-  zNew = sqliteMallocRaw(strlen(z)+1);
+  zNew = sqlite3MallocRaw(strlen(z)+1, 1);
   if( zNew ) strcpy(zNew, z);
   return zNew;
 }
 char *sqlite3StrNDup(const char *z, int n){
   char *zNew;
   if( z==0 ) return 0;
-  zNew = sqliteMallocRaw(n+1);
+  zNew = sqlite3MallocRaw(n+1, 1);
   if( zNew ){
     memcpy(zNew, z, n);
     zNew[n] = 0;
   }
   return zNew;
 }
-#endif /* !defined(SQLITE_MEMDEBUG) */
 
 /*
-** Reallocate a buffer to a different size.  This is similar to
-** sqliteRealloc() except that if the allocation fails the buffer
-** is freed.
-*/
-void sqlite3ReallocOrFree(void **ppBuf, int newSize){
-  void *pNew = sqliteRealloc(*ppBuf, newSize);
-  if( pNew==0 ){
-    sqliteFree(*ppBuf);
-  }
-  *ppBuf = pNew;
-}
-
-/*
 ** Create a string from the 2nd and subsequent arguments (up to the
 ** first NULL argument), store the string in memory obtained from
 ** sqliteMalloc() and make the pointer indicated by the 1st argument
@@ -411,11 +768,6 @@
     zResult += strlen(zResult);
   }
   va_end(ap);
-#ifdef SQLITE_MEMDEBUG
-#if SQLITE_MEMDEBUG>1
-  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
-#endif
-#endif
 }
 
 /*
@@ -440,7 +792,7 @@
 ** to NULL.
 */
 void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
-  if( db && (db->pErr || (db->pErr = sqlite3ValueNew())) ){
+  if( db && (db->pErr || (db->pErr = sqlite3ValueNew())!=0) ){
     db->errCode = err_code;
     if( zFormat ){
       char *z;
@@ -482,6 +834,15 @@
 }
 
 /*
+** Clear the error message in pParse, if any
+*/
+void sqlite3ErrorClear(Parse *pParse){
+  sqliteFree(pParse->zErrMsg);
+  pParse->zErrMsg = 0;
+  pParse->nErr = 0;
+}
+
+/*
 ** Convert an SQL-style quoted string into a normal string by removing
 ** the quote characters.  The conversion is done in-place.  If the
 ** input does not begin with a quote character, then this routine
@@ -522,6 +883,7 @@
 ** lower-case character. 
 */
 const unsigned char sqlite3UpperToLower[] = {
+#ifdef SQLITE_ASCII
       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, 45, 46, 47, 48, 49, 50, 51, 52, 53,
@@ -537,6 +899,25 @@
     216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
     234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
     252,253,254,255
+#endif
+#ifdef SQLITE_EBCDIC
+      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 0x */
+     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
+     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
+     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
+     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
+     80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
+     96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
+    112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
+    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
+    144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
+    160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
+    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
+    192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
+    208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
+    224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
+    239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
+#endif
 };
 #define UpperToLower sqlite3UpperToLower
 
@@ -606,9 +987,11 @@
 ** for SQL.  So this routine always uses "." regardless of locale.
 */
 int sqlite3AtoF(const char *z, double *pResult){
+#ifndef SQLITE_OMIT_FLOATING_POINT
   int sign = 1;
   const char *zBegin = z;
   LONGDOUBLE_TYPE v1 = 0.0;
+  while( isspace(*z) ) z++;
   if( *z=='-' ){
     sign = -1;
     z++;
@@ -656,6 +1039,9 @@
   }
   *pResult = sign<0 ? -v1 : v1;
   return z - zBegin;
+#else
+  return sqlite3atoi64(z, pResult);
+#endif /* SQLITE_OMIT_FLOATING_POINT */
 }
 
 /*
@@ -673,6 +1059,7 @@
   i64 v = 0;
   int neg;
   int i, c;
+  while( isspace(*zNum) ) zNum++;
   if( *zNum=='-' ){
     neg = 1;
     zNum++;
@@ -1003,3 +1390,95 @@
   return p;
 }
 #endif
+
+/*
+** Return a pointer to the ThreadData associated with the calling thread.
+*/
+ThreadData *sqlite3ThreadData(){
+  ThreadData *p = (ThreadData*)sqlite3OsThreadSpecificData(1);
+  if( !p ){
+    sqlite3FailedMalloc();
+  }
+  return p;
+}
+
+/*
+** Return a pointer to the ThreadData associated with the calling thread.
+** If no ThreadData has been allocated to this thread yet, return a pointer
+** to a substitute ThreadData structure that is all zeros. 
+*/
+const ThreadData *sqlite3ThreadDataReadOnly(){
+  static const ThreadData zeroData = {0};  /* Initializer to silence warnings
+                                           ** from broken compilers */
+  const ThreadData *pTd = sqlite3OsThreadSpecificData(0);
+  return pTd ? pTd : &zeroData;
+}
+
+/*
+** Check to see if the ThreadData for this thread is all zero.  If it
+** is, then deallocate it. 
+*/
+void sqlite3ReleaseThreadData(){
+  sqlite3OsThreadSpecificData(-1);
+}
+
+/*
+** This function must be called before exiting any API function (i.e. 
+** returning control to the user) that has called sqlite3Malloc or
+** sqlite3Realloc.
+**
+** The returned value is normally a copy of the second argument to this
+** function. However, if a malloc() failure has occured since the previous
+** invocation SQLITE_NOMEM is returned instead. 
+**
+** If the first argument, db, is not NULL and a malloc() error has occured,
+** then the connection error-code (the value returned by sqlite3_errcode())
+** is set to SQLITE_NOMEM.
+*/
+static int mallocHasFailed = 0;
+int sqlite3ApiExit(sqlite3* db, int rc){
+  if( sqlite3MallocFailed() ){
+    mallocHasFailed = 0;
+    sqlite3OsLeaveMutex();
+    sqlite3Error(db, SQLITE_NOMEM, 0);
+    rc = SQLITE_NOMEM;
+  }
+  return rc;
+}
+
+/* 
+** Return true is a malloc has failed in this thread since the last call
+** to sqlite3ApiExit(), or false otherwise.
+*/
+int sqlite3MallocFailed(){
+  return (mallocHasFailed && sqlite3OsInMutex(1));
+}
+
+/* 
+** Set the "malloc has failed" condition to true for this thread.
+*/
+void sqlite3FailedMalloc(){
+  sqlite3OsEnterMutex();
+  assert( mallocHasFailed==0 );
+  mallocHasFailed = 1;
+}
+
+#ifdef SQLITE_MEMDEBUG
+/*
+** This function sets a flag in the thread-specific-data structure that will
+** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
+*/
+void sqlite3MallocDisallow(){
+  assert( sqlite3_mallocDisallowed>=0 );
+  sqlite3_mallocDisallowed++;
+}
+
+/*
+** This function clears the flag set in the thread-specific-data structure set
+** by sqlite3MallocDisallow().
+*/
+void sqlite3MallocAllow(){
+  assert( sqlite3_mallocDisallowed>0 );
+  sqlite3_mallocDisallowed--;
+}
+#endif

Modified: packages/libdbd-sqlite3-perl/trunk/vacuum.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/vacuum.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/vacuum.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -14,9 +14,10 @@
 ** Most of the code in this file may be omitted by defining the
 ** SQLITE_OMIT_VACUUM macro.
 **
-** $Id: vacuum.c,v 1.45 2005/06/07 09:21:07 danielk1977 Exp $
+** $Id: vacuum.c,v 1.59 2006/02/24 02:53:50 drh Exp $
 */
 #include "sqliteInt.h"
+#include "vdbeInt.h"
 #include "os.h"
 
 #ifndef SQLITE_OMIT_VACUUM
@@ -42,7 +43,7 @@
   if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
     return sqlite3_errcode(db);
   }
-  while( SQLITE_ROW==sqlite3_step(pStmt) );
+  while( SQLITE_ROW==sqlite3_step(pStmt) ){}
   return sqlite3_finalize(pStmt);
 }
 
@@ -58,7 +59,7 @@
   if( rc!=SQLITE_OK ) return rc;
 
   while( SQLITE_ROW==sqlite3_step(pStmt) ){
-    rc = execSql(db, sqlite3_column_text(pStmt, 0));
+    rc = execSql(db, (char*)sqlite3_column_text(pStmt, 0));
     if( rc!=SQLITE_OK ){
       sqlite3_finalize(pStmt);
       return rc;
@@ -80,7 +81,7 @@
 ** with 2.0.0, SQLite no longer uses GDBM so this command has
 ** become a no-op.
 */
-void sqlite3Vacuum(Parse *pParse, Token *pTableName){
+void sqlite3Vacuum(Parse *pParse){
   Vdbe *v = sqlite3GetVdbe(pParse);
   if( v ){
     sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
@@ -100,11 +101,12 @@
   Btree *pMain;           /* The database being vacuumed */
   Btree *pTemp;
   char *zSql = 0;
-  int writeschema_flag;   /* Saved value of the write-schema flag */
+  int saved_flags;       /* Saved value of the db->flags */
+  Db *pDb = 0;           /* Database to detach at end of vacuum */
 
   /* Save the current value of the write-schema flag before setting it. */
-  writeschema_flag = db->flags&SQLITE_WriteSchema;
-  db->flags |= SQLITE_WriteSchema;
+  saved_flags = db->flags;
+  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
 
   if( !db->autoCommit ){
     sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
@@ -164,19 +166,23 @@
   sqliteFree(zSql);
   zSql = 0;
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+  pDb = &db->aDb[db->nDb-1];
   assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
   pTemp = db->aDb[db->nDb-1].pBt;
   sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
      sqlite3BtreeGetReserve(pMain));
   assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
-  execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
+  rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
+  if( rc!=SQLITE_OK ){
+    goto end_of_vacuum;
+  }
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
   sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain));
 #endif
 
   /* Begin a transaction */
-  rc = execSql(db, "BEGIN;");
+  rc = execSql(db, "BEGIN EXCLUSIVE;");
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
   /* Query the schema of the main database. Create a mirror schema
@@ -247,7 +253,7 @@
   ** opened for writing. This way, the SQL transaction used to create the
   ** temporary database never needs to be committed.
   */
-  if( sqlite3BtreeIsInTrans(pTemp) ){
+  if( rc==SQLITE_OK ){
     u32 meta;
     int i;
 
@@ -264,26 +270,27 @@
        6, 0,    /* Preserve the user version */
     };
 
-    assert( 0==sqlite3BtreeIsInTrans(pMain) );
-    rc = sqlite3BtreeBeginTrans(pMain, 1);
-    if( rc!=SQLITE_OK ) goto end_of_vacuum;
+    assert( 1==sqlite3BtreeIsInTrans(pTemp) );
+    assert( 1==sqlite3BtreeIsInTrans(pMain) );
 
     /* Copy Btree meta values */
     for(i=0; i<sizeof(aCopy)/sizeof(aCopy[0]); i+=2){
       rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
       if( rc!=SQLITE_OK ) goto end_of_vacuum;
       rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
+      if( rc!=SQLITE_OK ) goto end_of_vacuum;
     }
 
     rc = sqlite3BtreeCopyFile(pMain, pTemp);
     if( rc!=SQLITE_OK ) goto end_of_vacuum;
+    rc = sqlite3BtreeCommit(pTemp);
+    if( rc!=SQLITE_OK ) goto end_of_vacuum;
     rc = sqlite3BtreeCommit(pMain);
   }
 
 end_of_vacuum:
-  /* Restore the original value of the write-schema flag. */
-  db->flags &= ~SQLITE_WriteSchema;
-  db->flags |= writeschema_flag;
+  /* Restore the original value of db->flags */
+  db->flags = saved_flags;
 
   /* Currently there is an SQL level transaction open on the vacuum
   ** database. No locks are held on any other files (since the main file
@@ -293,16 +300,28 @@
   ** is closed by the DETACH.
   */
   db->autoCommit = 1;
-  if( rc==SQLITE_OK ){
-    rc = execSql(db, "DETACH vacuum_db;");
-  }else{
-    execSql(db, "DETACH vacuum_db;");
+
+  if( pDb ){
+    sqlite3MallocDisallow();
+    sqlite3BtreeClose(pDb->pBt);
+    sqlite3MallocAllow();
+    pDb->pBt = 0;
+    pDb->pSchema = 0;
   }
+
+  /* If one of the execSql() calls above returned SQLITE_NOMEM, then the
+  ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()).
+  ** Fix this so the flag and return code match.
+  */
+  if( rc==SQLITE_NOMEM ){
+    sqlite3MallocFailed();
+  }
+
   if( zTemp ){
     sqlite3OsDelete(zTemp);
     sqliteFree(zTemp);
   }
-  if( zSql ) sqliteFree( zSql );
+  sqliteFree( zSql );
   sqlite3ResetInternalSchema(db, 0);
 #endif
 

Modified: packages/libdbd-sqlite3-perl/trunk/vdbe.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/vdbe.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/vdbe.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -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.491 2005/09/20 17:42:23 drh Exp $
+** $Id: vdbe.c,v 1.548 2006/03/22 22:10:08 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -101,6 +101,22 @@
 */
 #define Dynamicify(P,enc) sqlite3VdbeMemDynamicify(P)
 
+/*
+** The header of a record consists of a sequence variable-length integers.
+** These integers are almost always small and are encoded as a single byte.
+** The following macro takes advantage this fact to provide a fast decode
+** of the integers in a record header.  It is faster for the common case
+** where the integer is a single byte.  It is a little slower when the
+** integer is two or more bytes.  But overall it is faster.
+**
+** The following expressions are equivalent:
+**
+**     x = sqlite3GetVarint32( A, &B );
+**
+**     x = GetVarint( A, B );
+**
+*/
+#define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))
 
 /*
 ** An ephemeral string value (signified by the MEM_Ephem flag) contains
@@ -118,23 +134,6 @@
        && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
 
 /*
-** Convert the given stack entity into a integer if it isn't one
-** already.
-**
-** Any prior string or real representation is invalidated.  
-** NULLs are converted into 0.
-*/
-#define Integerify(P) sqlite3VdbeMemIntegerify(P)
-
-/*
-** Convert P so that it has type MEM_Real.
-**
-** Any prior string or integer representation is invalidated.
-** NULLs are converted into 0.0.
-*/
-#define Realify(P) sqlite3VdbeMemRealify(P)
-
-/*
 ** Argument pMem points at a memory cell that will be passed to a
 ** user-defined function or returned to the user as the result of a query.
 ** The second argument, 'db_enc' is the text encoding used by the vdbe for
@@ -177,30 +176,64 @@
 ** Allocate cursor number iCur.  Return a pointer to it.  Return NULL
 ** if we run out of memory.
 */
-static Cursor *allocateCursor(Vdbe *p, int iCur){
+static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){
   Cursor *pCx;
   assert( iCur<p->nCursor );
   if( p->apCsr[iCur] ){
     sqlite3VdbeFreeCursor(p->apCsr[iCur]);
   }
   p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
+  if( pCx ){
+    pCx->iDb = iDb;
+  }
   return pCx;
 }
 
 /*
-** Apply any conversion required by the supplied column affinity to
-** memory cell pRec. affinity may be one of:
+** Try to convert a value into a numeric representation if we can
+** do so without loss of information.  In other words, if the string
+** looks like a number, convert it into a number.  If it does not
+** look like a number, leave it alone.
+*/
+static void applyNumericAffinity(Mem *pRec){
+  if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
+    int realnum;
+    sqlite3VdbeMemNulTerminate(pRec);
+    if( (pRec->flags&MEM_Str)
+         && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
+      i64 value;
+      sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
+      if( !realnum && sqlite3atoi64(pRec->z, &value) ){
+        sqlite3VdbeMemRelease(pRec);
+        pRec->i = value;
+        pRec->flags = MEM_Int;
+      }else{
+        sqlite3VdbeMemRealify(pRec);
+      }
+    }
+  }
+}
+
+/*
+** Processing is determine by the affinity parameter:
 **
-** SQLITE_AFF_NUMERIC
-** SQLITE_AFF_TEXT
-** SQLITE_AFF_NONE
-** SQLITE_AFF_INTEGER
+** SQLITE_AFF_INTEGER:
+** SQLITE_AFF_REAL:
+** SQLITE_AFF_NUMERIC:
+**    Try to convert pRec to an integer representation or a 
+**    floating-point representation if an integer representation
+**    is not possible.  Note that the integer representation is
+**    always preferred, even if the affinity is REAL, because
+**    an integer representation is more space efficient on disk.
 **
+** SQLITE_AFF_TEXT:
+**    Convert pRec to a text representation.
+**
+** SQLITE_AFF_NONE:
+**    No-op.  pRec is unchanged.
 */
 static void applyAffinity(Mem *pRec, char affinity, u8 enc){
-  if( affinity==SQLITE_AFF_NONE ){
-    /* do nothing */
-  }else if( affinity==SQLITE_AFF_TEXT ){
+  if( affinity==SQLITE_AFF_TEXT ){
     /* Only attempt the conversion to TEXT if there is an integer or real
     ** representation (blob and NULL do not get converted) but no string
     ** representation.
@@ -209,36 +242,32 @@
       sqlite3VdbeMemStringify(pRec, enc);
     }
     pRec->flags &= ~(MEM_Real|MEM_Int);
-  }else{
-    if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){
-      /* pRec does not have a valid integer or real representation. 
-      ** Attempt a conversion if pRec has a string representation and
-      ** it looks like a number.
-      */
-      int realnum;
-      sqlite3VdbeMemNulTerminate(pRec);
-      if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){
-        if( realnum ){
-          Realify(pRec);
-        }else{
-          Integerify(pRec);
-        }
-      }
+  }else if( affinity!=SQLITE_AFF_NONE ){
+    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
+             || affinity==SQLITE_AFF_NUMERIC );
+    applyNumericAffinity(pRec);
+    if( pRec->flags & MEM_Real ){
+      sqlite3VdbeIntegerAffinity(pRec);
     }
-
-    if( affinity==SQLITE_AFF_INTEGER ){
-      /* For INTEGER affinity, try to convert a real value to an int */
-      if( (pRec->flags&MEM_Real) && !(pRec->flags&MEM_Int) ){
-        pRec->i = pRec->r;
-        if( ((double)pRec->i)==pRec->r ){
-          pRec->flags |= MEM_Int;
-        }
-      }
-    }
   }
 }
 
 /*
+** Try to convert the type of a function argument or a result column
+** into a numeric representation.  Use either INTEGER or REAL whichever
+** is appropriate.  But only do the conversion if it is possible without
+** loss of information and return the revised type of the argument.
+**
+** This is an EXPERIMENTAL api and is subject to change or removal.
+*/
+int sqlite3_value_numeric_type(sqlite3_value *pVal){
+  Mem *pMem = (Mem*)pVal;
+  applyNumericAffinity(pMem);
+  storeTypeInfo(pMem, 0);
+  return pMem->type;
+}
+
+/*
 ** Exported version of applyAffinity(). This one works on sqlite3_value*, 
 ** not the internal Mem* type.
 */
@@ -251,7 +280,7 @@
 ** Write a nice string representation of the contents of cell pMem
 ** into buffer zBuf, length nBuf.
 */
-void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf){
+void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
   char *zCsr = zBuf;
   int f = pMem->flags;
 
@@ -388,6 +417,7 @@
   Op *pOp;                   /* Current operation */
   int rc = SQLITE_OK;        /* Value to return */
   sqlite3 *db = p->db;       /* The database */
+  u8 encoding = ENC(db);     /* The database encoding */
   Mem *pTos;                 /* Top entry in the operand stack */
 #ifdef VDBE_PROFILE
   unsigned long long start;  /* CPU clock count at start of opcode */
@@ -402,11 +432,15 @@
 
   if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
   assert( db->magic==SQLITE_MAGIC_BUSY );
+  pTos = p->pTos;
+  if( p->rc==SQLITE_NOMEM ){
+    /* This happens if a malloc() inside a call to sqlite3_column_text() or
+    ** sqlite3_column_text16() failed.  */
+    goto no_mem;
+  }
   assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
   p->rc = SQLITE_OK;
   assert( p->explain==0 );
-  pTos = p->pTos;
-  if( sqlite3_malloc_failed ) goto no_mem;
   if( p->popStack ){
     popStack(&pTos, p->popStack);
     p->popStack = 0;
@@ -417,7 +451,7 @@
   for(pc=p->pc; rc==SQLITE_OK; pc++){
     assert( pc>=0 && pc<p->nOp );
     assert( pTos<=&p->aStack[pc] );
-    if( sqlite3_malloc_failed ) goto no_mem;
+    if( sqlite3MallocFailed() ) goto no_mem;
 #ifdef VDBE_PROFILE
     origPc = pc;
     start = hwtime();
@@ -644,24 +678,25 @@
   pTos->enc = SQLITE_UTF8;
   pTos->r = sqlite3VdbeRealValue(pTos);
   pTos->flags |= MEM_Real;
-  sqlite3VdbeChangeEncoding(pTos, db->enc);
+  sqlite3VdbeChangeEncoding(pTos, encoding);
   break;
 }
 
 /* Opcode: String8 * * P3
 **
-** P3 points to a nul terminated UTF-8 string. This opcode is transformed
+** P3 points to a nul terminated UTF-8 string. This opcode is transformed 
 ** into an OP_String before it is executed for the first time.
 */
 case OP_String8: {         /* same as TK_STRING */
-#ifndef SQLITE_OMIT_UTF16
+  assert( pOp->p3!=0 );
   pOp->opcode = OP_String;
+  pOp->p1 = strlen(pOp->p3);
 
-  assert( pOp->p3!=0 );
-  if( db->enc!=SQLITE_UTF8 ){
+#ifndef SQLITE_OMIT_UTF16
+  if( encoding!=SQLITE_UTF8 ){
     pTos++;
     sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
-    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem;
+    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
     if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
     pTos->flags &= ~(MEM_Dyn);
     pTos->flags |= MEM_Static;
@@ -670,34 +705,24 @@
     }
     pOp->p3type = P3_DYNAMIC;
     pOp->p3 = pTos->z;
+    pOp->p1 = pTos->n;
     break;
   }
 #endif
   /* Otherwise fall through to the next case, OP_String */
 }
   
-/* Opcode: String * * P3
+/* Opcode: String P1 * P3
 **
-** The string value P3 is pushed onto the stack.  If P3==0 then a
-** NULL is pushed onto the stack. P3 is assumed to be a nul terminated
-** string encoded with the database native encoding.
+** The string value P3 of length P1 (bytes) is pushed onto the stack.
 */
 case OP_String: {
   pTos++;
   assert( pOp->p3!=0 );
   pTos->flags = MEM_Str|MEM_Static|MEM_Term;
   pTos->z = pOp->p3;
-#ifndef SQLITE_OMIT_UTF16
-  if( db->enc==SQLITE_UTF8 ){
-    pTos->n = strlen(pTos->z);
-  }else{
-    pTos->n  = sqlite3utf16ByteLen(pTos->z, -1);
-  }
-#else
-  assert( db->enc==SQLITE_UTF8 );
-  pTos->n = strlen(pTos->z);
-#endif
-  pTos->enc = db->enc;
+  pTos->n = pOp->p1;
+  pTos->enc = encoding;
   break;
 }
 
@@ -868,20 +893,45 @@
 
 /* Opcode: Callback P1 * *
 **
-** Pop P1 values off the stack and form them into an array.  Then
-** invoke the callback function using the newly formed array as the
-** 3rd parameter.
+** The top P1 values on the stack represent a single result row from
+** a query.  This opcode causes the sqlite3_step() call to terminate
+** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
+** structure to provide access to the top P1 values as the result
+** row.  When the sqlite3_step() function is run again, the top P1
+** values will be automatically popped from the stack before the next
+** instruction executes.
 */
 case OP_Callback: {            /* no-push */
-  int i;
+  Mem *pMem;
+  Mem *pFirstColumn;
   assert( p->nResColumn==pOp->p1 );
 
-  for(i=0; i<pOp->p1; i++){
-    Mem *pVal = &pTos[0-i];
-    sqlite3VdbeMemNulTerminate(pVal);
-    storeTypeInfo(pVal, db->enc);
+  /* Data in the pager might be moved or changed out from under us
+  ** in between the return from this sqlite3_step() call and the
+  ** next call to sqlite3_step().  So deephermeralize everything on 
+  ** the stack.  Note that ephemeral data is never stored in memory 
+  ** cells so we do not have to worry about them.
+  */
+  pFirstColumn = &pTos[0-pOp->p1];
+  for(pMem = p->aStack; pMem<pFirstColumn; pMem++){
+    Deephemeralize(pMem);
   }
 
+  /* Invalidate all ephemeral cursor row caches */
+  p->cacheCtr = (p->cacheCtr + 2)|1;
+
+  /* Make sure the results of the current row are \000 terminated
+  ** and have an assigned type.  The results are deephemeralized as
+  ** as side effect.
+  */
+  for(; pMem<=pTos; pMem++ ){
+    sqlite3VdbeMemNulTerminate(pMem);
+    storeTypeInfo(pMem, encoding);
+  }
+
+  /* Set up the statement structure so that it will pop the current
+  ** results from the stack when the statement returns.
+  */
   p->resOnStack = 1;
   p->nCallback++;
   p->popStack = pOp->p1;
@@ -917,7 +967,7 @@
       nByte = -1;
       break;
     }
-    Stringify(pTerm, db->enc);
+    Stringify(pTerm, encoding);
     nByte += pTerm->n;
   }
 
@@ -956,7 +1006,7 @@
     pTos->n = j;
     pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
     pTos->xDel = 0;
-    pTos->enc = db->enc;
+    pTos->enc = encoding;
     pTos->z = zNew;
   }
   break;
@@ -1014,8 +1064,10 @@
 case OP_Divide:                /* same as TK_SLASH, no-push */
 case OP_Remainder: {           /* same as TK_REM, no-push */
   Mem *pNos = &pTos[-1];
+  int flags;
   assert( pNos>=p->aStack );
-  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
+  flags = pTos->flags | pNos->flags;
+  if( (flags & MEM_Null)!=0 ){
     Release(pTos);
     pTos--;
     Release(pTos);
@@ -1070,6 +1122,9 @@
     Release(pTos);
     pTos->r = b;
     pTos->flags = MEM_Real;
+    if( (flags & MEM_Real)==0 ){
+      sqlite3VdbeIntegerAffinity(pTos);
+    }
   }
   break;
 
@@ -1125,7 +1180,7 @@
   pArg = &pTos[1-n];
   for(i=0; i<n; i++, pArg++){
     apVal[i] = pArg;
-    storeTypeInfo(pArg, db->enc);
+    storeTypeInfo(pArg, encoding);
   }
 
   assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );
@@ -1150,7 +1205,7 @@
   if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   (*ctx.pFunc->xFunc)(&ctx, n, apVal);
   if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
-  if( sqlite3_malloc_failed ) goto no_mem;
+  if( sqlite3MallocFailed() ) goto no_mem;
   popStack(&pTos, n);
 
   /* If any auxilary data functions have been called by this user function,
@@ -1162,22 +1217,17 @@
     pOp->p3type = P3_VDBEFUNC;
   }
 
+  /* If the function returned an error, throw an exception */
+  if( ctx.isError ){
+    sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);
+    rc = SQLITE_ERROR;
+  }
+
   /* Copy the result of the function to the top of the stack */
-  sqlite3VdbeChangeEncoding(&ctx.s, db->enc);
+  sqlite3VdbeChangeEncoding(&ctx.s, encoding);
   pTos++;
   pTos->flags = 0;
   sqlite3VdbeMemMove(pTos, &ctx.s);
-
-  /* If the function returned an error, throw an exception */
-  if( ctx.isError ){
-    if( !(pTos->flags&MEM_Str) ){
-      sqlite3SetString(&p->zErrMsg, "user function error", (char*)0);
-    }else{
-      sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pTos), (char*)0);
-      sqlite3VdbeChangeEncoding(pTos, db->enc);
-    }
-    rc = SQLITE_ERROR;
-  }
   break;
 }
 
@@ -1214,7 +1264,7 @@
 case OP_ShiftLeft:              /* same as TK_LSHIFT, no-push */
 case OP_ShiftRight: {           /* same as TK_RSHIFT, no-push */
   Mem *pNos = &pTos[-1];
-  int a, b;
+  i64 a, b;
 
   assert( pNos>=p->aStack );
   if( (pTos->flags | pNos->flags) & MEM_Null ){
@@ -1249,7 +1299,7 @@
 */
 case OP_AddImm: {            /* no-push */
   assert( pTos>=p->aStack );
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pTos);
   pTos->i += pOp->p1;
   break;
 }
@@ -1267,7 +1317,7 @@
 case OP_ForceInt: {            /* no-push */
   i64 v;
   assert( pTos>=p->aStack );
-  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
   if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
     Release(pTos);
     pTos--;
@@ -1277,7 +1327,8 @@
   if( pTos->flags & MEM_Int ){
     v = pTos->i + (pOp->p1!=0);
   }else{
-    Realify(pTos);
+    /* FIX ME:  should this not be assert( pTos->flags & MEM_Real ) ??? */
+    sqlite3VdbeMemRealify(pTos);
     v = (int)pTos->r;
     if( pTos->r>(double)v ) v++;
     if( pOp->p1 && pTos->r==(double)v ) v++;
@@ -1301,7 +1352,7 @@
 */
 case OP_MustBeInt: {            /* no-push */
   assert( pTos>=p->aStack );
-  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
   if( (pTos->flags & MEM_Int)==0 ){
     if( pOp->p2==0 ){
       rc = SQLITE_MISMATCH;
@@ -1317,67 +1368,39 @@
   break;
 }
 
-#ifndef SQLITE_OMIT_CAST
-/* Opcode: ToInt * * *
+/* Opcode: RealAffinity * * *
 **
-** Force the value on the top of the stack to be an integer.  If
-** The value is currently a real number, drop its fractional part.
-** If the value is text or blob, try to convert it to an integer using the
-** equivalent of atoi() and store 0 if no such conversion is possible.
+** If the top of the stack is an integer, convert it to a real value.
 **
-** A NULL value is not changed by this routine.  It remains NULL.
+** This opcode is used when extracting information from a column that
+** has REAL affinity.  Such column values may still be stored as
+** integers, for space efficiency, but after extraction we want them
+** to have only a real value.
 */
-case OP_ToInt: {                  /* no-push */
+case OP_RealAffinity: {                  /* no-push */
   assert( pTos>=p->aStack );
-  if( pTos->flags & MEM_Null ) break;
-  assert( MEM_Str==(MEM_Blob>>3) );
-  pTos->flags |= (pTos->flags&MEM_Blob)>>3;
-  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
-  sqlite3VdbeMemIntegerify(pTos);
-  break;
-}
-
-/* Opcode: ToNumeric * * *
-**
-** Force the value on the top of the stack to be numeric (either an
-** integer or a floating-point number.
-** If the value is text or blob, try to convert it to an using the
-** equivalent of atoi() or atof() and store 0 if no such conversion 
-** is possible.
-**
-** A NULL value is not changed by this routine.  It remains NULL.
-*/
-case OP_ToNumeric: {                  /* no-push */
-  assert( pTos>=p->aStack );
-  if( pTos->flags & MEM_Null ) break;
-  assert( MEM_Str==(MEM_Blob>>3) );
-  pTos->flags |= (pTos->flags&MEM_Blob)>>3;
-  applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc);
-  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
+  if( pTos->flags & MEM_Int ){
     sqlite3VdbeMemRealify(pTos);
-  }else{
-    sqlite3VdbeMemRelease(pTos);
   }
-  assert( (pTos->flags & MEM_Dyn)==0 );
-  pTos->flags &= (MEM_Int|MEM_Real);
   break;
 }
 
+#ifndef SQLITE_OMIT_CAST
 /* Opcode: ToText * * *
 **
 ** Force the value on the top of the stack to be text.
-** If the value is numeric, convert it to an using the
+** If the value is numeric, convert it to a string using the
 ** equivalent of printf().  Blob values are unchanged and
 ** are afterwards simply interpreted as text.
 **
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
-case OP_ToText: {                  /* no-push */
+case OP_ToText: {                  /* same as TK_TO_TEXT, no-push */
   assert( pTos>=p->aStack );
   if( pTos->flags & MEM_Null ) break;
   assert( MEM_Str==(MEM_Blob>>3) );
   pTos->flags |= (pTos->flags&MEM_Blob)>>3;
-  applyAffinity(pTos, SQLITE_AFF_TEXT, db->enc);
+  applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
   assert( pTos->flags & MEM_Str );
   pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
   break;
@@ -1392,19 +1415,73 @@
 **
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
-case OP_ToBlob: {                  /* no-push */
+case OP_ToBlob: {                  /* same as TK_TO_BLOB, no-push */
   assert( pTos>=p->aStack );
   if( pTos->flags & MEM_Null ) break;
   if( (pTos->flags & MEM_Blob)==0 ){
-    applyAffinity(pTos, SQLITE_AFF_TEXT, db->enc);
+    applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
     assert( pTos->flags & MEM_Str );
     pTos->flags |= MEM_Blob;
   }
   pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Str);
   break;
 }
+
+/* Opcode: ToNumeric * * *
+**
+** Force the value on the top of the stack to be numeric (either an
+** integer or a floating-point number.)
+** If the value is text or blob, try to convert it to an using the
+** equivalent of atoi() or atof() and store 0 if no such conversion 
+** is possible.
+**
+** A NULL value is not changed by this routine.  It remains NULL.
+*/
+case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, no-push */
+  assert( pTos>=p->aStack );
+  if( (pTos->flags & MEM_Null)==0 ){
+    sqlite3VdbeMemNumerify(pTos);
+  }
+  break;
+}
 #endif /* SQLITE_OMIT_CAST */
 
+/* Opcode: ToInt * * *
+**
+** Force the value on the top of the stack to be an integer.  If
+** The value is currently a real number, drop its fractional part.
+** If the value is text or blob, try to convert it to an integer using the
+** equivalent of atoi() and store 0 if no such conversion is possible.
+**
+** A NULL value is not changed by this routine.  It remains NULL.
+*/
+case OP_ToInt: {                  /* same as TK_TO_INT, no-push */
+  assert( pTos>=p->aStack );
+  if( (pTos->flags & MEM_Null)==0 ){
+    sqlite3VdbeMemIntegerify(pTos);
+  }
+  break;
+}
+
+#ifndef SQLITE_OMIT_CAST
+/* Opcode: ToReal * * *
+**
+** Force the value on the top of the stack to be a floating point number.
+** If The value is currently an integer, convert it.
+** If the value is text or blob, try to convert it to an integer using the
+** equivalent of atoi() and store 0 if no such conversion is possible.
+**
+** A NULL value is not changed by this routine.  It remains NULL.
+*/
+case OP_ToReal: {                  /* same as TK_TO_REAL, no-push */
+  assert( pTos>=p->aStack );
+  if( (pTos->flags & MEM_Null)==0 ){
+    sqlite3VdbeMemRealify(pTos);
+  }
+  break;
+}
+#endif /* SQLITE_OMIT_CAST */
+
 /* Opcode: Eq P1 P2 P3
 **
 ** Pop the top two elements from the stack.  If they are equal, then
@@ -1422,7 +1499,8 @@
 ** 0x200 is set but is NULL when the 0x200 bit of P1 is clear.
 **
 ** The least significant byte of P1 (mask 0xff) must be an affinity character -
-** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
+** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made 
+** to coerce both values
 ** according to the affinity before the comparison is made. If the byte is
 ** 0x00, then numeric affinity is used.
 **
@@ -1522,8 +1600,8 @@
 
   affinity = pOp->p1 & 0xFF;
   if( affinity ){
-    applyAffinity(pNos, affinity, db->enc);
-    applyAffinity(pTos, affinity, db->enc);
+    applyAffinity(pNos, affinity, encoding);
+    applyAffinity(pTos, affinity, encoding);
   }
 
   assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
@@ -1571,13 +1649,13 @@
   if( pTos->flags & MEM_Null ){
     v1 = 2;
   }else{
-    Integerify(pTos);
+    sqlite3VdbeMemIntegerify(pTos);
     v1 = pTos->i==0;
   }
   if( pNos->flags & MEM_Null ){
     v2 = 2;
   }else{
-    Integerify(pNos);
+    sqlite3VdbeMemIntegerify(pNos);
     v2 = pNos->i==0;
   }
   if( pOp->opcode==OP_And ){
@@ -1614,6 +1692,7 @@
 case OP_AbsValue: {
   assert( pTos>=p->aStack );
   if( pTos->flags & MEM_Real ){
+    neg_abs_real_case:
     Release(pTos);
     if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
       pTos->r = -pTos->r;
@@ -1628,11 +1707,8 @@
   }else if( pTos->flags & MEM_Null ){
     /* Do nothing */
   }else{
-    Realify(pTos);
-    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
-      pTos->r = -pTos->r;
-    }
-    pTos->flags = MEM_Real;
+    sqlite3VdbeMemNumerify(pTos);
+    goto neg_abs_real_case;
   }
   break;
 }
@@ -1646,7 +1722,7 @@
 case OP_Not: {                /* same as TK_NOT, no-push */
   assert( pTos>=p->aStack );
   if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pTos);
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos->i = !pTos->i;
   pTos->flags = MEM_Int;
@@ -1662,7 +1738,7 @@
 case OP_BitNot: {             /* same as TK_BITNOT, no-push */
   assert( pTos>=p->aStack );
   if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pTos);
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos->i = ~pTos->i;
   pTos->flags = MEM_Int;
@@ -1795,13 +1871,6 @@
 ** If the KeyAsData opcode has previously executed on this cursor, then the
 ** field might be extracted from the key rather than the data.
 **
-** If P1 is negative, then the record is stored on the stack rather than in
-** a table.  For P1==-1, the top of the stack is used.  For P1==-2, the
-** next on the stack is used.  And so forth.  The value pushed is always
-** just a pointer into the record which is stored further down on the
-** stack.  The column value is not copied. The number of columns in the
-** record is stored on the stack just above the record itself.
-**
 ** If the column contains fewer than P2 fields, then push a NULL.  Or
 ** if P3 is of type P3_MEM, then push the P3 value.  The P3 value will
 ** be default value for a column that has been added using the ALTER TABLE
@@ -1819,10 +1888,7 @@
   u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
   u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
   u32 nField;        /* number of fields in the record */
-  u32 szHdr;         /* Number of bytes in the record header */
   int len;           /* The length of the serialized data for the column */
-  int offset = 0;    /* Offset into the data */
-  int idx;           /* Index into the header */
   int i;             /* Loop counter */
   char *zData;       /* Part of the record being decoded */
   Mem sMem;          /* For storing the record being decoded */
@@ -1836,31 +1902,19 @@
   ** bytes in the record.
   **
   ** zRec is set to be the complete text of the record if it is available.
-  ** The complete record text is always available for pseudo-tables and
-  ** when we are decoded a record from the stack.  If the record is stored
-  ** in a cursor, the complete record text might be available in the 
-  ** pC->aRow cache.  Or it might not be.  If the data is unavailable,
-  ** zRec is set to NULL.
+  ** The complete record text is always available for pseudo-tables
+  ** If the record is stored in a cursor, the complete record text
+  ** might be available in the  pC->aRow cache.  Or it might not be.
+  ** If the data is unavailable,  zRec is set to NULL.
   **
   ** We also compute the number of columns in the record.  For cursors,
   ** the number of columns is stored in the Cursor.nField element.  For
   ** records on the stack, the next entry down on the stack is an integer
   ** which is the number of records.
   */
-  assert( p1<0 || p->apCsr[p1]!=0 );
-  if( p1<0 ){
-    /* Take the record off of the stack */
-    Mem *pRec = &pTos[p1];
-    Mem *pCnt = &pRec[-1];
-    assert( pRec>=p->aStack );
-    assert( pRec->flags & MEM_Blob );
-    payloadSize = pRec->n;
-    zRec = pRec->z;
-    assert( pCnt>=p->aStack );
-    assert( pCnt->flags & MEM_Int );
-    nField = pCnt->i;
-    pCrsr = 0;
-  }else if( (pC = p->apCsr[p1])->pCursor!=0 ){
+  pC = p->apCsr[p1];
+  assert( pC!=0 );
+  if( pC->pCursor!=0 ){
     /* The record is stored in a B-Tree */
     rc = sqlite3VdbeCursorMoveto(pC);
     if( rc ) goto abort_due_to_error;
@@ -1868,9 +1922,9 @@
     pCrsr = pC->pCursor;
     if( pC->nullRow ){
       payloadSize = 0;
-    }else if( pC->cacheValid ){
+    }else if( pC->cacheStatus==p->cacheCtr ){
       payloadSize = pC->payloadSize;
-      zRec = pC->aRow;
+      zRec = (char*)pC->aRow;
     }else if( pC->isIndex ){
       i64 payloadSize64;
       sqlite3BtreeKeySize(pCrsr, &payloadSize64);
@@ -1879,16 +1933,14 @@
       sqlite3BtreeDataSize(pCrsr, &payloadSize);
     }
     nField = pC->nField;
-#ifndef SQLITE_OMIT_TRIGGER
   }else if( pC->pseudoTable ){
     /* The record is the sole entry of a pseudo-table */
     payloadSize = pC->nData;
     zRec = pC->pData;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
     assert( payloadSize==0 || zRec!=0 );
     nField = pC->nField;
     pCrsr = 0;
-#endif
   }else{
     zRec = 0;
     payloadSize = 0;
@@ -1898,7 +1950,7 @@
 
   /* If payloadSize is 0, then just push a NULL onto the stack. */
   if( payloadSize==0 ){
-    pTos->flags = MEM_Null;
+    assert( pTos->flags==MEM_Null );
     break;
   }
 
@@ -1907,20 +1959,26 @@
   /* Read and parse the table header.  Store the results of the parse
   ** into the record header cache fields of the cursor.
   */
-  if( pC && pC->cacheValid ){
+  if( pC && pC->cacheStatus==p->cacheCtr ){
     aType = pC->aType;
     aOffset = pC->aOffset;
   }else{
-    int avail;    /* Number of bytes of available data */
-    if( pC && pC->aType ){
-      aType = pC->aType;
-    }else{
-      aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
+    u8 *zIdx;        /* Index into header */
+    u8 *zEndHdr;     /* Pointer to first byte after the header */
+    u32 offset;      /* Offset into the data */
+    int szHdrSz;     /* Size of the header size field at start of record */
+    int avail;       /* Number of bytes of available data */
+
+    aType = pC->aType;
+    if( aType==0 ){
+      pC->aType = aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
     }
-    aOffset = &aType[nField];
     if( aType==0 ){
       goto no_mem;
     }
+    pC->aOffset = aOffset = &aType[nField];
+    pC->payloadSize = payloadSize;
+    pC->cacheStatus = p->cacheCtr;
 
     /* Figure out how many bytes are in the header */
     if( zRec ){
@@ -1937,72 +1995,62 @@
       ** the record.
       */
       if( avail>=payloadSize ){
-        zRec = pC->aRow = zData;
+        zRec = zData;
+        pC->aRow = (u8*)zData;
       }else{
         pC->aRow = 0;
       }
     }
-    idx = sqlite3GetVarint32(zData, &szHdr);
+    assert( zRec!=0 || avail>=payloadSize || avail>=9 );
+    szHdrSz = GetVarint((u8*)zData, offset);
 
-
     /* The KeyFetch() or DataFetch() above are fast and will get the entire
     ** record header in most cases.  But they will fail to get the complete
     ** record header if the record header does not fit on a single page
     ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to
     ** acquire the complete header text.
     */
-    if( !zRec && avail<szHdr ){
-      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->isIndex, &sMem);
+    if( !zRec && avail<offset ){
+      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
       if( rc!=SQLITE_OK ){
         goto op_column_out;
       }
       zData = sMem.z;
     }
+    zEndHdr = (u8 *)&zData[offset];
+    zIdx = (u8 *)&zData[szHdrSz];
 
     /* Scan the header and use it to fill in the aType[] and aOffset[]
     ** arrays.  aType[i] will contain the type integer for the i-th
     ** column and aOffset[i] will contain the offset from the beginning
     ** of the record to the start of the data for the i-th column
     */
-    offset = szHdr;
-    assert( offset>0 );
-    i = 0;
-    while( idx<szHdr && i<nField && offset<=payloadSize ){
-      aOffset[i] = offset;
-      idx += sqlite3GetVarint32(&zData[idx], &aType[i]);
-      offset += sqlite3VdbeSerialTypeLen(aType[i]);
-      i++;
+    for(i=0; i<nField; i++){
+      if( zIdx<zEndHdr ){
+        aOffset[i] = offset;
+        zIdx += GetVarint(zIdx, aType[i]);
+        offset += sqlite3VdbeSerialTypeLen(aType[i]);
+      }else{
+        /* If i is less that nField, then there are less fields in this
+        ** record than SetNumColumns indicated there are columns in the
+        ** table. Set the offset for any extra columns not present in
+        ** the record to 0. This tells code below to push a NULL onto the
+        ** stack instead of deserializing a value from the record.
+        */
+        aOffset[i] = 0;
+      }
     }
     Release(&sMem);
     sMem.flags = MEM_Null;
 
-    /* If i is less that nField, then there are less fields in this
-    ** record than SetNumColumns indicated there are columns in the
-    ** table. Set the offset for any extra columns not present in
-    ** the record to 0. This tells code below to push a NULL onto the
-    ** stack instead of deserializing a value from the record.
+    /* If we have read more header data than was contained in the header,
+    ** or if the end of the last field appears to be past the end of the
+    ** record, then we must be dealing with a corrupt database.
     */
-    while( i<nField ){
-      aOffset[i++] = 0;
-    }
-
-    /* The header should end at the start of data and the data should
-    ** end at last byte of the record. If this is not the case then
-    ** we are dealing with a malformed record.
-    */
-    if( idx!=szHdr || offset!=payloadSize ){
+    if( zIdx>zEndHdr || offset>payloadSize ){
       rc = SQLITE_CORRUPT_BKPT;
       goto op_column_out;
     }
-
-    /* Remember all aType and aColumn information if we have a cursor
-    ** to remember it in. */
-    if( pC ){
-      pC->payloadSize = payloadSize;
-      pC->aType = aType;
-      pC->aOffset = aOffset;
-      pC->cacheValid = 1;
-    }
   }
 
   /* Get the column information. If aOffset[p2] is non-zero, then 
@@ -2023,8 +2071,8 @@
       }
       zData = sMem.z;
     }
-    sqlite3VdbeSerialGet(zData, aType[p2], pTos);
-    pTos->enc = db->enc;
+    sqlite3VdbeSerialGet((u8*)zData, aType[p2], pTos);
+    pTos->enc = encoding;
   }else{
     if( pOp->p3type==P3_MEM ){
       sqlite3VdbeMemShallowCopy(pTos, (Mem *)(pOp->p3), MEM_Static);
@@ -2035,7 +2083,7 @@
 
   /* If we dynamically allocated space to hold the data (in the
   ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
-  ** dynamically allocated space over to the pTos structure rather.
+  ** dynamically allocated space over to the pTos structure.
   ** This prevents a memory copy.
   */
   if( (sMem.flags & MEM_Dyn)!=0 ){
@@ -2052,10 +2100,6 @@
   rc = sqlite3VdbeMemMakeWriteable(pTos);
 
 op_column_out:
-  /* Release the aType[] memory if we are not dealing with cursor */
-  if( !pC || !pC->aType ){
-    sqliteFree(aType);
-  }
   break;
 }
 
@@ -2081,17 +2125,14 @@
 ** field of the index key (i.e. the first character of P3 corresponds to the
 ** lowest element on the stack).
 **
-** The mapping from character to affinity is as follows:
-**    'n' = NUMERIC.
-**    'i' = INTEGER.
-**    't' = TEXT.
-**    'o' = NONE.
+** The mapping from character to affinity is given by the SQLITE_AFF_
+** macros defined in sqliteInt.h.
 **
 ** If P3 is NULL then all index fields have the affinity NONE.
 **
 ** See also OP_MakeIdxRec
 */
-/* Opcode: MakeRecordI P1 P2 P3
+/* Opcode: MakeIdxRec P1 P2 P3
 **
 ** This opcode works just OP_MakeRecord except that it reads an extra
 ** integer from the stack (thus reading a total of abs(P1+1) entries)
@@ -2133,6 +2174,7 @@
   int jumpIfNull;        /* Jump here if non-zero and any entries are NULL. */
   int addRowid;          /* True to append a rowid column at the end */
   char *zAffinity;       /* The affinity string for the record */
+  int file_format;       /* File format to use for encoding */
 
   leaveOnStack = ((pOp->p1<0)?1:0);
   nField = pOp->p1 * (leaveOnStack?-1:1);
@@ -2143,18 +2185,19 @@
   pData0 = &pTos[1-nField];
   assert( pData0>=p->aStack );
   containsNull = 0;
+  file_format = p->minWriteFileFormat;
 
   /* Loop through the elements that will make up the record to figure
   ** out how much space is required for the new record.
   */
   for(pRec=pData0; pRec<=pTos; pRec++){
     if( zAffinity ){
-      applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
+      applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
     }
     if( pRec->flags&MEM_Null ){
       containsNull = 1;
     }
-    serial_type = sqlite3VdbeSerialType(pRec);
+    serial_type = sqlite3VdbeSerialType(pRec, file_format);
     nData += sqlite3VdbeSerialTypeLen(serial_type);
     nHdr += sqlite3VarintLen(serial_type);
   }
@@ -2166,8 +2209,8 @@
   if( addRowid ){
     pRowid = &pTos[0-nField];
     assert( pRowid>=p->aStack );
-    Integerify(pRowid);
-    serial_type = sqlite3VdbeSerialType(pRowid);
+    sqlite3VdbeMemIntegerify(pRowid);
+    serial_type = sqlite3VdbeSerialType(pRowid, 0);
     nData += sqlite3VdbeSerialTypeLen(serial_type);
     nHdr += sqlite3VarintLen(serial_type);
   }
@@ -2186,24 +2229,24 @@
       goto no_mem;
     }
   }else{
-    zNewRecord = zTemp;
+    zNewRecord = (u8*)zTemp;
   }
 
   /* Write the record */
   zCsr = zNewRecord;
   zCsr += sqlite3PutVarint(zCsr, nHdr);
   for(pRec=pData0; pRec<=pTos; pRec++){
-    serial_type = sqlite3VdbeSerialType(pRec);
+    serial_type = sqlite3VdbeSerialType(pRec, file_format);
     zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
   }
   if( addRowid ){
-    zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid));
+    zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid, 0));
   }
   for(pRec=pData0; pRec<=pTos; pRec++){
-    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
+    zCsr += sqlite3VdbeSerialPut(zCsr, pRec, file_format);  /* serial data */
   }
   if( addRowid ){
-    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
+    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid, 0);
   }
   assert( zCsr==(zNewRecord+nByte) );
 
@@ -2220,7 +2263,7 @@
     pTos->flags = MEM_Blob | MEM_Short;
   }else{
     assert( zNewRecord!=(unsigned char *)zTemp );
-    pTos->z = zNewRecord;
+    pTos->z = (char*)zNewRecord;
     pTos->flags = MEM_Blob | MEM_Dyn;
     pTos->xDel = 0;
   }
@@ -2248,7 +2291,7 @@
 case OP_Statement: {       /* no-push */
   int i = pOp->p1;
   Btree *pBt;
-  if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt) && !(db->autoCommit) ){
+  if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt)!=0 && !(db->autoCommit) ){
     assert( sqlite3BtreeIsInTrans(pBt) );
     if( !sqlite3BtreeIsInStmt(pBt) ){
       rc = sqlite3BtreeBeginStmt(pBt);
@@ -2280,26 +2323,29 @@
     ** that the other VMs must complete first. 
     */
     sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit", 
-        " transaction - SQL statements in progress", 0);
+        " transaction - SQL statements in progress", (char*)0);
     rc = SQLITE_ERROR;
   }else if( i!=db->autoCommit ){
-    db->autoCommit = i;
     if( pOp->p2 ){
       assert( i==1 );
       sqlite3RollbackAll(db);
-    }else if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
-      p->pTos = pTos;
-      p->pc = pc;
-      db->autoCommit = 1-i;
-      p->rc = SQLITE_BUSY;
-      return SQLITE_BUSY;
+      db->autoCommit = 1;
+    }else{
+      db->autoCommit = i;
+      if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+        p->pTos = pTos;
+        p->pc = pc;
+        db->autoCommit = 1-i;
+        p->rc = SQLITE_BUSY;
+        return SQLITE_BUSY;
+      }
     }
     return SQLITE_DONE;
   }else{
     sqlite3SetString(&p->zErrMsg,
         (!i)?"cannot start a transaction within a transaction":(
         (rollback)?"cannot rollback - no transaction is active":
-                   "cannot commit - no transaction is active"), 0);
+                   "cannot commit - no transaction is active"), (char*)0);
          
     rc = SQLITE_ERROR;
   }
@@ -2396,16 +2442,24 @@
   pDb = &db->aDb[pOp->p1];
   assert( pDb->pBt!=0 );
   assert( pTos>=p->aStack );
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pTos);
   /* See note about index shifting on OP_ReadCookie */
   rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i);
   if( pOp->p2==0 ){
     /* When the schema cookie changes, record the new cookie internally */
-    pDb->schema_cookie = pTos->i;
+    pDb->pSchema->schema_cookie = pTos->i;
     db->flags |= SQLITE_InternChanges;
+  }else if( pOp->p2==1 ){
+    /* Record changes in the file format */
+    pDb->pSchema->file_format = pTos->i;
   }
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
+  if( pOp->p1==1 ){
+    /* Invalidate all prepared statements whenever the TEMP database
+    ** schema is changed.  Ticket #1644 */
+    sqlite3ExpirePreparedStatements(db);
+  }
   break;
 }
 
@@ -2493,26 +2547,35 @@
   Btree *pX;
   int iDb;
   Cursor *pCur;
+  Db *pDb;
   
   assert( pTos>=p->aStack );
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pTos);
   iDb = pTos->i;
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
   assert( iDb>=0 && iDb<db->nDb );
-  pX = db->aDb[iDb].pBt;
+  pDb = &db->aDb[iDb];
+  pX = pDb->pBt;
   assert( pX!=0 );
-  wrFlag = pOp->opcode==OP_OpenWrite;
+  if( pOp->opcode==OP_OpenWrite ){
+    wrFlag = 1;
+    if( pDb->pSchema->file_format < p->minWriteFileFormat ){
+      p->minWriteFileFormat = pDb->pSchema->file_format;
+    }
+  }else{
+    wrFlag = 0;
+  }
   if( p2<=0 ){
     assert( pTos>=p->aStack );
-    Integerify(pTos);
+    sqlite3VdbeMemIntegerify(pTos);
     p2 = pTos->i;
     assert( (pTos->flags & MEM_Dyn)==0 );
     pTos--;
     assert( p2>=2 );
   }
   assert( i>=0 );
-  pCur = allocateCursor(p, i);
+  pCur = allocateCursor(p, i, iDb);
   if( pCur==0 ) goto no_mem;
   pCur->nullRow = 1;
   if( pX==0 ) break;
@@ -2524,7 +2587,7 @@
   if( pOp->p3type==P3_KEYINFO ){
     pCur->pKeyInfo = (KeyInfo*)pOp->p3;
     pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
-    pCur->pKeyInfo->enc = p->db->enc;
+    pCur->pKeyInfo->enc = ENC(p->db);
   }else{
     pCur->pKeyInfo = 0;
     pCur->pIncrKey = &pCur->bogusIncrKey;
@@ -2590,7 +2653,7 @@
   int i = pOp->p1;
   Cursor *pCx;
   assert( i>=0 );
-  pCx = allocateCursor(p, i);
+  pCx = allocateCursor(p, i, -1);
   if( pCx==0 ) goto no_mem;
   pCx->nullRow = 1;
   rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
@@ -2612,7 +2675,7 @@
         rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
             pOp->p3, &pCx->pCursor);
         pCx->pKeyInfo = (KeyInfo*)pOp->p3;
-        pCx->pKeyInfo->enc = p->db->enc;
+        pCx->pKeyInfo->enc = ENC(p->db);
         pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
       }
       pCx->isTable = 0;
@@ -2627,7 +2690,6 @@
   break;
 }
 
-#ifndef SQLITE_OMIT_TRIGGER
 /* Opcode: OpenPseudo P1 * *
 **
 ** Open a new cursor that points to a fake table that contains a single
@@ -2636,13 +2698,15 @@
 ** closed.
 **
 ** A pseudo-table created by this opcode is useful for holding the
-** NEW or OLD tables in a trigger.
+** NEW or OLD tables in a trigger.  Also used to hold the a single
+** row output from the sorter so that the row can be decomposed into
+** individual columns using the OP_Column opcode.
 */
 case OP_OpenPseudo: {       /* no-push */
   int i = pOp->p1;
   Cursor *pCx;
   assert( i>=0 );
-  pCx = allocateCursor(p, i);
+  pCx = allocateCursor(p, i, -1);
   if( pCx==0 ) goto no_mem;
   pCx->nullRow = 1;
   pCx->pseudoTable = 1;
@@ -2651,7 +2715,6 @@
   pCx->isIndex = 0;
   break;
 }
-#endif
 
 /* Opcode: Close P1 * *
 **
@@ -2725,7 +2788,7 @@
     *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
     if( pC->isTable ){
       i64 iKey;
-      Integerify(pTos);
+      sqlite3VdbeMemIntegerify(pTos);
       iKey = intToKey(pTos->i);
       if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){
         pC->movetoTarget = iKey;
@@ -2741,7 +2804,8 @@
       pC->lastRowid = pTos->i;
       pC->rowidIsValid = res==0;
     }else{
-      Stringify(pTos, db->enc);
+      assert( pTos->flags & MEM_Blob );
+      /* Stringify(pTos, encoding); */
       rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
@@ -2749,7 +2813,7 @@
       pC->rowidIsValid = 0;
     }
     pC->deferredMoveto = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
     *pC->pIncrKey = 0;
     sqlite3_search_count++;
     if( oc==OP_MoveGe || oc==OP_MoveGt ){
@@ -2846,11 +2910,11 @@
   if( (pC = p->apCsr[i])->pCursor!=0 ){
     int res, rx;
     assert( pC->isTable==0 );
-    Stringify(pTos, db->enc);
+    Stringify(pTos, encoding);
     rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
     alreadyExists = rx==SQLITE_OK && res==0;
     pC->deferredMoveto = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
   }
   if( pOp->opcode==OP_Found ){
     if( alreadyExists ) pc = pOp->p2 - 1;
@@ -2868,7 +2932,7 @@
 **
 ** The top of the stack is an integer record number.  Call this
 ** record number R.  The next on the stack is an index key created
-** using MakeIdxKey.  Call it K.  This instruction pops R from the
+** using MakeIdxRec.  Call it K.  This instruction pops R from the
 ** stack but it leaves K unchanged.
 **
 ** P1 is an index.  So it has no data and its key consists of a
@@ -2895,7 +2959,7 @@
   /* Pop the value R off the top of the stack
   */
   assert( pNos>=p->aStack );
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pTos);
   R = pTos->i;
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
@@ -2904,7 +2968,7 @@
   assert( pCx!=0 );
   pCrsr = pCx->pCursor;
   if( pCrsr!=0 ){
-    int res, rc;
+    int res;
     i64 v;         /* The record number on the P1 entry that matches K */
     char *zKey;    /* The value of K */
     int nKey;      /* Number of bytes in K */
@@ -2913,20 +2977,22 @@
 
     /* Make sure K is a string and make zKey point to K
     */
-    Stringify(pNos, db->enc);
+    Stringify(pNos, encoding);
     zKey = pNos->z;
     nKey = pNos->n;
 
-    szRowid = sqlite3VdbeIdxRowidLen(nKey, zKey);
+    szRowid = sqlite3VdbeIdxRowidLen((u8*)zKey);
     len = nKey-szRowid;
 
     /* Search for an entry in P1 where all but the last four bytes match K.
     ** If there is no such entry, jump immediately to P2.
     */
     assert( pCx->deferredMoveto==0 );
-    pCx->cacheValid = 0;
+    pCx->cacheStatus = CACHE_STALE;
     rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
-    if( rc!=SQLITE_OK ) goto abort_due_to_error;
+    if( rc!=SQLITE_OK ){
+      goto abort_due_to_error;
+    }
     if( res<0 ){
       rc = sqlite3BtreeNext(pCrsr, &res);
       if( res ){
@@ -2934,7 +3000,7 @@
         break;
       }
     }
-    rc = sqlite3VdbeIdxKeyCompare(pCx, len, zKey, &res); 
+    rc = sqlite3VdbeIdxKeyCompare(pCx, len, (u8*)zKey, &res); 
     if( rc!=SQLITE_OK ) goto abort_due_to_error;
     if( res>0 ){
       pc = pOp->p2 - 1;
@@ -2997,7 +3063,7 @@
     pC->lastRowid = pTos->i;
     pC->rowidIsValid = res==0;
     pC->nullRow = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
     if( res!=0 ){
       pc = pOp->p2 - 1;
       pC->rowidIsValid = 0;
@@ -3105,7 +3171,10 @@
       if( pC->nextRowidValid ){
         v = pC->nextRowid;
       }else{
-        rx = sqlite3BtreeLast(pC->pCursor, &res);
+        rc = sqlite3BtreeLast(pC->pCursor, &res);
+        if( rc!=SQLITE_OK ){
+          goto abort_due_to_error;
+        }
         if( res ){
           v = 1;
         }else{
@@ -3124,7 +3193,7 @@
         Mem *pMem;
         assert( pOp->p2>0 && pOp->p2<p->nMem );  /* P2 is a valid memory cell */
         pMem = &p->aMem[pOp->p2];
-        Integerify(pMem);
+        sqlite3VdbeMemIntegerify(pMem);
         assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P2) holds an integer */
         if( pMem->i==MAX_ROWID || pC->useRandomRowid ){
           rc = SQLITE_FULL;
@@ -3170,7 +3239,7 @@
     }
     pC->rowidIsValid = 0;
     pC->deferredMoveto = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
   }
   pTos++;
   pTos->i = v;
@@ -3178,7 +3247,7 @@
   break;
 }
 
-/* Opcode: Insert P1 P2 *
+/* Opcode: Insert P1 P2 P3
 **
 ** Write an entry into the table of cursor P1.  A new entry is
 ** created if it doesn't already exist or the data for an existing
@@ -3210,7 +3279,7 @@
 
     if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
     if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
-    if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
+    if( pC->nextRowidValid && pNos->i>=pC->nextRowid ){
       pC->nextRowidValid = 0;
     }
     if( pTos->flags & MEM_Null ){
@@ -3219,7 +3288,6 @@
     }else{
       assert( pTos->flags & (MEM_Blob|MEM_Str) );
     }
-#ifndef SQLITE_OMIT_TRIGGER
     if( pC->pseudoTable ){
       sqliteFree(pC->pData);
       pC->iKey = iKey;
@@ -3236,21 +3304,29 @@
       }
       pC->nullRow = 0;
     }else{
-#endif
       rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
-#ifndef SQLITE_OMIT_TRIGGER
     }
-#endif
     
     pC->rowidIsValid = 0;
     pC->deferredMoveto = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
+
+    /* Invoke the update-hook if required. */
+    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3 ){
+      const char *zDb = db->aDb[pC->iDb].zName;
+      const char *zTbl = pOp->p3;
+      int op = ((pOp->p2 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+      assert( pC->isTable );
+      db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
+      assert( pC->iDb>=0 );
+    }
   }
   popStack(&pTos, 2);
+
   break;
 }
 
-/* Opcode: Delete P1 P2 *
+/* Opcode: Delete P1 P2 P3
 **
 ** Delete the record at which the P1 cursor is currently pointing.
 **
@@ -3271,11 +3347,37 @@
   pC = p->apCsr[i];
   assert( pC!=0 );
   if( pC->pCursor!=0 ){
+    i64 iKey;
+
+    /* If the update-hook will be invoked, set iKey to the rowid of the
+    ** row being deleted.
+    */
+    if( db->xUpdateCallback && pOp->p3 ){
+      assert( pC->isTable );
+      if( pC->rowidIsValid ){
+        iKey = pC->lastRowid;
+      }else{
+        rc = sqlite3BtreeKeySize(pC->pCursor, &iKey);
+        if( rc ){
+          goto abort_due_to_error;
+        }
+        iKey = keyToInt(iKey);
+      }
+    }
+
     rc = sqlite3VdbeCursorMoveto(pC);
     if( rc ) goto abort_due_to_error;
     rc = sqlite3BtreeDelete(pC->pCursor);
     pC->nextRowidValid = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
+
+    /* Invoke the update-hook if required. */
+    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3 ){
+      const char *zDb = db->aDb[pC->iDb].zName;
+      const char *zTbl = pOp->p3;
+      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
+      assert( pC->iDb>=0 );
+    }
   }
   if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
   break;
@@ -3360,12 +3462,10 @@
     }else{
       sqlite3BtreeData(pCrsr, 0, n, pTos->z);
     }
-#ifndef SQLITE_OMIT_TRIGGER
   }else if( pC->pseudoTable ){
     pTos->n = pC->nData;
     pTos->z = pC->pData;
     pTos->flags = MEM_Blob|MEM_Ephem;
-#endif
   }else{
     pTos->flags = MEM_Null;
   }
@@ -3445,7 +3545,7 @@
     rc = sqlite3BtreeLast(pCrsr, &res);
     pC->nullRow = res;
     pC->deferredMoveto = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
     if( res && pOp->p2>0 ){
       pc = pOp->p2 - 1;
     }
@@ -3494,7 +3594,7 @@
     rc = sqlite3BtreeFirst(pCrsr, &res);
     pC->atFirst = res==0;
     pC->deferredMoveto = 0;
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
   }else{
     res = 1;
   }
@@ -3539,7 +3639,7 @@
       rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
                                   sqlite3BtreePrevious(pCrsr, &res);
       pC->nullRow = res;
-      pC->cacheValid = 0;
+      pC->cacheStatus = CACHE_STALE;
     }
     if( res==0 ){
       pc = pOp->p2 - 1;
@@ -3554,9 +3654,9 @@
 
 /* Opcode: IdxInsert P1 * *
 **
-** The top of the stack holds a SQL index key made using the
-** MakeIdxKey instruction.  This opcode writes that key into the
-** index P1.  Data for the entry is nil.
+** The top of the stack holds a SQL index key made using either the
+** MakeIdxRec or MakeRecord instructions.  This opcode writes that key
+** into the index P1.  Data for the entry is nil.
 **
 ** This instruction only works for indices.  The equivalent instruction
 ** for tables is OP_Insert.
@@ -3576,7 +3676,7 @@
     assert( pC->isTable==0 );
     rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
     assert( pC->deferredMoveto==0 );
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
   }
   Release(pTos);
   pTos--;
@@ -3585,7 +3685,8 @@
 
 /* Opcode: IdxDelete P1 * *
 **
-** The top of the stack is an index key built using the MakeIdxKey opcode.
+** The top of the stack is an index key built using the either the
+** MakeIdxRec or MakeRecord opcodes.
 ** This opcode removes that entry from the index.
 */
 case OP_IdxDelete: {        /* no-push */
@@ -3597,13 +3698,13 @@
   assert( i>=0 && i<p->nCursor );
   assert( p->apCsr[i]!=0 );
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
-    int rx, res;
-    rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
-    if( rx==SQLITE_OK && res==0 ){
+    int res;
+    rc = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
+    if( rc==SQLITE_OK && res==0 ){
       rc = sqlite3BtreeDelete(pCrsr);
     }
     assert( pC->deferredMoveto==0 );
-    pC->cacheValid = 0;
+    pC->cacheStatus = CACHE_STALE;
   }
   Release(pTos);
   pTos--;
@@ -3616,7 +3717,7 @@
 ** the end of the index key pointed to by cursor P1.  This integer should be
 ** the rowid of the table entry to which this index entry points.
 **
-** See also: Rowid, MakeIdxKey.
+** See also: Rowid, MakeIdxRec.
 */
 case OP_IdxRowid: {
   int i = pOp->p1;
@@ -3700,14 +3801,14 @@
   assert( p->apCsr[i]!=0 );
   assert( pTos>=p->aStack );
   if( (pC = p->apCsr[i])->pCursor!=0 ){
-    int res, rc;
+    int res;
  
     assert( pTos->flags & MEM_Blob );  /* Created using OP_Make*Key */
-    Stringify(pTos, db->enc);
+    Stringify(pTos, encoding);
     assert( pC->deferredMoveto==0 );
     *pC->pIncrKey = pOp->p3!=0;
     assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT );
-    rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, &res);
+    rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res);
     *pC->pIncrKey = 0;
     if( rc!=SQLITE_OK ){
       break;
@@ -3729,7 +3830,7 @@
 /* Opcode: IdxIsNull P1 P2 *
 **
 ** The top of the stack contains an index entry such as might be generated
-** by the MakeIdxKey opcode.  This routine looks at the first P1 fields of
+** by the MakeIdxRec opcode.  This routine looks at the first P1 fields of
 ** that key.  If any of the first P1 fields are NULL, then a jump is made
 ** to address P2.  Otherwise we fall straight through.
 **
@@ -3745,9 +3846,9 @@
   assert( pTos->flags & MEM_Blob );
   z = pTos->z;
   n = pTos->n;
-  k = sqlite3GetVarint32(z, &serial_type);
+  k = sqlite3GetVarint32((u8*)z, &serial_type);
   for(; k<n && i>0; i--){
-    k += sqlite3GetVarint32(&z[k], &serial_type);
+    k += sqlite3GetVarint32((u8*)&z[k], &serial_type);
     if( serial_type==0 ){   /* Serial type 0 is a NULL */
       pc = pOp->p2-1;
       break;
@@ -3810,6 +3911,41 @@
 ** See also: Destroy
 */
 case OP_Clear: {        /* no-push */
+
+  /* For consistency with the way other features of SQLite operate
+  ** with a truncate, we will also skip the update callback.
+  */
+#if 0
+  Btree *pBt = db->aDb[pOp->p2].pBt;
+  if( db->xUpdateCallback && pOp->p3 ){
+    const char *zDb = db->aDb[pOp->p2].zName;
+    const char *zTbl = pOp->p3;
+    BtCursor *pCur = 0;
+    int fin = 0;
+
+    rc = sqlite3BtreeCursor(pBt, pOp->p1, 0, 0, 0, &pCur);
+    if( rc!=SQLITE_OK ){
+      goto abort_due_to_error;
+    }
+    for(
+      rc=sqlite3BtreeFirst(pCur, &fin); 
+      rc==SQLITE_OK && !fin; 
+      rc=sqlite3BtreeNext(pCur, &fin)
+    ){
+      i64 iKey;
+      rc = sqlite3BtreeKeySize(pCur, &iKey);
+      if( rc ){
+        break;
+      }
+      iKey = keyToInt(iKey);
+      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
+    }
+    sqlite3BtreeCloseCursor(pCur);
+    if( rc!=SQLITE_OK ){
+      goto abort_due_to_error;
+    }
+  }
+#endif
   rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
   break;
 }
@@ -3885,14 +4021,19 @@
   sqlite3SafetyOff(db);
   assert( db->init.busy==0 );
   db->init.busy = 1;
+  assert( !sqlite3MallocFailed() );
   rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+  sqliteFree(zSql);
   db->init.busy = 0;
   sqlite3SafetyOn(db);
-  sqliteFree(zSql);
+  if( rc==SQLITE_NOMEM ){
+    sqlite3FailedMalloc();
+    goto no_mem;
+  }
   break;  
 }
 
-#ifndef SQLITE_OMIT_ANALYZE
+#if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER)
 /* Opcode: LoadAnalysis P1 * *
 **
 ** Read the sqlite_stat1 table for database P1 and load the content
@@ -3905,7 +4046,7 @@
   sqlite3AnalysisLoad(db, iDb);
   break;  
 }
-#endif /* SQLITE_OMIT_ANALYZE */
+#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER)  */
 
 /* Opcode: DropTable P1 * P3
 **
@@ -3992,7 +4133,7 @@
     pTos->xDel = 0;
   }
   pTos->enc = SQLITE_UTF8;
-  sqlite3VdbeChangeEncoding(pTos, db->enc);
+  sqlite3VdbeChangeEncoding(pTos, encoding);
   sqliteFree(aRoot);
   break;
 }
@@ -4005,7 +4146,7 @@
 */
 case OP_FifoWrite: {        /* no-push */
   assert( pTos>=p->aStack );
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pTos);
   sqlite3VdbeFifoPush(&p->sFifo, pTos->i);
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
@@ -4046,7 +4187,7 @@
   /* FIX ME: This should be allocated as part of the vdbe at compile-time */
   if( i>=p->contextStackDepth ){
     p->contextStackDepth = i+1;
-    sqlite3ReallocOrFree((void**)&p->contextStack, sizeof(Context)*(i+1));
+    sqliteReallocOrFree((void**)&p->contextStack, sizeof(Context)*(i+1));
     if( p->contextStack==0 ) goto no_mem;
   }
   pContext = &p->contextStack[i];
@@ -4129,8 +4270,8 @@
   assert( pTos>=p->aStack );
   assert( i>=0 && i<p->nMem );
   pMem = &p->aMem[i];
-  Integerify(pMem);
-  Integerify(pTos);
+  sqlite3VdbeMemIntegerify(pMem);
+  sqlite3VdbeMemIntegerify(pTos);
   if( pMem->i<pTos->i){
     pMem->i = pTos->i;
   }
@@ -4140,30 +4281,27 @@
 
 /* Opcode: MemIncr P1 P2 *
 **
-** Increment the integer valued memory cell P1 by 1.  If P2 is not zero
-** and the result after the increment is exactly 1, then jump
-** to P2.
+** Increment the integer valued memory cell P2 by the value in P1.
 **
-** This instruction throws an error if the memory cell is not initially
-** an integer.
+** It is illegal to use this instruction on a memory cell that does
+** not contain an integer.  An assertion fault will result if you try.
 */
 case OP_MemIncr: {        /* no-push */
-  int i = pOp->p1;
+  int i = pOp->p2;
   Mem *pMem;
   assert( i>=0 && i<p->nMem );
   pMem = &p->aMem[i];
   assert( pMem->flags==MEM_Int );
-  pMem->i++;
-  if( pOp->p2>0 && pMem->i==1 ){
-     pc = pOp->p2 - 1;
-  }
+  pMem->i += pOp->p1;
   break;
 }
 
 /* Opcode: IfMemPos P1 P2 *
 **
-** If the value of memory cell P1 is 1 or greater, jump to P2. This
-** opcode assumes that memory cell P1 holds an integer value.
+** If the value of memory cell P1 is 1 or greater, jump to P2.
+**
+** It is illegal to use this instruction on a memory cell that does
+** not contain an integer.  An assertion fault will result if you try.
 */
 case OP_IfMemPos: {        /* no-push */
   int i = pOp->p1;
@@ -4177,6 +4315,44 @@
   break;
 }
 
+/* Opcode: IfMemNeg P1 P2 *
+**
+** If the value of memory cell P1 is less than zero, jump to P2. 
+**
+** It is illegal to use this instruction on a memory cell that does
+** not contain an integer.  An assertion fault will result if you try.
+*/
+case OP_IfMemNeg: {        /* no-push */
+  int i = pOp->p1;
+  Mem *pMem;
+  assert( i>=0 && i<p->nMem );
+  pMem = &p->aMem[i];
+  assert( pMem->flags==MEM_Int );
+  if( pMem->i<0 ){
+     pc = pOp->p2 - 1;
+  }
+  break;
+}
+
+/* Opcode: IfMemZero P1 P2 *
+**
+** If the value of memory cell P1 is exactly 0, jump to P2. 
+**
+** It is illegal to use this instruction on a memory cell that does
+** not contain an integer.  An assertion fault will result if you try.
+*/
+case OP_IfMemZero: {        /* no-push */
+  int i = pOp->p1;
+  Mem *pMem;
+  assert( i>=0 && i<p->nMem );
+  pMem = &p->aMem[i];
+  assert( pMem->flags==MEM_Int );
+  if( pMem->i==0 ){
+     pc = pOp->p2 - 1;
+  }
+  break;
+}
+
 /* Opcode: MemNull P1 * *
 **
 ** Store a NULL in memory cell P1
@@ -4233,12 +4409,15 @@
   assert( apVal || n==0 );
   for(i=0; i<n; i++, pRec++){
     apVal[i] = pRec;
-    storeTypeInfo(pRec, db->enc);
+    storeTypeInfo(pRec, encoding);
   }
   ctx.pFunc = (FuncDef*)pOp->p3;
   assert( pOp->p1>=0 && pOp->p1<p->nMem );
   ctx.pMem = pMem = &p->aMem[pOp->p1];
   pMem->n++;
+  ctx.s.flags = MEM_Null;
+  ctx.s.z = 0;
+  ctx.s.xDel = 0;
   ctx.isError = 0;
   ctx.pColl = 0;
   if( ctx.pFunc->needCollSeq ){
@@ -4250,8 +4429,10 @@
   (ctx.pFunc->xStep)(&ctx, n, apVal);
   popStack(&pTos, n);
   if( ctx.isError ){
+    sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);
     rc = SQLITE_ERROR;
   }
+  sqlite3VdbeMemRelease(&ctx.s);
   break;
 }
 
@@ -4272,7 +4453,10 @@
   assert( pOp->p1>=0 && pOp->p1<p->nMem );
   pMem = &p->aMem[pOp->p1];
   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
-  sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p3);
+  rc = sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p3);
+  if( rc==SQLITE_ERROR ){
+    sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0);
+  }
   break;
 }
 
@@ -4308,6 +4492,37 @@
   break;
 }
 
+#ifndef SQLITE_OMIT_SHARED_CACHE
+/* Opcode: TableLock P1 P2 P3
+**
+** Obtain a lock on a particular table. This instruction is only used when
+** the shared-cache feature is enabled. 
+**
+** If P1 is not negative, then it is the index of the database
+** in sqlite3.aDb[] and a read-lock is required. If P1 is negative, a 
+** write-lock is required. In this case the index of the database is the 
+** absolute value of P1 minus one (iDb = abs(P1) - 1;) and a write-lock is
+** required. 
+**
+** P2 contains the root-page of the table to lock.
+**
+** P3 contains a pointer to the name of the table being locked. This is only
+** used to generate an error message if the lock cannot be obtained.
+*/
+case OP_TableLock: {        /* no-push */
+  int p1 = pOp->p1; 
+  u8 isWriteLock = (p1<0);
+  if( isWriteLock ){
+    p1 = (-1*p1)-1;
+  }
+  rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
+  if( rc==SQLITE_LOCKED ){
+    const char *z = (const char *)pOp->p3;
+    sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0);
+  }
+  break;
+}
+#endif /* SHARED_OMIT_SHARED_CACHE */
 
 /* An other opcode is illegal...
 */
@@ -4347,7 +4562,7 @@
 #ifndef NDEBUG
     /* Sanity checking on the top element of the stack */
     if( pTos>=p->aStack ){
-      sqlite3VdbeMemSanity(pTos, db->enc);
+      sqlite3VdbeMemSanity(pTos);
     }
     assert( pc>=-1 && pc<p->nOp );
 #ifdef SQLITE_DEBUG
@@ -4366,7 +4581,7 @@
           fprintf(p->trace, " r:%g", pTos[i].r);
         }else{
           char zBuf[100];
-          sqlite3VdbeMemPrettyPrint(&pTos[i], zBuf, 100);
+          sqlite3VdbeMemPrettyPrint(&pTos[i], zBuf);
           fprintf(p->trace, " ");
           fprintf(p->trace, "%s", zBuf);
         }
@@ -4410,7 +4625,7 @@
   */
 abort_due_to_error:
   if( p->zErrMsg==0 ){
-    if( sqlite3_malloc_failed ) rc = SQLITE_NOMEM;
+    if( sqlite3MallocFailed() ) rc = SQLITE_NOMEM;
     sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
   }
   goto vdbe_halt;

Modified: packages/libdbd-sqlite3-perl/trunk/vdbe.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/vdbe.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/vdbe.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.99 2005/09/20 17:42:23 drh Exp $
+** $Id: vdbe.h,v 1.102 2006/03/17 13:56:34 drh Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -69,6 +69,7 @@
 #define P3_KEYINFO  (-6)  /* P3 is a pointer to a KeyInfo structure */
 #define P3_VDBEFUNC (-7)  /* P3 is a pointer to a VdbeFunc structure */
 #define P3_MEM      (-8)  /* P3 is a pointer to a Mem*    structure */
+#define P3_TRANSIENT (-9)  /* P3 is a pointer to a transient string */
 
 /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
 ** is made.  That copy is freed when the Vdbe is finalized.  But if the
@@ -80,6 +81,17 @@
 #define P3_KEYINFO_HANDOFF (-9)
 
 /*
+** The Vdbe.aColName array contains 5n Mem structures, where n is the 
+** number of columns of data returned by the statement.
+*/
+#define COLNAME_NAME     0
+#define COLNAME_DECLTYPE 1
+#define COLNAME_DATABASE 2
+#define COLNAME_TABLE    3
+#define COLNAME_COLUMN   4
+#define COLNAME_N        5      /* Number of COLNAME_xxx symbols */
+
+/*
 ** The following macro converts a relative address in the p2 field
 ** of a VdbeOp structure into a negative number so that 
 ** sqlite3VdbeAddOpList() knows that the address is relative.  Calling
@@ -105,6 +117,7 @@
 void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
 void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
 void sqlite3VdbeJumpHere(Vdbe*, int addr);
+void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
 void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
 VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
 int sqlite3VdbeMakeLabel(Vdbe*);
@@ -117,7 +130,7 @@
 int sqlite3VdbeReset(Vdbe*);
 int sqliteVdbeSetVariables(Vdbe*,int,const char**);
 void sqlite3VdbeSetNumCols(Vdbe*,int);
-int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
+int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
 void sqlite3VdbeCountChanges(Vdbe*);
 sqlite3 *sqlite3VdbeDb(Vdbe*);
 

Modified: packages/libdbd-sqlite3-perl/trunk/vdbeInt.h
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/vdbeInt.h	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/vdbeInt.h	2006-04-18 15:20:48 UTC (rev 2605)
@@ -60,6 +60,7 @@
 */
 struct Cursor {
   BtCursor *pCursor;    /* The cursor structure of the backend */
+  int iDb;              /* Index of cursor database in db->aDb[] (or -1) */
   i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
   i64 nextRowid;        /* Next rowid returned by OP_NewRowid */
   Bool zeroed;          /* True if zeroed out and ready for reuse */
@@ -85,9 +86,10 @@
 
   /* Cached information about the header for the data record that the
   ** cursor is currently pointing to.  Only valid if cacheValid is true.
-  ** zRow might point to (ephemeral) data for the current row, or it might
-  ** be NULL. */
-  Bool cacheValid;      /* True if the cache is valid */
+  ** aRow might point to (ephemeral) data for the current row, or it might
+  ** be NULL.
+  */
+  int cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
   int payloadSize;      /* Total number of bytes in the record */
   u32 *aType;           /* Type values for all entries in the record */
   u32 *aOffset;         /* Cached offsets to the start of each columns data */
@@ -103,6 +105,11 @@
 #define NBFS 32
 
 /*
+** A value for Cursor.cacheValid that means the cache is always invalid.
+*/
+#define CACHE_STALE 0
+
+/*
 ** Internally, the vdbe manipulates nearly all SQL values as Mem
 ** structures. Each Mem struct may cache multiple representations (string,
 ** integer etc.) of the same value.  A value (and therefore Mem structure)
@@ -250,7 +257,7 @@
 */
 typedef struct Context Context;
 struct Context {
-  int lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
+  i64 lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
   int nChange;      /* Statement changes (Vdbe.nChanges)     */
   Fifo sFifo;       /* Records that will participate in a DELETE or UPDATE */
 };
@@ -286,6 +293,7 @@
   int nMem;               /* Number of memory locations currently allocated */
   Mem *aMem;              /* The memory locations */
   int nCallback;          /* Number of callbacks invoked so far */
+  int cacheCtr;           /* Cursor row cache generation counter */
   Fifo sFifo;             /* A list of ROWIDs */
   int contextStackTop;    /* Index of top element in the context stack */
   int contextStackDepth;  /* The size of the "context" stack */
@@ -306,8 +314,13 @@
   u8 changeCntOn;         /* True to update the change-counter */
   u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
   u8 expired;             /* True if the VM needs to be recompiled */
+  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   int nChange;            /* Number of db changes made since last reset */
   i64 startTime;          /* Time when query started - used for profiling */
+#ifdef SQLITE_SSE
+  int fetchId;          /* Statement number used by sqlite3_fetch_statement */
+  int lru;              /* Counter used for LRU cache replacement */
+#endif
 };
 
 /*
@@ -331,8 +344,8 @@
 void sqlite3VdbePrintSql(Vdbe*);
 #endif
 int sqlite3VdbeSerialTypeLen(u32);
-u32 sqlite3VdbeSerialType(Mem*);
-int sqlite3VdbeSerialPut(unsigned char*, Mem*);
+u32 sqlite3VdbeSerialType(Mem*, int);
+int sqlite3VdbeSerialPut(unsigned char*, Mem*, int);
 int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
 void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
 
@@ -341,7 +354,7 @@
 int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
 int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
 int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*);
-int sqlite3VdbeIdxRowidLen(int,const u8*);
+int sqlite3VdbeIdxRowidLen(const u8*);
 int sqlite3VdbeExec(Vdbe*);
 int sqlite3VdbeList(Vdbe*);
 int sqlite3VdbeHalt(Vdbe*);
@@ -360,16 +373,18 @@
 i64 sqlite3VdbeIntValue(Mem*);
 int sqlite3VdbeMemIntegerify(Mem*);
 double sqlite3VdbeRealValue(Mem*);
+void sqlite3VdbeIntegerAffinity(Mem*);
 int sqlite3VdbeMemRealify(Mem*);
+int sqlite3VdbeMemNumerify(Mem*);
 int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
 void sqlite3VdbeMemRelease(Mem *p);
-void sqlite3VdbeMemFinalize(Mem*, FuncDef*);
+int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
 #ifndef NDEBUG
-void sqlite3VdbeMemSanity(Mem*, u8);
+void sqlite3VdbeMemSanity(Mem*);
 int sqlite3VdbeOpcodeNoPush(u8);
 #endif
 int sqlite3VdbeMemTranslate(Mem*, u8);
-void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
+void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
 int sqlite3VdbeMemHandleBom(Mem *pMem);
 void sqlite3VdbeFifoInit(Fifo*);
 int sqlite3VdbeFifoPush(Fifo*, i64);

Modified: packages/libdbd-sqlite3-perl/trunk/vdbeapi.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/vdbeapi.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/vdbeapi.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -58,7 +58,7 @@
   return sqlite3VdbeIntValue((Mem*)pVal);
 }
 const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
-  return (const char *)sqlite3ValueText(pVal, SQLITE_UTF8);
+  return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_value_text16(sqlite3_value* pVal){
@@ -74,6 +74,7 @@
 int sqlite3_value_type(sqlite3_value* pVal){
   return pVal->type;
 }
+/* sqlite3_value_numeric_type() defined in vdbe.c */
 
 /**************************** sqlite3_result_  *******************************
 ** The following routines are used by user-defined functions to specify
@@ -95,10 +96,12 @@
   pCtx->isError = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
 }
+#ifndef SQLITE_OMIT_UTF16
 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
   pCtx->isError = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
 }
+#endif
 void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
   sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
 }
@@ -156,6 +159,9 @@
   sqlite3 *db;
   int rc;
 
+  /* Assert that malloc() has not failed */
+  assert( !sqlite3MallocFailed() );
+
   if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
     return SQLITE_MISUSE;
   }
@@ -238,7 +244,8 @@
   }
 #endif
 
-  sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
+  sqlite3Error(p->db, rc, 0);
+  p->rc = sqlite3ApiExit(p->db, p->rc);
   return rc;
 }
 
@@ -329,9 +336,10 @@
 ** Return the number of times the Step function of a aggregate has been 
 ** called.
 **
-** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite3_context structure which is only defined in
-** this source file.
+** This function is deprecated.  Do not use it for new code.  It is
+** provide only to avoid breaking legacy code.  New aggregate function
+** implementations should keep their own counts within their aggregate
+** context.
 */
 int sqlite3_aggregate_count(sqlite3_context *p){
   assert( p && p->pFunc && p->pFunc->xStep );
@@ -375,30 +383,76 @@
   return &pVm->pTos[(1-vals)+i];
 }
 
+/*
+** This function is called after invoking an sqlite3_value_XXX function on a 
+** column value (i.e. a value returned by evaluating an SQL expression in the
+** select list of a SELECT statement) that may cause a malloc() failure. If 
+** malloc() has failed, the threads mallocFailed flag is cleared and the result
+** code of statement pStmt set to SQLITE_NOMEM.
+**
+** Specificly, this is called from within:
+**
+**     sqlite3_column_int()
+**     sqlite3_column_int64()
+**     sqlite3_column_text()
+**     sqlite3_column_text16()
+**     sqlite3_column_real()
+**     sqlite3_column_bytes()
+**     sqlite3_column_bytes16()
+**
+** But not for sqlite3_column_blob(), which never calls malloc().
+*/
+static void columnMallocFailure(sqlite3_stmt *pStmt)
+{
+  /* If malloc() failed during an encoding conversion within an
+  ** sqlite3_column_XXX API, then set the return code of the statement to
+  ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
+  ** and _finalize() will return NOMEM.
+  */
+  Vdbe *p = (Vdbe *)pStmt;
+  p->rc = sqlite3ApiExit(0, p->rc);
+}
+
 /**************************** sqlite3_column_  *******************************
 ** The following routines are used to access elements of the current row
 ** in the result set.
 */
 const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_blob( columnMem(pStmt,i) );
+  const void *val;
+  sqlite3MallocDisallow();
+  val = sqlite3_value_blob( columnMem(pStmt,i) );
+  sqlite3MallocAllow();
+  return val;
 }
 int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_bytes( columnMem(pStmt,i) );
+  int val = sqlite3_value_bytes( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return val;
 }
 int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_bytes16( columnMem(pStmt,i) );
+  int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return val;
 }
 double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_double( columnMem(pStmt,i) );
+  double val = sqlite3_value_double( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return val;
 }
 int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_int( columnMem(pStmt,i) );
+  int val = sqlite3_value_int( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return val;
 }
 sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_int64( columnMem(pStmt,i) );
+  sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return val;
 }
 const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_text( columnMem(pStmt,i) );
+  const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return val;
 }
 #if 0
 sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
@@ -407,13 +461,22 @@
 #endif
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_text16( columnMem(pStmt,i) );
+  const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return val;
 }
 #endif /* SQLITE_OMIT_UTF16 */
 int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
   return sqlite3_value_type( columnMem(pStmt,i) );
 }
 
+/* The following function is experimental and subject to change or
+** removal */
+/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){
+**  return sqlite3_value_numeric_type( columnMem(pStmt,i) );
+**}
+*/
+
 /*
 ** Convert the N-th element of pStmt->pColName[] into a string using
 ** xFunc() then return that string.  If N is out of range, return 0.
@@ -436,6 +499,7 @@
   const void *(*xFunc)(Mem*),
   int useType
 ){
+  const void *ret;
   Vdbe *p = (Vdbe *)pStmt;
   int n = sqlite3_column_count(pStmt);
 
@@ -443,20 +507,27 @@
     return 0;
   }
   N += useType*n;
-  return xFunc(&p->aColName[N]);
+  ret = xFunc(&p->aColName[N]);
+
+  /* A malloc may have failed inside of the xFunc() call. If this is the case,
+  ** clear the mallocFailed flag and return NULL.
+  */
+  sqlite3ApiExit(0, 0);
+  return ret;
 }
 
-
 /*
 ** Return the name of the Nth column of the result set returned by SQL
 ** statement pStmt.
 */
 const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
 }
 #endif
 
@@ -465,26 +536,30 @@
 ** of the result set of SQL statement pStmt.
 */
 const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
-#if !defined(SQLITE_OMIT_ORIGIN_NAMES) && 0
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
 /*
 ** Return the name of the database from which a result column derives.
 ** NULL is returned if the result column is an expression or constant or
 ** anything else which is not an unabiguous reference to a database column.
 */
 const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 2);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 2);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -494,11 +569,13 @@
 ** anything else which is not an unabiguous reference to a database column.
 */
 const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 3);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 3);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -508,18 +585,18 @@
 ** anything else which is not an unabiguous reference to a database column.
 */
 const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 4);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 4);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
 }
 #endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_OMIT_ORIGIN_NAMES */
+#endif /* SQLITE_ENABLE_COLUMN_METADATA */
 
 
-
-
 /******************************* sqlite3_bind_  ***************************
 ** 
 ** Routines used to attach values to wildcards in a compiled SQL statement.
@@ -571,13 +648,12 @@
   }
   pVar = &p->aVar[i-1];
   rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
-  if( rc ){
-    return rc;
-  }
   if( rc==SQLITE_OK && encoding!=0 ){
-    rc = sqlite3VdbeChangeEncoding(pVar, p->db->enc);
+    rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
   }
-  return rc;
+
+  sqlite3Error(((Vdbe *)pStmt)->db, rc, 0);
+  return sqlite3ApiExit(((Vdbe *)pStmt)->db, rc);
 }
 
 
@@ -721,7 +797,9 @@
     return SQLITE_ERROR;
   }
   for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
+    sqlite3MallocDisallow();
     rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
+    sqlite3MallocAllow();
   }
   return rc;
 }

Modified: packages/libdbd-sqlite3-perl/trunk/vdbeaux.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/vdbeaux.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/vdbeaux.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -58,8 +58,14 @@
 /*
 ** Resize the Vdbe.aOp array so that it contains at least N
 ** elements. If the Vdbe is in VDBE_MAGIC_RUN state, then
-** the Vdbe.aOp array will be sized to contain exactly N 
-** elements.
+** the Vdbe.aOp array will be sized to contain exactly N
+** elements. Vdbe.nOpAlloc is set to reflect the new size of
+** the array.
+**
+** If an out-of-memory error occurs while resizing the array,
+** Vdbe.aOp and Vdbe.nOpAlloc remain unchanged (this is so that
+** any opcodes already allocated can be correctly deallocated
+** along with the rest of the Vdbe).
 */
 static void resizeOpArray(Vdbe *p, int N){
   int runMode = p->magic==VDBE_MAGIC_RUN;
@@ -101,9 +107,11 @@
   i = p->nOp;
   p->nOp++;
   assert( p->magic==VDBE_MAGIC_INIT );
-  resizeOpArray(p, i+1);
-  if( sqlite3_malloc_failed ){
-    return 0;
+  if( p->nOpAlloc<=i ){
+    resizeOpArray(p, i+1);
+    if( sqlite3MallocFailed() ){
+      return 0;
+    }
   }
   pOp = &p->aOp[i];
   pOp->opcode = op;
@@ -147,7 +155,7 @@
   assert( p->magic==VDBE_MAGIC_INIT );
   if( i>=p->nLabelAlloc ){
     p->nLabelAlloc = p->nLabelAlloc*2 + 10;
-    sqlite3ReallocOrFree((void**)&p->aLabel,
+    sqliteReallocOrFree((void**)&p->aLabel,
                           p->nLabelAlloc*sizeof(p->aLabel[0]));
   }
   if( p->aLabel ){
@@ -196,12 +204,13 @@
   ** IEEE floats.
   */ 
   static const u32 masks[5] = {
-    NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16),
-    NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16),
-    NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16),
-    NOPUSH_MASK_6 + (NOPUSH_MASK_7<<16),
-    NOPUSH_MASK_8 + (NOPUSH_MASK_9<<16)
+    NOPUSH_MASK_0 + (((unsigned)NOPUSH_MASK_1)<<16),
+    NOPUSH_MASK_2 + (((unsigned)NOPUSH_MASK_3)<<16),
+    NOPUSH_MASK_4 + (((unsigned)NOPUSH_MASK_5)<<16),
+    NOPUSH_MASK_6 + (((unsigned)NOPUSH_MASK_7)<<16),
+    NOPUSH_MASK_8 + (((unsigned)NOPUSH_MASK_9)<<16)
   };
+  assert( op<32*5 );
   return (masks[op>>5] & (1<<(op&0x1F)));
 }
 
@@ -300,7 +309,7 @@
   int addr;
   assert( p->magic==VDBE_MAGIC_INIT );
   resizeOpArray(p, p->nOp + nOp);
-  if( sqlite3_malloc_failed ){
+  if( sqlite3MallocFailed() ){
     return 0;
   }
   addr = p->nOp;
@@ -333,7 +342,7 @@
 ** few minor changes to the program.
 */
 void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
-  assert( p->magic==VDBE_MAGIC_INIT );
+  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
   if( p && addr>=0 && p->nOp>addr && p->aOp ){
     p->aOp[addr].p1 = val;
   }
@@ -345,14 +354,14 @@
 */
 void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
   assert( val>=0 );
-  assert( p->magic==VDBE_MAGIC_INIT );
+  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
   if( p && addr>=0 && p->nOp>addr && p->aOp ){
     p->aOp[addr].p2 = val;
   }
 }
 
 /*
-** Change teh P2 operand of instruction addr so that it points to
+** Change the P2 operand of instruction addr so that it points to
 ** the address of the next instruction to be coded.
 */
 void sqlite3VdbeJumpHere(Vdbe *p, int addr){
@@ -387,6 +396,19 @@
 
 
 /*
+** Change N opcodes starting at addr to No-ops.
+*/
+void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
+  VdbeOp *pOp = &p->aOp[addr];
+  while( N-- ){
+    freeP3(pOp->p3type, pOp->p3);
+    memset(pOp, 0, sizeof(pOp[0]));
+    pOp->opcode = OP_Noop;
+    pOp++;
+  }
+}
+
+/*
 ** Change the value of the P3 operand for a specific instruction.
 ** This routine is useful when a large program is loaded from a
 ** static array using sqlite3VdbeAddOpList but we want to make a
@@ -413,9 +435,11 @@
 */
 void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
   Op *pOp;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( p==0 || p->aOp==0 ){
-    freeP3(n, (void*)*(char**)&zP3);
+  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
+  if( p==0 || p->aOp==0 || sqlite3MallocFailed() ){
+    if (n != P3_KEYINFO) {
+      freeP3(n, (void*)*(char**)&zP3);
+    }
     return;
   }
   if( addr<0 || addr>=p->nOp ){
@@ -432,16 +456,18 @@
     KeyInfo *pKeyInfo;
     int nField, nByte;
 
-    /* KeyInfo structures that include an KeyInfo.aSortOrder are always
-    ** sent in using P3_KEYINFO_HANDOFF.  The KeyInfo.aSortOrder array
-    ** is not duplicated when P3_KEYINFO is used. */
-    /* assert( pKeyInfo->aSortOrder==0 ); */
     nField = ((KeyInfo*)zP3)->nField;
-    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]);
+    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
     pKeyInfo = sqliteMallocRaw( nByte );
     pOp->p3 = (char*)pKeyInfo;
     if( pKeyInfo ){
+      unsigned char *aSortOrder;
       memcpy(pKeyInfo, zP3, nByte);
+      aSortOrder = pKeyInfo->aSortOrder;
+      if( aSortOrder ){
+        pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
+        memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
+      }
       pOp->p3type = P3_KEYINFO;
     }else{
       pOp->p3type = P3_NOTUSED;
@@ -467,7 +493,8 @@
 void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
   va_list ap;
   assert( p->nOp>0 );
-  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 );
+  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 
+          || sqlite3MallocFailed() );
   va_start(ap, zFormat);
   sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
   va_end(ap);
@@ -644,8 +671,9 @@
     pMem->type = SQLITE_INTEGER;
     pMem++;
 
-    pMem->flags = MEM_Short|MEM_Str|MEM_Term;   /* P3 */
+    pMem->flags = MEM_Ephem|MEM_Str|MEM_Term;   /* P3 */
     pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
+    pMem->n = strlen(pMem->z);
     pMem->type = SQLITE_TEXT;
     pMem->enc = SQLITE_UTF8;
 
@@ -733,7 +761,7 @@
       + nMem*sizeof(Mem)               /* aMem */
       + nCursor*sizeof(Cursor*)        /* apCsr */
     );
-    if( !sqlite3_malloc_failed ){
+    if( !sqlite3MallocFailed() ){
       p->aMem = &p->aStack[nStack];
       p->nMem = nMem;
       p->aVar = &p->aMem[nMem];
@@ -777,6 +805,8 @@
   p->explain |= isExplain;
   p->magic = VDBE_MAGIC_RUN;
   p->nChange = 0;
+  p->cacheCtr = 1;
+  p->minWriteFileFormat = 255;
 #ifdef VDBE_PROFILE
   {
     int i;
@@ -857,9 +887,10 @@
 void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
   Mem *pColName;
   int n;
-  assert( 0==p->nResColumn );
+  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+  sqliteFree(p->aColName);
+  n = nResColumn*COLNAME_N;
   p->nResColumn = nResColumn;
-  n = nResColumn*2;
   p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
   if( p->aColName==0 ) return;
   while( n-- > 0 ){
@@ -878,13 +909,14 @@
 ** the string is freed using sqliteFree() when the vdbe is finished with
 ** it. Otherwise, N bytes of zName are copied.
 */
-int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
+int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
   int rc;
   Mem *pColName;
-  assert( idx<(2*p->nResColumn) );
-  if( sqlite3_malloc_failed ) return SQLITE_NOMEM;
+  assert( idx<p->nResColumn );
+  assert( var<COLNAME_N );
+  if( sqlite3MallocFailed() ) return SQLITE_NOMEM;
   assert( p->aColName!=0 );
-  pColName = &(p->aColName[idx]);
+  pColName = &(p->aColName[idx+var*p->nResColumn]);
   if( N==P3_DYNAMIC || N==P3_STATIC ){
     rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
   }else{
@@ -919,7 +951,6 @@
 
   /* If there are any write-transactions at all, invoke the commit hook */
   if( needXcommit && db->xCommitCallback ){
-    int rc;
     sqlite3SafetyOff(db);
     rc = db->xCommitCallback(db->pCommitArg);
     sqlite3SafetyOn(db);
@@ -965,7 +996,7 @@
     int needSync = 0;
     char *zMaster = 0;   /* File-name for the master journal */
     char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
-    OsFile master;
+    OsFile *master = 0;
 
     /* Select a master journal file name */
     do {
@@ -979,7 +1010,6 @@
     }while( sqlite3OsFileExists(zMaster) );
 
     /* Open the master journal. */
-    memset(&master, 0, sizeof(master));
     rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
     if( rc!=SQLITE_OK ){
       sqliteFree(zMaster);
@@ -1001,7 +1031,7 @@
         if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
           needSync = 1;
         }
-        rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1);
+        rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1);
         if( rc!=SQLITE_OK ){
           sqlite3OsClose(&master);
           sqlite3OsDelete(zMaster);
@@ -1016,9 +1046,9 @@
     ** the master journal file is store in so that it gets synced too.
     */
     zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
-    rc = sqlite3OsOpenDirectory(zMainFile, &master);
+    rc = sqlite3OsOpenDirectory(master, zMainFile);
     if( rc!=SQLITE_OK ||
-          (needSync && (rc=sqlite3OsSync(&master,0))!=SQLITE_OK) ){
+          (needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){
       sqlite3OsClose(&master);
       sqlite3OsDelete(zMaster);
       sqliteFree(zMaster);
@@ -1094,10 +1124,10 @@
 ** aborted so that they do not have data rolled out from underneath
 ** them leading to a segfault.
 */
-static void abortOtherActiveVdbes(Vdbe *pVdbe){
+void sqlite3AbortOtherActiveVdbes(sqlite3 *db, Vdbe *pExcept){
   Vdbe *pOther;
-  for(pOther=pVdbe->db->pVdbe; pOther; pOther=pOther->pNext){
-    if( pOther==pVdbe ) continue;
+  for(pOther=db->pVdbe; pOther; pOther=pOther->pNext){
+    if( pOther==pExcept ) continue;
     if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue;
     closeAllCursors(pOther);
     pOther->aborted = 1;
@@ -1146,7 +1176,39 @@
   sqlite3 *db = p->db;
   int i;
   int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */
+  int isSpecialError;            /* Set to true if SQLITE_NOMEM or IOERR */
 
+  /* This function contains the logic that determines if a statement or
+  ** transaction will be committed or rolled back as a result of the
+  ** execution of this virtual machine. 
+  **
+  ** Special errors:
+  **
+  **     If an SQLITE_NOMEM error has occured in a statement that writes to
+  **     the database, then either a statement or transaction must be rolled
+  **     back to ensure the tree-structures are in a consistent state. A
+  **     statement transaction is rolled back if one is open, otherwise the
+  **     entire transaction must be rolled back.
+  **
+  **     If an SQLITE_IOERR error has occured in a statement that writes to
+  **     the database, then the entire transaction must be rolled back. The
+  **     I/O error may have caused garbage to be written to the journal 
+  **     file. Were the transaction to continue and eventually be rolled 
+  **     back that garbage might end up in the database file.
+  **     
+  **     In both of the above cases, the Vdbe.errorAction variable is 
+  **     ignored. If the sqlite3.autoCommit flag is false and a transaction
+  **     is rolled back, it will be set to true.
+  **
+  ** Other errors:
+  **
+  ** No error:
+  **
+  */
+
+  if( sqlite3MallocFailed() ){
+    p->rc = SQLITE_NOMEM;
+  }
   if( p->magic!=VDBE_MAGIC_RUN ){
     /* Already halted.  Nothing to do. */
     assert( p->magic==VDBE_MAGIC_HALT );
@@ -1154,67 +1216,133 @@
   }
   closeAllCursors(p);
   checkActiveVdbeCnt(db);
-  if( p->pc<0 ){
-    /* No commit or rollback needed if the program never started */
-  }else if( db->autoCommit && db->activeVdbeCnt==1 ){
-    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
-      /* The auto-commit flag is true, there are no other active queries
-      ** using this handle and the vdbe program was successful or hit an
-      ** 'OR FAIL' constraint. This means a commit is required.
+
+  /* No commit or rollback needed if the program never started */
+  if( p->pc>=0 ){
+
+    /* Check for one of the special errors - SQLITE_NOMEM or SQLITE_IOERR */
+    isSpecialError = ((p->rc==SQLITE_NOMEM || p->rc==SQLITE_IOERR)?1:0);
+    if( isSpecialError ){
+      /* This loop does static analysis of the query to see which of the
+      ** following three categories it falls into:
+      **
+      **     Read-only
+      **     Query with statement journal
+      **     Query without statement journal
+      **
+      ** We could do something more elegant than this static analysis (i.e.
+      ** store the type of query as part of the compliation phase), but 
+      ** handling malloc() or IO failure is a fairly obscure edge case so 
+      ** this is probably easier. Todo: Might be an opportunity to reduce 
+      ** code size a very small amount though...
       */
-      int rc = vdbeCommit(db);
-      if( rc==SQLITE_BUSY ){
-        return SQLITE_BUSY;
-      }else if( rc!=SQLITE_OK ){
-        p->rc = rc;
-        xFunc = sqlite3BtreeRollback;
+      int isReadOnly = 1;
+      int isStatement = 0;
+      assert(p->aOp || p->nOp==0);
+      for(i=0; i<p->nOp; i++){ 
+        switch( p->aOp[i].opcode ){
+          case OP_Transaction:
+            isReadOnly = 0;
+            break;
+          case OP_Statement:
+            isStatement = 1;
+            break;
+        }
       }
-    }else{
-      xFunc = sqlite3BtreeRollback;
+  
+      /* If the query was read-only, we need do no rollback at all. Otherwise,
+      ** proceed with the special handling.
+      */
+      if( !isReadOnly ){
+        if( p->rc==SQLITE_NOMEM && isStatement ){
+          xFunc = sqlite3BtreeRollbackStmt;
+        }else{
+          /* We are forced to roll back the active transaction. Before doing
+          ** so, abort any other statements this handle currently has active.
+          */
+          sqlite3AbortOtherActiveVdbes(db, p);
+          sqlite3RollbackAll(db);
+          db->autoCommit = 1;
+        }
+      }
     }
-  }else{
-    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
-      xFunc = sqlite3BtreeCommitStmt;
-    }else if( p->errorAction==OE_Abort ){
-      xFunc = sqlite3BtreeRollbackStmt;
-    }else{
-      xFunc = sqlite3BtreeRollback;
-      db->autoCommit = 1;
-      abortOtherActiveVdbes(p);
+  
+    /* If the auto-commit flag is set and this is the only active vdbe, then
+    ** we do either a commit or rollback of the current transaction. 
+    **
+    ** Note: This block also runs if one of the special errors handled 
+    ** above has occured. 
+    */
+    if( db->autoCommit && db->activeVdbeCnt==1 ){
+      if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
+	/* The auto-commit flag is true, and the vdbe program was 
+        ** successful or hit an 'OR FAIL' constraint. This means a commit 
+        ** is required.
+        */
+        int rc = vdbeCommit(db);
+        if( rc==SQLITE_BUSY ){
+          return SQLITE_BUSY;
+        }else if( rc!=SQLITE_OK ){
+          p->rc = rc;
+          sqlite3RollbackAll(db);
+        }else{
+          sqlite3CommitInternalChanges(db);
+        }
+      }else{
+        sqlite3RollbackAll(db);
+      }
+    }else if( !xFunc ){
+      if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
+        xFunc = sqlite3BtreeCommitStmt;
+      }else if( p->errorAction==OE_Abort ){
+        xFunc = sqlite3BtreeRollbackStmt;
+      }else{
+        sqlite3AbortOtherActiveVdbes(db, p);
+        sqlite3RollbackAll(db);
+        db->autoCommit = 1;
+      }
     }
-  }
-
-  /* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
-  ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
-  ** each backend. If an error occurs and the return code is still
-  ** SQLITE_OK, set the return code to the new error value.
-  */
-  for(i=0; xFunc && i<db->nDb; i++){ 
-    int rc;
-    Btree *pBt = db->aDb[i].pBt;
-    if( pBt ){
-      rc = xFunc(pBt);
-      if( p->rc==SQLITE_OK ) p->rc = rc;
+  
+    /* If xFunc is not NULL, then it is one of sqlite3BtreeRollbackStmt or
+    ** sqlite3BtreeCommitStmt. Call it once on each backend. If an error occurs
+    ** and the return code is still SQLITE_OK, set the return code to the new
+    ** error value.
+    */
+    assert(!xFunc ||
+      xFunc==sqlite3BtreeCommitStmt ||
+      xFunc==sqlite3BtreeRollbackStmt
+    );
+    for(i=0; xFunc && i<db->nDb; i++){ 
+      int rc;
+      Btree *pBt = db->aDb[i].pBt;
+      if( pBt ){
+        rc = xFunc(pBt);
+        if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
+          p->rc = rc;
+          sqlite3SetString(&p->zErrMsg, 0);
+        }
+      }
     }
-  }
-
-  /* If this was an INSERT, UPDATE or DELETE, set the change counter. */
-  if( p->changeCntOn && p->pc>=0 ){
-    if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
-      sqlite3VdbeSetChanges(db, p->nChange);
-    }else{
-      sqlite3VdbeSetChanges(db, 0);
+  
+    /* If this was an INSERT, UPDATE or DELETE and the statement was committed, 
+    ** set the change counter. 
+    */
+    if( p->changeCntOn && p->pc>=0 ){
+      if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
+        sqlite3VdbeSetChanges(db, p->nChange);
+      }else{
+        sqlite3VdbeSetChanges(db, 0);
+      }
+      p->nChange = 0;
     }
-    p->nChange = 0;
+  
+    /* Rollback or commit any schema changes that occurred. */
+    if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
+      sqlite3ResetInternalSchema(db, 0);
+      db->flags = (db->flags | SQLITE_InternChanges);
+    }
   }
 
-  /* Rollback or commit any schema changes that occurred. */
-  if( p->rc!=SQLITE_OK ){
-    sqlite3RollbackInternalChanges(db);
-  }else if( db->flags & SQLITE_InternChanges ){
-    sqlite3CommitInternalChanges(db);
-  }
-
   /* We have successfully halted and closed the VM.  Record this fact. */
   if( p->pc>=0 ){
     db->activeVdbeCnt--;
@@ -1255,8 +1383,9 @@
   */
   if( p->pc>=0 ){
     if( p->zErrMsg ){
-      sqlite3Error(p->db, p->rc, "%s", p->zErrMsg);
-      sqliteFree(p->zErrMsg);
+      sqlite3* db = p->db;
+      sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX);
+      db->errCode = p->rc;
       p->zErrMsg = 0;
     }else if( p->rc ){
       sqlite3Error(p->db, p->rc, 0);
@@ -1277,7 +1406,7 @@
 
   /* Save profiling information from this VDBE run.
   */
-  assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 );
+  assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || !p->aStack );
 #ifdef VDBE_PROFILE
   {
     FILE *out = fopen("vdbe_profile.out", "a");
@@ -1369,7 +1498,7 @@
   releaseMemArray(p->aVar, p->nVar);
   sqliteFree(p->aLabel);
   sqliteFree(p->aStack);
-  releaseMemArray(p->aColName, p->nResColumn*2);
+  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
   sqliteFree(p->aColName);
   p->magic = VDBE_MAGIC_DEAD;
   sqliteFree(p);
@@ -1401,7 +1530,7 @@
     }
     sqlite3_search_count++;
     p->deferredMoveto = 0;
-    p->cacheValid = 0;
+    p->cacheStatus = CACHE_STALE;
   }
   return SQLITE_OK;
 }
@@ -1438,16 +1567,20 @@
 **      5                     6            signed integer
 **      6                     8            signed integer
 **      7                     8            IEEE float
-**     8-11                                reserved for expansion
+**      8                     0            Integer constant 0
+**      9                     0            Integer constant 1
+**     10,11                               reserved for expansion
 **    N>=12 and even       (N-12)/2        BLOB
 **    N>=13 and odd        (N-13)/2        text
 **
+** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
+** of SQLite will not understand those serial types.
 */
 
 /*
 ** Return the serial-type for the value stored in pMem.
 */
-u32 sqlite3VdbeSerialType(Mem *pMem){
+u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
   int flags = pMem->flags;
 
   if( flags&MEM_Null ){
@@ -1457,7 +1590,11 @@
     /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
 #   define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
     i64 i = pMem->i;
-    u64 u = i<0 ? -i : i;
+    u64 u;
+    if( file_format>=4 && (i&1)==i ){
+      return 8+i;
+    }
+    u = i<0 ? -i : i;
     if( u<=127 ) return 1;
     if( u<=32767 ) return 2;
     if( u<=8388607 ) return 3;
@@ -1496,17 +1633,12 @@
 ** buf. It is assumed that the caller has allocated sufficient space.
 ** Return the number of bytes written.
 */ 
-int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
-  u32 serial_type = sqlite3VdbeSerialType(pMem);
+int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem, int file_format){
+  u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
   int len;
 
-  /* NULL */
-  if( serial_type==0 ){
-    return 0;
-  }
- 
   /* Integer and Real */
-  if( serial_type<=7 ){
+  if( serial_type<=7 && serial_type>0 ){
     u64 v;
     int i;
     if( serial_type==7 ){
@@ -1521,12 +1653,16 @@
     }
     return len;
   }
-  
+
   /* String or blob */
-  assert( serial_type>=12 );
-  len = sqlite3VdbeSerialTypeLen(serial_type);
-  memcpy(buf, pMem->z, len);
-  return len;
+  if( serial_type>=12 ){
+    len = sqlite3VdbeSerialTypeLen(serial_type);
+    memcpy(buf, pMem->z, len);
+    return len;
+  }
+
+  /* NULL or constants 0 or 1 */
+  return 0;
 }
 
 /*
@@ -1539,8 +1675,6 @@
   Mem *pMem                     /* Memory cell to write value into */
 ){
   switch( serial_type ){
-    case 8:    /* Reserved for future use */
-    case 9:    /* Reserved for future use */
     case 10:   /* Reserved for future use */
     case 11:   /* Reserved for future use */
     case 0: {  /* NULL */
@@ -1579,7 +1713,7 @@
     case 7: { /* IEEE floating point */
       u64 x;
       u32 y;
-#ifndef NDEBUG
+#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
       /* Verify that integers and floating point values use the same
       ** byte order.  The byte order differs on some (broken) architectures.
       */
@@ -1599,6 +1733,12 @@
       }
       return 8;
     }
+    case 8:    /* Integer 0 */
+    case 9: {  /* Integer 1 */
+      pMem->i = serial_type-8;
+      pMem->flags = MEM_Int;
+      return 0;
+    }
     default: {
       int len = (serial_type-12)/2;
       pMem->z = (char *)buf;
@@ -1616,6 +1756,23 @@
 }
 
 /*
+** The header of a record consists of a sequence variable-length integers.
+** These integers are almost always small and are encoded as a single byte.
+** The following macro takes advantage this fact to provide a fast decode
+** of the integers in a record header.  It is faster for the common case
+** where the integer is a single byte.  It is a little slower when the
+** integer is two or more bytes.  But overall it is faster.
+**
+** The following expressions are equivalent:
+**
+**     x = sqlite3GetVarint32( A, &B );
+**
+**     x = GetVarint( A, B );
+**
+*/
+#define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))
+
+/*
 ** This function compares the two table rows or index records specified by 
 ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
 ** or positive integer if {nKey1, pKey1} is less than, equal to or 
@@ -1642,9 +1799,9 @@
   mem1.enc = pKeyInfo->enc;
   mem2.enc = pKeyInfo->enc;
   
-  idx1 = sqlite3GetVarint32(pKey1, &szHdr1);
+  idx1 = GetVarint(aKey1, szHdr1);
   d1 = szHdr1;
-  idx2 = sqlite3GetVarint32(pKey2, &szHdr2);
+  idx2 = GetVarint(aKey2, szHdr2);
   d2 = szHdr2;
   nField = pKeyInfo->nField;
   while( idx1<szHdr1 && idx2<szHdr2 ){
@@ -1652,9 +1809,9 @@
     u32 serial_type2;
 
     /* Read the serial types for the next element in each key. */
-    idx1 += sqlite3GetVarint32(&aKey1[idx1], &serial_type1);
+    idx1 += GetVarint( aKey1+idx1, serial_type1 );
     if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
-    idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);
+    idx2 += GetVarint( aKey2+idx2, serial_type2 );
     if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
 
     /* Assert that there is enough space left in each key for the blob of
@@ -1686,9 +1843,8 @@
     }else if( d2<nKey2 ){
       rc = -1;
     }
-  }
-
-  if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){
+  }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField
+               && pKeyInfo->aSortOrder[i] ){
     rc = -rc;
   }
 
@@ -1701,7 +1857,7 @@
 ** an integer rowid).  This routine returns the number of bytes in
 ** that integer.
 */
-int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){
+int sqlite3VdbeIdxRowidLen(const u8 *aKey){
   u32 szHdr;        /* Size of the header */
   u32 typeRowid;    /* Serial type of the rowid */
 
@@ -1732,10 +1888,10 @@
   if( rc ){
     return rc;
   }
-  sqlite3GetVarint32(m.z, &szHdr);
-  sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid);
+  sqlite3GetVarint32((u8*)m.z, &szHdr);
+  sqlite3GetVarint32((u8*)&m.z[szHdr-1], &typeRowid);
   lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
-  sqlite3VdbeSerialGet(&m.z[m.n-lenRowid], typeRowid, &v);
+  sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
   *rowid = v.i;
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;
@@ -1771,7 +1927,7 @@
   if( rc ){
     return rc;
   }
-  lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z);
+  lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
   *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;

Modified: packages/libdbd-sqlite3-perl/trunk/vdbemem.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/vdbemem.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/vdbemem.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -41,11 +41,22 @@
 #ifdef SQLITE_OMIT_UTF16
   return SQLITE_ERROR;
 #else
+
+
+  /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
+  ** then the encoding of the value may not have changed.
+  */
   rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);
+  assert(rc==SQLITE_OK    || rc==SQLITE_NOMEM);
+  assert(rc==SQLITE_OK    || pMem->enc!=desiredEnc);
+  assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
+
   if( rc==SQLITE_NOMEM ){
+/*
     sqlite3VdbeMemRelease(pMem);
     pMem->flags = MEM_Null;
     pMem->z = 0;
+*/
   }
   return rc;
 #endif
@@ -73,7 +84,7 @@
   memcpy(z, pMem->z, n );
   z[n] = 0;
   z[n+1] = 0;
-  pMem->z = z;
+  pMem->z = (char*)z;
   pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
   return SQLITE_OK;
 }
@@ -93,7 +104,7 @@
   assert( (pMem->flags & MEM_Dyn)==0 );
   assert( pMem->flags & (MEM_Str|MEM_Blob) );
   if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
-    z = pMem->zShort;
+    z = (u8*)pMem->zShort;
     pMem->flags |= MEM_Short|MEM_Term;
   }else{
     z = sqliteMallocRaw( n+2 );
@@ -106,8 +117,9 @@
   memcpy(z, pMem->z, n );
   z[n] = 0;
   z[n+1] = 0;
-  pMem->z = z;
+  pMem->z = (char*)z;
   pMem->flags &= ~(MEM_Ephem|MEM_Static);
+  assert(0==(1&(int)pMem->z));
   return SQLITE_OK;
 }
 
@@ -162,7 +174,7 @@
 int sqlite3VdbeMemStringify(Mem *pMem, int enc){
   int rc = SQLITE_OK;
   int fg = pMem->flags;
-  u8 *z = pMem->zShort;
+  char *z = pMem->zShort;
 
   assert( !(fg&(MEM_Str|MEM_Blob)) );
   assert( fg&(MEM_Int|MEM_Real) );
@@ -173,11 +185,11 @@
   ** 
   ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
   */
-  if( fg & MEM_Real ){
+  if( fg & MEM_Int ){
+    sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
+  }else{
+    assert( fg & MEM_Real );
     sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
-  }else{
-    assert( fg & MEM_Int );
-    sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
   }
   pMem->n = strlen(z);
   pMem->z = z;
@@ -191,8 +203,12 @@
 ** Memory cell pMem contains the context of an aggregate function.
 ** This routine calls the finalize method for that function.  The
 ** result of the aggregate is stored back into pMem.
+**
+** Return SQLITE_ERROR if the finalizer reports an error.  SQLITE_OK
+** otherwise.
 */
-void sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
+int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
+  int rc = SQLITE_OK;
   if( pFunc && pFunc->xFinalize ){
     sqlite3_context ctx;
     assert( (pMem->flags & MEM_Null)!=0 || pFunc==*(FuncDef**)&pMem->i );
@@ -200,6 +216,7 @@
     ctx.s.z = pMem->zShort;
     ctx.pMem = pMem;
     ctx.pFunc = pFunc;
+    ctx.isError = 0;
     pFunc->xFinalize(&ctx);
     if( pMem->z && pMem->z!=pMem->zShort ){
       sqliteFree( pMem->z );
@@ -208,7 +225,11 @@
     if( pMem->flags & MEM_Short ){
       pMem->z = pMem->zShort;
     }
+    if( ctx.isError ){
+      rc = SQLITE_ERROR;
+    }
   }
+  return rc;
 }
 
 /*
@@ -254,7 +275,7 @@
     i64 value;
     if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
        || sqlite3VdbeMemNulTerminate(pMem) ){
-      return SQLITE_NOMEM;
+      return 0;
     }
     assert( pMem->z );
     sqlite3atoi64(pMem->z, &value);
@@ -265,16 +286,6 @@
 }
 
 /*
-** Convert pMem to type integer.  Invalidate any prior representations.
-*/
-int sqlite3VdbeMemIntegerify(Mem *pMem){
-  pMem->i = sqlite3VdbeIntValue(pMem);
-  sqlite3VdbeMemRelease(pMem);
-  pMem->flags = MEM_Int;
-  return SQLITE_OK;
-}
-
-/*
 ** Return the best representation of pMem that we can get into a
 ** double.  If pMem is already a double or an integer, return its
 ** value.  If it is a string or blob, try to convert it to a double.
@@ -289,7 +300,7 @@
     double val = 0.0;
     if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
        || sqlite3VdbeMemNulTerminate(pMem) ){
-      return SQLITE_NOMEM;
+      return 0.0;
     }
     assert( pMem->z );
     sqlite3AtoF(pMem->z, &val);
@@ -300,9 +311,31 @@
 }
 
 /*
-** Convert pMem so that it is of type MEM_Real.  Invalidate any
-** prior representations.
+** The MEM structure is already a MEM_Real.  Try to also make it a
+** MEM_Int if we can.
 */
+void sqlite3VdbeIntegerAffinity(Mem *pMem){
+  assert( pMem->flags & MEM_Real );
+  pMem->i = pMem->r;
+  if( ((double)pMem->i)==pMem->r ){
+    pMem->flags |= MEM_Int;
+  }
+}
+
+/*
+** Convert pMem to type integer.  Invalidate any prior representations.
+*/
+int sqlite3VdbeMemIntegerify(Mem *pMem){
+  pMem->i = sqlite3VdbeIntValue(pMem);
+  sqlite3VdbeMemRelease(pMem);
+  pMem->flags = MEM_Int;
+  return SQLITE_OK;
+}
+
+/*
+** Convert pMem so that it is of type MEM_Real.
+** Invalidate any prior representations.
+*/
 int sqlite3VdbeMemRealify(Mem *pMem){
   pMem->r = sqlite3VdbeRealValue(pMem);
   sqlite3VdbeMemRelease(pMem);
@@ -311,6 +344,16 @@
 }
 
 /*
+** Convert pMem so that it has types MEM_Real or MEM_Int or both.
+** Invalidate any prior representations.
+*/
+int sqlite3VdbeMemNumerify(Mem *pMem){
+  sqlite3VdbeMemRealify(pMem);
+  sqlite3VdbeIntegerAffinity(pMem);
+  return SQLITE_OK;
+}
+
+/*
 ** Delete any previous value and set the value stored in *pMem to NULL.
 */
 void sqlite3VdbeMemSetNull(Mem *pMem){
@@ -547,27 +590,33 @@
     assert( pMem1->enc==SQLITE_UTF8 || 
             pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
 
-    /* This assert may fail if the collation sequence is deleted after this
-    ** vdbe program is compiled. The documentation defines this as an
-    ** undefined condition. A crash is usual result.
+    /* The collation sequence must be defined at this point, even if
+    ** the user deletes the collation sequence after the vdbe program is
+    ** compiled (this was not always the case).
     */
     assert( !pColl || pColl->xCmp );
 
     if( pColl ){
       if( pMem1->enc==pColl->enc ){
+        /* The strings are already in the correct encoding.  Call the
+        ** comparison function directly */
         return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
       }else{
         u8 origEnc = pMem1->enc;
-        rc = pColl->xCmp(
-          pColl->pUser,
-          sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc),
-          sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc),
-          sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc),
-          sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc)
-        );
-        sqlite3ValueBytes((sqlite3_value*)pMem1, origEnc);
+        const void *v1, *v2;
+        int n1, n2;
+        /* Convert the strings into the encoding that the comparison
+        ** function expects */
+        v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc);
+        n1 = v1==0 ? 0 : pMem1->n;
+        assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) );
+        v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc);
+        n2 = v2==0 ? 0 : pMem2->n;
+        assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) );
+        /* Do the comparison */
+        rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
+        /* Convert the strings back into the database encoding */
         sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
-        sqlite3ValueBytes((sqlite3_value*)pMem2, origEnc);
         sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
         return rc;
       }
@@ -662,7 +711,7 @@
 ** Perform various checks on the memory cell pMem. An assert() will
 ** fail if pMem is internally inconsistent.
 */
-void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){
+void sqlite3VdbeMemSanity(Mem *pMem){
   int flags = pMem->flags;
   assert( flags!=0 );  /* Must define some type */
   if( pMem->flags & (MEM_Str|MEM_Blob) ){
@@ -711,20 +760,38 @@
 ** except the data returned is in the encoding specified by the second
 ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
 ** SQLITE_UTF8.
+**
+** (2006-02-16:)  The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
+** If that is the case, then the result must be aligned on an even byte
+** boundary.
 */
 const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
   if( !pVal ) return 0;
-  assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8);
+  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
 
   if( pVal->flags&MEM_Null ){
     return 0;
   }
+  assert( (MEM_Blob>>3) == MEM_Str );
+  pVal->flags |= (pVal->flags & MEM_Blob)>>3;
   if( pVal->flags&MEM_Str ){
-    sqlite3VdbeChangeEncoding(pVal, enc);
+    sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
+    if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){
+      assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
+      if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
+        return 0;
+      }
+    }
   }else if( !(pVal->flags&MEM_Blob) ){
     sqlite3VdbeMemStringify(pVal, enc);
+    assert( 0==(1&(int)pVal->z) );
   }
-  return (const void *)(pVal->z);
+  assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || sqlite3MallocFailed() );
+  if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
+    return pVal->z;
+  }else{
+    return 0;
+  }
 }
 
 /*
@@ -766,7 +833,7 @@
   op = pExpr->op;
 
   if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
-    zVal = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
+    zVal = sqliteStrNDup((char*)pExpr->token.z, pExpr->token.n);
     pVal = sqlite3ValueNew();
     if( !zVal || !pVal ) goto no_mem;
     sqlite3Dequote(zVal);
@@ -786,7 +853,7 @@
   else if( op==TK_BLOB ){
     int nVal;
     pVal = sqlite3ValueNew();
-    zVal = sqliteStrNDup(pExpr->token.z+1, pExpr->token.n-1);
+    zVal = sqliteStrNDup((char*)pExpr->token.z+1, pExpr->token.n-1);
     if( !zVal || !pVal ) goto no_mem;
     sqlite3Dequote(zVal);
     nVal = strlen(zVal)/2;

Modified: packages/libdbd-sqlite3-perl/trunk/where.c
===================================================================
--- packages/libdbd-sqlite3-perl/trunk/where.c	2006-04-18 15:19:32 UTC (rev 2604)
+++ packages/libdbd-sqlite3-perl/trunk/where.c	2006-04-18 15:20:48 UTC (rev 2605)
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.179 2005/09/20 17:42:23 drh Exp $
+** $Id: where.c,v 1.206 2006/03/28 23:55:58 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -83,7 +83,7 @@
   i16 iParent;            /* Disable pWC->a[iParent] when this term disabled */
   i16 leftCursor;         /* Cursor number of X in "X <op> <expr>" */
   i16 leftColumn;         /* Column number of X in "X <op> <expr>" */
-  u16 operator;           /* A WO_xx value describing <op> */
+  u16 eOperator;          /* A WO_xx value describing <op> */
   u8 flags;               /* Bit flags.  See below */
   u8 nChild;              /* Number of children that must disable us */
   WhereClause *pWC;       /* The clause this term is part of */
@@ -418,13 +418,13 @@
     if( pTerm->leftCursor==iCur
        && (pTerm->prereqRight & notReady)==0
        && pTerm->leftColumn==iColumn
-       && (pTerm->operator & op)!=0
+       && (pTerm->eOperator & op)!=0
     ){
       if( iCur>=0 && pIdx ){
         Expr *pX = pTerm->pExpr;
         CollSeq *pColl;
         char idxaff;
-        int k;
+        int j;
         Parse *pParse = pWC->pParse;
 
         idxaff = pIdx->pTable->aCol[iColumn].affinity;
@@ -438,9 +438,9 @@
             pColl = pParse->db->pDfltColl;
           }
         }
-        for(k=0; k<pIdx->nColumn && pIdx->aiColumn[k]!=iColumn; k++){}
-        assert( k<pIdx->nColumn );
-        if( pColl!=pIdx->keyInfo.aColl[k] ) continue;
+        for(j=0; j<pIdx->nColumn && pIdx->aiColumn[j]!=iColumn; j++){}
+        assert( j<pIdx->nColumn );
+        if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
       }
       return pTerm;
     }
@@ -511,7 +511,7 @@
     return 0;
   }
   sqlite3DequoteExpr(pRight);
-  z = pRight->token.z;
+  z = (char *)pRight->token.z;
   for(cnt=0; (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2]; cnt++){}
   if( cnt==0 || 255==(u8)z[cnt] ){
     return 0;
@@ -523,6 +523,16 @@
 #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
 
 /*
+** If the pBase expression originated in the ON or USING clause of
+** a join, then transfer the appropriate markings over to derived.
+*/
+static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
+  pDerived->flags |= pBase->flags & EP_FromJoin;
+  pDerived->iRightJoinTable = pBase->iRightJoinTable;
+}
+
+
+/*
 ** The input to this routine is an WhereTerm structure with only the
 ** "pExpr" field filled in.  The job of this routine is to analyze the
 ** subexpression and populate all the other fields of the WhereTerm
@@ -547,7 +557,7 @@
   int nPattern;
   int isComplete;
 
-  if( sqlite3_malloc_failed ) return;
+  if( sqlite3MallocFailed() ) return;
   prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
   if( pExpr->op==TK_IN ){
     assert( pExpr->pRight==0 );
@@ -563,14 +573,14 @@
   pTerm->prereqAll = prereqAll;
   pTerm->leftCursor = -1;
   pTerm->iParent = -1;
-  pTerm->operator = 0;
+  pTerm->eOperator = 0;
   if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){
     Expr *pLeft = pExpr->pLeft;
     Expr *pRight = pExpr->pRight;
     if( pLeft->op==TK_COLUMN ){
       pTerm->leftCursor = pLeft->iTable;
       pTerm->leftColumn = pLeft->iColumn;
-      pTerm->operator = operatorMask(pExpr->op);
+      pTerm->eOperator = operatorMask(pExpr->op);
     }
     if( pRight && pRight->op==TK_COLUMN ){
       WhereTerm *pNew;
@@ -595,7 +605,7 @@
       pNew->leftColumn = pLeft->iColumn;
       pNew->prereqRight = prereqLeft;
       pNew->prereqAll = prereqAll;
-      pNew->operator = operatorMask(pDup->op);
+      pNew->eOperator = operatorMask(pDup->op);
     }
   }
 
@@ -623,7 +633,7 @@
   }
 #endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */
 
-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
+#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
   /* Attempt to convert OR-connected terms into an IN operator so that
   ** they can make use of indices.  Example:
   **
@@ -632,6 +642,9 @@
   ** is converted into
   **
   **      x IN (expr1,expr2,expr3)
+  **
+  ** This optimization must be omitted if OMIT_SUBQUERY is defined because
+  ** the compiler for the the IN operator is part of sub-queries.
   */
   else if( pExpr->op==TK_OR ){
     int ok;
@@ -651,7 +664,7 @@
       iCursor = sOr.a[j].leftCursor;
       ok = iCursor>=0;
       for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){
-        if( pOrTerm->operator!=WO_EQ ){
+        if( pOrTerm->eOperator!=WO_EQ ){
           goto or_not_possible;
         }
         if( pOrTerm->leftCursor==iCursor && pOrTerm->leftColumn==iColumn ){
@@ -680,14 +693,17 @@
       }
       pNew = sqlite3Expr(TK_IN, pDup, 0, 0);
       if( pNew ){
+        int idxNew;
+        transferJoinMarkings(pNew, pExpr);
         pNew->pList = pList;
+        idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
+        exprAnalyze(pSrc, pMaskSet, pWC, idxNew);
+        pTerm = &pWC->a[idxTerm];
+        pWC->a[idxNew].iParent = idxTerm;
+        pTerm->nChild = 1;
       }else{
         sqlite3ExprListDelete(pList);
       }
-      pTerm->pExpr = pNew;
-      pTerm->flags |= TERM_DYNAMIC;
-      exprAnalyze(pSrc, pMaskSet, pWC, idxTerm);
-      pTerm = &pWC->a[idxTerm];
     }
 or_not_possible:
     whereClauseClear(&sOr);
@@ -755,14 +771,13 @@
 static int isSortingIndex(
   Parse *pParse,          /* Parsing context */
   Index *pIdx,            /* The index we are testing */
-  Table *pTab,            /* The table to be sorted */
-  int base,               /* Cursor number for pTab */
+  int base,               /* Cursor number for the table to be sorted */
   ExprList *pOrderBy,     /* The ORDER BY clause */
   int nEqCol,             /* Number of index columns with == constraints */
   int *pbRev              /* Set to 1 if ORDER BY is DESC */
 ){
   int i, j;                       /* Loop counters */
-  int sortOrder = SQLITE_SO_ASC;  /* Which direction we are sorting */
+  int sortOrder = 0;              /* XOR of index and ORDER BY sort direction */
   int nTerm;                      /* Number of ORDER BY terms */
   struct ExprList_item *pTerm;    /* A term of the ORDER BY clause */
   sqlite3 *db = pParse->db;
@@ -777,6 +792,7 @@
   for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){
     Expr *pExpr;       /* The expression of the ORDER BY pTerm */
     CollSeq *pColl;    /* The collating sequence of pExpr */
+    int termSortOrder; /* Sort order for this term */
 
     pExpr = pTerm->pExpr;
     if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
@@ -786,7 +802,8 @@
     }
     pColl = sqlite3ExprCollSeq(pParse, pExpr);
     if( !pColl ) pColl = db->pDfltColl;
-    if( pExpr->iColumn!=pIdx->aiColumn[i] || pColl!=pIdx->keyInfo.aColl[i] ){
+    if( pExpr->iColumn!=pIdx->aiColumn[i] || 
+        sqlite3StrICmp(pColl->zName, pIdx->azColl[i]) ){
       /* Term j of the ORDER BY clause does not match column i of the index */
       if( i<nEqCol ){
         /* If an index column that is constrained by == fails to match an
@@ -800,14 +817,18 @@
         return 0;
       }
     }
+    assert( pIdx->aSortOrder!=0 );
+    assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
+    assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 );
+    termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder;
     if( i>nEqCol ){
-      if( pTerm->sortOrder!=sortOrder ){
+      if( termSortOrder!=sortOrder ){
         /* Indices can only be used if all ORDER BY terms past the
         ** equality constraints are all either DESC or ASC. */
         return 0;
       }
     }else{
-      sortOrder = pTerm->sortOrder;
+      sortOrder = termSortOrder;
     }
     j++;
     pTerm++;
@@ -817,7 +838,7 @@
   ** are covered.
   */
   if( j>=nTerm ){
-    *pbRev = sortOrder==SQLITE_SO_DESC;
+    *pbRev = sortOrder!=0;
     return 1;
   }
   return 0;
@@ -854,10 +875,10 @@
 ** logN is a little off.
 */
 static double estLog(double N){
-  double logN = 1.0;
-  double x = 10.0;
+  double logN = 1;
+  double x = 10;
   while( N>x ){
-    logN += 1.0;
+    logN += 1;
     x *= 10;
   }
   return logN;
@@ -893,7 +914,7 @@
 ){
   WhereTerm *pTerm;
   Index *bestIdx = 0;         /* Index that gives the lowest cost */
-  double lowestCost = 1.0e99; /* The cost of using bestIdx */
+  double lowestCost;          /* The cost of using bestIdx */
   int bestFlags = 0;          /* Flags associated with bestIdx */
   int bestNEq = 0;            /* Best value for nEq */
   int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
@@ -904,7 +925,24 @@
   double cost;                /* Cost of using pProbe */
 
   TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
+  lowestCost = SQLITE_BIG_DBL;
+  pProbe = pSrc->pTab->pIndex;
 
+  /* If the table has no indices and there are no terms in the where
+  ** clause that refer to the ROWID, then we will never be able to do
+  ** anything other than a full table scan on this table.  We might as
+  ** well put it first in the join order.  That way, perhaps it can be
+  ** referenced by other tables in the join.
+  */
+  if( pProbe==0 &&
+     findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 &&
+     (pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, &rev)) ){
+    *pFlags = 0;
+    *ppIndex = 0;
+    *pnEq = 0;
+    return 0.0;
+  }
+
   /* Check for a rowid=EXPR or rowid IN (...) constraints
   */
   pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
@@ -912,7 +950,7 @@
     Expr *pExpr;
     *ppIndex = 0;
     bestFlags = WHERE_ROWID_EQ;
-    if( pTerm->operator & WO_EQ ){
+    if( pTerm->eOperator & WO_EQ ){
       /* Rowid== is always the best pick.  Look no further.  Because only
       ** a single row is generated, output is always in sorted order */
       *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
@@ -928,7 +966,7 @@
       /* Rowid IN (SELECT): cost is NlogN where N is the number of rows
       ** in the result of the inner select.  We have no way to estimate
       ** that value so make a wild guess. */
-      lowestCost = 200.0;
+      lowestCost = 200;
     }
     TRACE(("... rowid IN cost: %.9g\n", lowestCost));
   }
@@ -936,8 +974,7 @@
   /* Estimate the cost of a table scan.  If we do not know how many
   ** entries are in the table, use 1 million as a guess.
   */
-  pProbe = pSrc->pTab->pIndex;
-  cost = pProbe ? pProbe->aiRowEst[0] : 1000000.0;
+  cost = pProbe ? pProbe->aiRowEst[0] : 1000000;
   TRACE(("... table scan base cost: %.9g\n", cost));
   flags = WHERE_ROWID_RANGE;
 
@@ -947,11 +984,11 @@
   if( pTerm ){
     if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){
       flags |= WHERE_TOP_LIMIT;
-      cost *= 0.333;  /* Guess that rowid<EXPR eliminates two-thirds or rows */
+      cost /= 3;  /* Guess that rowid<EXPR eliminates two-thirds or rows */
     }
     if( findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0) ){
       flags |= WHERE_BTM_LIMIT;
-      cost *= 0.333;  /* Guess that rowid>EXPR eliminates two-thirds of rows */
+      cost /= 3;  /* Guess that rowid>EXPR eliminates two-thirds of rows */
     }
     TRACE(("... rowid range reduces cost to %.9g\n", cost));
   }else{
@@ -980,7 +1017,7 @@
   */
   for(; pProbe; pProbe=pProbe->pNext){
     int i;                       /* Loop counter */
-    double inMultiplier = 1.0;
+    double inMultiplier = 1;
 
     TRACE(("... index %s:\n", pProbe->zName));
 
@@ -993,13 +1030,13 @@
       pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe);
       if( pTerm==0 ) break;
       flags |= WHERE_COLUMN_EQ;
-      if( pTerm->operator & WO_IN ){
+      if( pTerm->eOperator & WO_IN ){
         Expr *pExpr = pTerm->pExpr;
         flags |= WHERE_COLUMN_IN;
         if( pExpr->pSelect!=0 ){
-          inMultiplier *= 100.0;
+          inMultiplier *= 100;
         }else if( pExpr->pList!=0 ){
-          inMultiplier *= pExpr->pList->nExpr + 1.0;
+          inMultiplier *= pExpr->pList->nExpr + 1;
         }
       }
     }
@@ -1020,11 +1057,11 @@
         flags |= WHERE_COLUMN_RANGE;
         if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){
           flags |= WHERE_TOP_LIMIT;
-          cost *= 0.333;
+          cost /= 3;
         }
         if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){
           flags |= WHERE_BTM_LIMIT;
-          cost *= 0.333;
+          cost /= 3;
         }
         TRACE(("...... range reduces cost to %.9g\n", cost));
       }
@@ -1034,7 +1071,7 @@
     */
     if( pOrderBy ){
       if( (flags & WHERE_COLUMN_IN)==0 &&
-           isSortingIndex(pParse,pProbe,pSrc->pTab,iCur,pOrderBy,nEq,&rev) ){
+           isSortingIndex(pParse,pProbe,iCur,pOrderBy,nEq,&rev) ){
         if( flags==0 ){
           flags = WHERE_COLUMN_RANGE;
         }
@@ -1063,7 +1100,7 @@
       }
       if( m==0 ){
         flags |= WHERE_IDX_ONLY;
-        cost *= 0.5;
+        cost /= 2;
         TRACE(("...... idx-only reduces cost to %.9g\n", cost));
       }
     }
@@ -1134,14 +1171,24 @@
 **    *  Check the top nColumn entries on the stack.  If any
 **       of those entries are NULL, jump immediately to brk,
 **       which is the loop exit, since no index entry will match
-**       if any part of the key is NULL.
+**       if any part of the key is NULL. Pop (nColumn+nExtra) 
+**       elements from the stack.
 **
 **    *  Construct a probe entry from the top nColumn entries in
-**       the stack with affinities appropriate for index pIdx.
+**       the stack with affinities appropriate for index pIdx. 
+**       Only nColumn elements are popped from the stack in this case
+**       (by OP_MakeRecord).
+**
 */
-static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){
+static void buildIndexProbe(
+  Vdbe *v, 
+  int nColumn, 
+  int nExtra, 
+  int brk, 
+  Index *pIdx
+){
   sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
-  sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
+  sqlite3VdbeAddOp(v, OP_Pop, nColumn+nExtra, 0);
   sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
   sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
   sqlite3IndexAffinityStr(v, pIdx);
@@ -1180,7 +1227,7 @@
     sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);
     VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));
     pLevel->nIn++;
-    sqlite3ReallocOrFree((void**)&pLevel->aInLoop,
+    sqliteReallocOrFree((void**)&pLevel->aInLoop,
                                  sizeof(pLevel->aInLoop[0])*3*pLevel->nIn);
     aIn = pLevel->aInLoop;
     if( aIn ){
@@ -1408,7 +1455,7 @@
   ** return value.
   */
   pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
-  if( sqlite3_malloc_failed ){
+  if( sqlite3MallocFailed() ){
     goto whereBeginNoMem;
   }
   pWInfo->pParse = pParse;
@@ -1432,7 +1479,7 @@
     createMask(&maskSet, pTabList->a[i].iCursor);
   }
   exprAnalyzeAll(pTabList, &maskSet, &wc);
-  if( sqlite3_malloc_failed ){
+  if( sqlite3MallocFailed() ){
     goto whereBeginNoMem;
   }
 
@@ -1464,11 +1511,19 @@
     Index *pBest = 0;           /* The best index seen so far */
     int bestFlags = 0;          /* Flags associated with pBest */
     int bestNEq = 0;            /* nEq associated with pBest */
-    double lowestCost = 1.0e99; /* Cost of the pBest */
-    int bestJ;                  /* The value of j */
+    double lowestCost;          /* Cost of the pBest */
+    int bestJ = 0;              /* The value of j */
     Bitmask m;                  /* Bitmask value for j or bestJ */
+    int once = 0;               /* True when first table is seen */
 
+    lowestCost = SQLITE_BIG_DBL;
     for(j=iFrom, pTabItem=&pTabList->a[j]; j<pTabList->nSrc; j++, pTabItem++){
+      if( once && 
+          ((pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
+           || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0))
+      ){
+        break;
+      }
       m = getMask(&maskSet, pTabItem->iCursor);
       if( (m & notReady)==0 ){
         if( j==iFrom ) iFrom++;
@@ -1478,17 +1533,13 @@
                        (i==0 && ppOrderBy) ? *ppOrderBy : 0,
                        &pIdx, &flags, &nEq);
       if( cost<lowestCost ){
+        once = 1;
         lowestCost = cost;
         pBest = pIdx;
         bestFlags = flags;
         bestNEq = nEq;
         bestJ = j;
       }
-      if( (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
-         || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0)
-      ){
-        break;
-      }
     }
     TRACE(("*** Optimizer choose table %d for loop %d\n", bestJ,
            pLevel-pWInfo->a));
@@ -1524,8 +1575,9 @@
   sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
   pLevel = pWInfo->a;
   for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
-    Table *pTab;
-    Index *pIx;
+    Table *pTab;     /* Table to open */
+    Index *pIx;      /* Index used to access pTab (if any) */
+    int iDb;         /* Index of database containing table/index */
     int iIdxCur = pLevel->iIdxCur;
 
 #ifndef SQLITE_OMIT_EXPLAIN
@@ -1538,27 +1590,41 @@
       }
       if( (pIx = pLevel->pIdx)!=0 ){
         zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName);
+      }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+        zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg);
       }
       sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC);
     }
 #endif /* SQLITE_OMIT_EXPLAIN */
     pTabItem = &pTabList->a[pLevel->iFrom];
     pTab = pTabItem->pTab;
+    iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
     if( pTab->isTransient || pTab->pSelect ) continue;
     if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
-      sqlite3OpenTableForReading(v, pTabItem->iCursor, pTab);
+      sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead);
+      if( pTab->nCol<(sizeof(Bitmask)*8) ){
+        Bitmask b = pTabItem->colUsed;
+        int n = 0;
+        for(; b; b=b>>1, n++){}
+        sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-1, n);
+        assert( n<=pTab->nCol );
+      }
+    }else{
+      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
     }
     pLevel->iTabCur = pTabItem->iCursor;
     if( (pIx = pLevel->pIdx)!=0 ){
-      sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
+      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
+      assert( pIx->pSchema==pTab->pSchema );
+      sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
       VdbeComment((v, "# %s", pIx->zName));
       sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
-                     (char*)&pIx->keyInfo, P3_KEYINFO);
+                     (char*)pKey, P3_KEYINFO_HANDOFF);
     }
     if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){
       sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
     }
-    sqlite3CodeVerifySchema(pParse, pTab->iDb);
+    sqlite3CodeVerifySchema(pParse, iDb);
   }
   pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
 
@@ -1667,7 +1733,7 @@
       if( testOp!=OP_Noop ){
         sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
         sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-        sqlite3VdbeAddOp(v, testOp, 'n', brk);
+        sqlite3VdbeAddOp(v, testOp, SQLITE_AFF_NUMERIC, brk);
       }
     }else if( pLevel->flags & WHERE_COLUMN_RANGE ){
       /* Case 3: The WHERE clause term that refers to the right-most
@@ -1683,8 +1749,11 @@
       */
       int start;
       int nEq = pLevel->nEq;
-      int leFlag=0, geFlag=0;
+      int topEq=0;        /* True if top limit uses ==. False is strictly < */
+      int btmEq=0;        /* True if btm limit uses ==. False if strictly > */
+      int topOp, btmOp;   /* Operators for the top and bottom search bounds */
       int testOp;
+      int nNotNull;       /* Number of rows of index that must be non-NULL */
       int topLimit = (pLevel->flags & WHERE_TOP_LIMIT)!=0;
       int btmLimit = (pLevel->flags & WHERE_BTM_LIMIT)!=0;
 
@@ -1701,6 +1770,21 @@
         sqlite3VdbeAddOp(v, OP_Dup, nEq-1, 0);
       }
 
+      /* Figure out what comparison operators to use for top and bottom 
+      ** search bounds. For an ascending index, the bottom bound is a > or >=
+      ** operator and the top bound is a < or <= operator.  For a descending
+      ** index the operators are reversed.
+      */
+      nNotNull = nEq + topLimit;
+      if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){
+        topOp = WO_LT|WO_LE;
+        btmOp = WO_GT|WO_GE;
+      }else{
+        topOp = WO_GT|WO_GE;
+        btmOp = WO_LT|WO_LE;
+        SWAP(int, topLimit, btmLimit);
+      }
+
       /* Generate the termination key.  This is the key value that
       ** will end the search.  There is no termination key if there
       ** are no equality terms and no "X<..." term.
@@ -1711,24 +1795,24 @@
       if( topLimit ){
         Expr *pX;
         int k = pIdx->aiColumn[j];
-        pTerm = findTerm(&wc, iCur, k, notReady, WO_LT|WO_LE, pIdx);
+        pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx);
         assert( pTerm!=0 );
         pX = pTerm->pExpr;
         assert( (pTerm->flags & TERM_CODED)==0 );
         sqlite3ExprCode(pParse, pX->pRight);
-        leFlag = pX->op==TK_LE;
+        topEq = pTerm->eOperator & (WO_LE|WO_GE);
         disableTerm(pLevel, pTerm);
         testOp = OP_IdxGE;
       }else{
         testOp = nEq>0 ? OP_IdxGE : OP_Noop;
-        leFlag = 1;
+        topEq = 1;
       }
       if( testOp!=OP_Noop ){
         int nCol = nEq + topLimit;
         pLevel->iMem = pParse->nMem++;
-        buildIndexProbe(v, nCol, brk, pIdx);
+        buildIndexProbe(v, nCol, nEq, brk, pIdx);
         if( bRev ){
-          int op = leFlag ? OP_MoveLe : OP_MoveLt;
+          int op = topEq ? OP_MoveLe : OP_MoveLt;
           sqlite3VdbeAddOp(v, op, iIdxCur, brk);
         }else{
           sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
@@ -1749,25 +1833,25 @@
       if( btmLimit ){
         Expr *pX;
         int k = pIdx->aiColumn[j];
-        pTerm = findTerm(&wc, iCur, k, notReady, WO_GT|WO_GE, pIdx);
+        pTerm = findTerm(&wc, iCur, k, notReady, btmOp, pIdx);
         assert( pTerm!=0 );
         pX = pTerm->pExpr;
         assert( (pTerm->flags & TERM_CODED)==0 );
         sqlite3ExprCode(pParse, pX->pRight);
-        geFlag = pX->op==TK_GE;
+        btmEq = pTerm->eOperator & (WO_LE|WO_GE);
         disableTerm(pLevel, pTerm);
       }else{
-        geFlag = 1;
+        btmEq = 1;
       }
       if( nEq>0 || btmLimit ){
         int nCol = nEq + btmLimit;
-        buildIndexProbe(v, nCol, brk, pIdx);
+        buildIndexProbe(v, nCol, 0, brk, pIdx);
         if( bRev ){
           pLevel->iMem = pParse->nMem++;
           sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
           testOp = OP_IdxLT;
         }else{
-          int op = geFlag ? OP_MoveGe : OP_MoveGt;
+          int op = btmEq ? OP_MoveGe : OP_MoveGt;
           sqlite3VdbeAddOp(v, op, iIdxCur, brk);
         }
       }else if( bRev ){
@@ -1784,12 +1868,12 @@
       if( testOp!=OP_Noop ){
         sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
         sqlite3VdbeAddOp(v, testOp, iIdxCur, brk);
-        if( (leFlag && !bRev) || (!geFlag && bRev) ){
+        if( (topEq && !bRev) || (!btmEq && bRev) ){
           sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
         }
       }
       sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
-      sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq + topLimit, cont);
+      sqlite3VdbeAddOp(v, OP_IdxIsNull, nNotNull, cont);
       if( !omitTable ){
         sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
         sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
@@ -1815,7 +1899,7 @@
       /* Generate a single key that will be used to both start and terminate
       ** the search
       */
-      buildIndexProbe(v, nEq, brk, pIdx);
+      buildIndexProbe(v, nEq, 0, brk, pIdx);
       sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
 
       /* Generate code (1) to move to the first matching element of the table.
@@ -2018,14 +2102,14 @@
     ** reference the index.
     */
     if( pLevel->flags & WHERE_IDX_ONLY ){
-      int i, j, last;
+      int k, j, last;
       VdbeOp *pOp;
       Index *pIdx = pLevel->pIdx;
 
       assert( pIdx!=0 );
       pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
       last = sqlite3VdbeCurrentAddr(v);
-      for(i=pWInfo->iTop; i<last; i++, pOp++){
+      for(k=pWInfo->iTop; k<last; k++, pOp++){
         if( pOp->p1!=pLevel->iTabCur ) continue;
         if( pOp->opcode==OP_Column ){
           pOp->p1 = pLevel->iIdxCur;




More information about the Pkg-perl-cvs-commits mailing list