]> granicus.if.org Git - php/commitdiff
Upgrade libsqlite 3 inside PDO sqlite to version 3.3.15
authorIlia Alshanetsky <iliaa@php.net>
Mon, 9 Apr 2007 16:35:11 +0000 (16:35 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Mon, 9 Apr 2007 16:35:11 +0000 (16:35 +0000)
51 files changed:
NEWS
ext/pdo_sqlite/sqlite/VERSION
ext/pdo_sqlite/sqlite/src/analyze.c
ext/pdo_sqlite/sqlite/src/attach.c
ext/pdo_sqlite/sqlite/src/btree.c
ext/pdo_sqlite/sqlite/src/btree.h
ext/pdo_sqlite/sqlite/src/build.c
ext/pdo_sqlite/sqlite/src/date.c
ext/pdo_sqlite/sqlite/src/expr.c
ext/pdo_sqlite/sqlite/src/func.c
ext/pdo_sqlite/sqlite/src/hash.c
ext/pdo_sqlite/sqlite/src/insert.c
ext/pdo_sqlite/sqlite/src/keywordhash.h
ext/pdo_sqlite/sqlite/src/loadext.c
ext/pdo_sqlite/sqlite/src/main.c
ext/pdo_sqlite/sqlite/src/opcodes.c
ext/pdo_sqlite/sqlite/src/opcodes.h
ext/pdo_sqlite/sqlite/src/os.c
ext/pdo_sqlite/sqlite/src/os.h
ext/pdo_sqlite/sqlite/src/os_common.h
ext/pdo_sqlite/sqlite/src/os_unix.c
ext/pdo_sqlite/sqlite/src/os_win.c
ext/pdo_sqlite/sqlite/src/pager.c
ext/pdo_sqlite/sqlite/src/pager.h
ext/pdo_sqlite/sqlite/src/parse.c
ext/pdo_sqlite/sqlite/src/parse.h
ext/pdo_sqlite/sqlite/src/parse.y
ext/pdo_sqlite/sqlite/src/pragma.c
ext/pdo_sqlite/sqlite/src/prepare.c
ext/pdo_sqlite/sqlite/src/printf.c
ext/pdo_sqlite/sqlite/src/select.c
ext/pdo_sqlite/sqlite/src/shell.c
ext/pdo_sqlite/sqlite/src/sqlite.h.in
ext/pdo_sqlite/sqlite/src/sqlite3ext.h
ext/pdo_sqlite/sqlite/src/sqliteInt.h
ext/pdo_sqlite/sqlite/src/tclsqlite.c
ext/pdo_sqlite/sqlite/src/test1.c
ext/pdo_sqlite/sqlite/src/test2.c
ext/pdo_sqlite/sqlite/src/test3.c
ext/pdo_sqlite/sqlite/src/trigger.c
ext/pdo_sqlite/sqlite/src/update.c
ext/pdo_sqlite/sqlite/src/utf.c
ext/pdo_sqlite/sqlite/src/util.c
ext/pdo_sqlite/sqlite/src/vacuum.c
ext/pdo_sqlite/sqlite/src/vdbe.c
ext/pdo_sqlite/sqlite/src/vdbeInt.h
ext/pdo_sqlite/sqlite/src/vdbeapi.c
ext/pdo_sqlite/sqlite/src/vdbeaux.c
ext/pdo_sqlite/sqlite/src/vdbefifo.c
ext/pdo_sqlite/sqlite/src/vdbemem.c
ext/pdo_sqlite/sqlite/src/where.c

diff --git a/NEWS b/NEWS
index 57dfea8aa00ecdaffc0ffcc1a7f503fd2ccb3f67..0be7180be80ed8ae3dbe61b762d0e53c46ad0536 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ PHP                                                                        NEWS
   . libpq (PostgreSQL) to version 8.2.3
   . libmysql (MySQL) to version 5.0.37
   . openssl to version 0.9.8e
-- Upgraded SQLite 3 to version 3.3.13 (Ilia)
+- Upgraded SQLite 3 to version 3.3.15 (Ilia)
 - Upgraded PCRE to version 7.0 (Nuno)
 - Updated timezone database to version 2007.3. (Derick)
 - Improved FastCGI SAPI to support external pipe and socket servers on win32.
index 6c165c2846c7a7e9e680f98ec22b0708255043a2..a9c846e62f91dddce56b9ec17c31e676d07d39f3 100644 (file)
@@ -1 +1 @@
-3.3.13
+3.3.15
index dc1f33286d029e0b04be2cc5fb5376fc6ec3593f..602aa2933fdc9357b77e5f4b96965566d34d2a1c 100644 (file)
@@ -211,7 +211,7 @@ static void analyzeOneTable(
       }
     }
     sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0);
-    sqlite3VdbeAddOp(v, OP_Insert, iStatCur, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, iStatCur, OPFLAG_APPEND);
     sqlite3VdbeJumpHere(v, addr);
   }
 }
index 10abc490141b7e9d877bdc410e6a0b18e3314f86..41eb949d5f940cc3fa52d9a4fbcc7a6ba2601217 100644 (file)
@@ -15,6 +15,7 @@
 */
 #include "sqliteInt.h"
 
+#ifndef SQLITE_OMIT_ATTACH
 /*
 ** Resolve an expression that was part of an ATTACH or DETACH statement. This
 ** is slightly different from resolving a normal SQL expression, because simple
@@ -133,13 +134,14 @@ static void attachFunc(
         "attached databases must use the same text encoding as main database");
       goto attach_error;
     }
+    sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode);
   }
   aNew->zName = sqliteStrDup(zName);
   aNew->safety_level = 3;
 
 #if SQLITE_HAS_CODEC
   {
-    extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
+    extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
     extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
     int nKey;
     char *zKey;
@@ -188,7 +190,7 @@ static void attachFunc(
     sqlite3ResetInternalSchema(db, 0);
     db->nDb = iDb;
     if( rc==SQLITE_NOMEM ){
-      if( !sqlite3MallocFailed() ) sqlite3FailedMalloc();
+      sqlite3FailedMalloc();
       sqlite3_snprintf(sizeof(zErr),zErr, "out of memory");
     }else{
       sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile);
@@ -350,14 +352,17 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){
 void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
   codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);
 }
+#endif /* SQLITE_OMIT_ATTACH */
 
 /*
 ** Register the functions sqlite_attach and sqlite_detach.
 */
 void sqlite3AttachFunctions(sqlite3 *db){
+#ifndef SQLITE_OMIT_ATTACH
   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);
+#endif
 }
 
 /*
index d3a6694fe72302ba12323014472b22df5120e2ee..c1d9844f5b7a46f327d9a5da88b0687aca5bddb5 100644 (file)
 ** entries and N+1 pointers to subpages.
 **
 **   ----------------------------------------------------------------
-**   |  Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N) | Ptr(N+1) |
+**   |  Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
 **   ----------------------------------------------------------------
 **
 ** All of the keys on the page that Ptr(0) points to have values less
 ** than Key(0).  All of the keys on page Ptr(1) and its subpages have
 ** values greater than Key(0) and less than Key(1).  All of the keys
-** on Ptr(N+1) and its subpages have values greater than Key(N).  And
+** on Ptr(N) and its subpages have values greater than Key(N-1).  And
 ** so forth.
 **
 ** Finding a particular key requires reading O(log(M)) pages from the 
@@ -41,7 +41,7 @@
 ** page.  If the payload is larger than the preset amount then surplus
 ** bytes are stored on overflow pages.  The payload for an entry
 ** and the preceding pointer are combined to form a "Cell".  Each 
-** page has a small header which contains the Ptr(N+1) pointer and other
+** page has a small header which contains the Ptr(N) pointer and other
 ** information such as the size of key and data.
 **
 ** FORMAT DETAILS
 **      3       2      number of cells on this page
 **      5       2      first byte of the cell content area
 **      7       1      number of fragmented free bytes
-**      8       4      Right child (the Ptr(N+1) value).  Omitted on leaves.
+**      8       4      Right child (the Ptr(N) value).  Omitted on leaves.
 **
 ** The flags define the format of this btree page.  The leaf flag means that
 ** this page has no children.  The zerodata flag means that this page carries
@@ -291,6 +291,7 @@ struct MemPage {
   } aOvfl[5];
   BtShared *pBt;       /* Pointer back to BTree structure */
   u8 *aData;           /* Pointer back to the start of the page */
+  DbPage *pDbPage;     /* Pager page handle */
   Pgno pgno;           /* Page number for this page */
   MemPage *pParent;    /* The parent of this page.  NULL for root */
 };
@@ -365,6 +366,7 @@ struct CellInfo {
   u8 *pCell;     /* Pointer to the start of cell content */
   i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
   u32 nData;     /* Number of bytes of data */
+  u32 nPayload;  /* Total amount of payload */
   u16 nHeader;   /* Size of the cell content header in bytes */
   u16 nLocal;    /* Amount of payload held locally */
   u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
@@ -710,6 +712,15 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
   return SQLITE_OK;
 }
 
+/*
+** Clear the current cursor position.
+*/
+static void clearCursorPosition(BtCursor *pCur){
+  sqliteFree(pCur->pKey);
+  pCur->pKey = 0;
+  pCur->eState = CURSOR_INVALID;
+}
+
 /*
 ** 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 
@@ -721,23 +732,21 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
 ** 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;
+static int restoreOrClearCursorPositionX(BtCursor *pCur){
+  int rc;
   assert( pCur->eState==CURSOR_REQUIRESEEK );
   pCur->eState = CURSOR_INVALID;
-  if( doSeek ){
-    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
-  }
+  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
   if( rc==SQLITE_OK ){
     sqliteFree(pCur->pKey);
     pCur->pKey = 0;
-    assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
+    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
   }
   return rc;
 }
 
-#define restoreOrClearCursorPosition(p,x) \
-  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
+#define restoreOrClearCursorPosition(p) \
+  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p):SQLITE_OK)
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
@@ -814,9 +823,10 @@ static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
 ** An error code is returned if something goes wrong, otherwise SQLITE_OK.
 */
 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 */
+  DbPage *pDbPage;  /* The pointer map page */
+  u8 *pPtrmap;      /* The pointer map data */
+  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 */
@@ -827,22 +837,23 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
     return SQLITE_CORRUPT_BKPT;
   }
   iPtrmap = PTRMAP_PAGENO(pBt, key);
-  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
+  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
   if( rc!=SQLITE_OK ){
     return rc;
   }
   offset = PTRMAP_PTROFFSET(pBt, key);
+  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
 
   if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
     TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
-    rc = sqlite3pager_write(pPtrmap);
+    rc = sqlite3PagerWrite(pDbPage);
     if( rc==SQLITE_OK ){
       pPtrmap[offset] = eType;
       put4byte(&pPtrmap[offset+1], parent);
     }
   }
 
-  sqlite3pager_unref(pPtrmap);
+  sqlite3PagerUnref(pDbPage);
   return rc;
 }
 
@@ -854,23 +865,25 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
 ** An error code is returned if something goes wrong, otherwise SQLITE_OK.
 */
 static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
+  DbPage *pDbPage;   /* The pointer map page */
   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, key);
-  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
+  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
   if( rc!=0 ){
     return rc;
   }
+  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
 
   offset = PTRMAP_PTROFFSET(pBt, key);
   assert( pEType!=0 );
   *pEType = pPtrmap[offset];
   if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
 
-  sqlite3pager_unref(pPtrmap);
+  sqlite3PagerUnref(pDbPage);
   if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
   return SQLITE_OK;
 }
@@ -944,6 +957,7 @@ static void parseCellPtr(
     pInfo->nKey = x;
     nPayload += x;
   }
+  pInfo->nPayload = nPayload;
   pInfo->nHeader = n;
   if( nPayload<=pPage->maxLocal ){
     /* This is the (easy) common case where the entire payload fits
@@ -1020,6 +1034,7 @@ static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
   if( pCell ){
     CellInfo info;
     parseCellPtr(pPage, pCell, &info);
+    assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
     if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
       Pgno ovfl = get4byte(&pCell[info.iOverflow]);
       return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
@@ -1068,7 +1083,7 @@ static int defragmentPage(MemPage *pPage){
   unsigned char *data;       /* The page data */
   unsigned char *temp;       /* Temp area for cell content */
 
-  assert( sqlite3pager_iswriteable(pPage->aData) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( pPage->pBt!=0 );
   assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
   assert( pPage->nOverflow==0 );
@@ -1126,7 +1141,7 @@ static int allocateSpace(MemPage *pPage, int nByte){
   unsigned char *data;
   
   data = pPage->aData;
-  assert( sqlite3pager_iswriteable(data) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( pPage->pBt );
   if( nByte<4 ) nByte = 4;
   if( pPage->nFree<nByte || pPage->nOverflow>0 ) return 0;
@@ -1183,7 +1198,7 @@ static void freeSpace(MemPage *pPage, int start, int size){
   unsigned char *data = pPage->aData;
 
   assert( pPage->pBt!=0 );
-  assert( sqlite3pager_iswriteable(data) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
   assert( (start + size)<=pPage->pBt->usableSize );
   if( size<4 ) size = 4;
@@ -1292,7 +1307,7 @@ static int initPage(
   pBt = pPage->pBt;
   assert( pBt!=0 );
   assert( pParent==0 || pParent->pBt==pBt );
-  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
+  assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
   assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] );
   if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
     /* The parent page should never change unless the file is corrupt */
@@ -1301,7 +1316,7 @@ static int initPage(
   if( pPage->isInit ) return SQLITE_OK;
   if( pPage->pParent==0 && pParent!=0 ){
     pPage->pParent = pParent;
-    sqlite3pager_ref(pParent->aData);
+    sqlite3PagerRef(pParent->pDbPage);
   }
   hdr = pPage->hdrOffset;
   data = pPage->aData;
@@ -1359,9 +1374,9 @@ static void zeroPage(MemPage *pPage, int flags){
   int hdr = pPage->hdrOffset;
   int first;
 
-  assert( sqlite3pager_pagenumber(data)==pPage->pgno );
+  assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
   assert( &data[pBt->pageSize] == (unsigned char*)pPage );
-  assert( sqlite3pager_iswriteable(data) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   memset(&data[hdr], 0, pBt->usableSize - hdr);
   data[hdr] = flags;
   first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
@@ -1382,18 +1397,23 @@ static void zeroPage(MemPage *pPage, int flags){
 ** Get a page from the pager.  Initialize the MemPage.pBt and
 ** MemPage.aData elements if needed.
 */
-static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage){
+static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage, int clrFlag){
   int rc;
-  unsigned char *aData;
   MemPage *pPage;
-  rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData);
+  DbPage *pDbPage;
+
+  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, clrFlag);
   if( rc ) return rc;
-  pPage = (MemPage*)&aData[pBt->pageSize];
-  pPage->aData = aData;
+  pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage);
+  pPage->aData = sqlite3PagerGetData(pDbPage);
+  pPage->pDbPage = pDbPage;
   pPage->pBt = pBt;
   pPage->pgno = pgno;
   pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
   *ppPage = pPage;
+  if( clrFlag ){
+    sqlite3PagerDontRollback(pPage->pDbPage);
+  }
   return SQLITE_OK;
 }
 
@@ -1412,7 +1432,7 @@ static int getAndInitPage(
   if( pgno==0 ){
     return SQLITE_CORRUPT_BKPT; 
   }
-  rc = getPage(pBt, pgno, ppPage);
+  rc = getPage(pBt, pgno, ppPage, 0);
   if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
     rc = initPage(*ppPage, pParent);
   }
@@ -1428,7 +1448,7 @@ static void releasePage(MemPage *pPage){
     assert( pPage->aData );
     assert( pPage->pBt );
     assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage );
-    sqlite3pager_unref(pPage->aData);
+    sqlite3PagerUnref(pPage->pDbPage);
   }
 }
 
@@ -1437,10 +1457,10 @@ static void releasePage(MemPage *pPage){
 ** reaches zero.  We need to unref the pParent pointer when that
 ** happens.
 */
-static void pageDestructor(void *pData, int pageSize){
+static void pageDestructor(DbPage *pData, int pageSize){
   MemPage *pPage;
   assert( (pageSize & 7)==0 );
-  pPage = (MemPage*)&((char*)pData)[pageSize];
+  pPage = (MemPage *)sqlite3PagerGetExtra(pData);
   if( pPage->pParent ){
     MemPage *pParent = pPage->pParent;
     pPage->pParent = 0;
@@ -1457,10 +1477,10 @@ static void pageDestructor(void *pData, int pageSize){
 ** This routine needs to reset the extra data section at the end of the
 ** page to agree with the restored data.
 */
-static void pageReinit(void *pData, int pageSize){
+static void pageReinit(DbPage *pData, int pageSize){
   MemPage *pPage;
   assert( (pageSize & 7)==0 );
-  pPage = (MemPage*)&((char*)pData)[pageSize];
+  pPage = (MemPage *)sqlite3PagerGetExtra(pData);
   if( pPage->isInit ){
     pPage->isInit = 0;
     initPage(pPage, pPage->pParent);
@@ -1520,7 +1540,7 @@ int sqlite3BtreeOpen(
     }
     for(pBt=pTsdro->pBtree; pBt; pBt=pBt->pNext){
       assert( pBt->nRef>0 );
-      if( 0==strcmp(zFullPathname, sqlite3pager_filename(pBt->pPager)) ){
+      if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) ){
         p->pBt = pBt;
         *ppBtree = p;
         pBt->nRef++;
@@ -1549,13 +1569,13 @@ int sqlite3BtreeOpen(
     sqliteFree(p);
     return SQLITE_NOMEM;
   }
-  rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
+  rc = sqlite3PagerOpen(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
   if( rc==SQLITE_OK ){
-    rc = sqlite3pager_read_fileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
+    rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
   }
   if( rc!=SQLITE_OK ){
     if( pBt->pPager ){
-      sqlite3pager_close(pBt->pPager);
+      sqlite3PagerClose(pBt->pPager);
     }
     sqliteFree(pBt);
     sqliteFree(p);
@@ -1564,11 +1584,11 @@ int sqlite3BtreeOpen(
   }
   p->pBt = pBt;
 
-  sqlite3pager_set_destructor(pBt->pPager, pageDestructor);
-  sqlite3pager_set_reiniter(pBt->pPager, pageReinit);
+  sqlite3PagerSetDestructor(pBt->pPager, pageDestructor);
+  sqlite3PagerSetReiniter(pBt->pPager, pageReinit);
   pBt->pCursor = 0;
   pBt->pPage1 = 0;
-  pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
+  pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
   pBt->pageSize = get2byte(&zDbHeader[16]);
   if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
        || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
@@ -1600,7 +1620,7 @@ int sqlite3BtreeOpen(
   }
   pBt->usableSize = pBt->pageSize - nReserve;
   assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
-  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
+  sqlite3PagerSetPagesize(pBt->pPager, pBt->pageSize);
 
 #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
   /* Add the new btree to the linked list starting at ThreadData.pBtree.
@@ -1677,7 +1697,7 @@ int sqlite3BtreeClose(Btree *p){
 
   /* Close the pager and free the shared-btree structure */
   assert( !pBt->pCursor );
-  sqlite3pager_close(pBt->pPager);
+  sqlite3PagerClose(pBt->pPager);
   if( pBt->xFreeSchema && pBt->pSchema ){
     pBt->xFreeSchema(pBt->pSchema);
   }
@@ -1692,7 +1712,7 @@ int sqlite3BtreeClose(Btree *p){
 int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
   BtShared *pBt = p->pBt;
   pBt->pBusyHandler = pHandler;
-  sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
+  sqlite3PagerSetBusyhandler(pBt->pPager, pHandler);
   return SQLITE_OK;
 }
 
@@ -1713,7 +1733,7 @@ int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
 */
 int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
   BtShared *pBt = p->pBt;
-  sqlite3pager_set_cachesize(pBt->pPager, mxPage);
+  sqlite3PagerSetCachesize(pBt->pPager, mxPage);
   return SQLITE_OK;
 }
 
@@ -1728,7 +1748,7 @@ int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
 int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
   BtShared *pBt = p->pBt;
-  sqlite3pager_set_safety_level(pBt->pPager, level, fullSync);
+  sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
   return SQLITE_OK;
 }
 #endif
@@ -1740,7 +1760,7 @@ int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
 int sqlite3BtreeSyncDisabled(Btree *p){
   BtShared *pBt = p->pBt;
   assert( pBt && pBt->pPager );
-  return sqlite3pager_nosync(pBt->pPager);
+  return sqlite3PagerNosync(pBt->pPager);
 }
 
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
@@ -1771,7 +1791,7 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){
         ((pageSize-1)&pageSize)==0 ){
     assert( (pageSize & 7)==0 );
     assert( !pBt->pPage1 && !pBt->pCursor );
-    pBt->pageSize = sqlite3pager_set_pagesize(pBt->pPager, pageSize);
+    pBt->pageSize = sqlite3PagerSetPagesize(pBt->pPager, pageSize);
   }
   pBt->usableSize = pBt->pageSize - nReserve;
   return SQLITE_OK;
@@ -1827,14 +1847,13 @@ int sqlite3BtreeGetAutoVacuum(Btree *p){
 ** SQLITE_OK is returned on success.  If the file is not a
 ** well-formed database file, then SQLITE_CORRUPT is returned.
 ** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM
-** is returned if we run out of memory.  SQLITE_PROTOCOL is returned
-** if there is a locking protocol violation.
+** is returned if we run out of memory. 
 */
 static int lockBtree(BtShared *pBt){
   int rc, pageSize;
   MemPage *pPage1;
   if( pBt->pPage1 ) return SQLITE_OK;
-  rc = getPage(pBt, 1, &pPage1);
+  rc = getPage(pBt, 1, &pPage1, 0);
   if( rc!=SQLITE_OK ) return rc;
   
 
@@ -1842,7 +1861,7 @@ static int lockBtree(BtShared *pBt){
   ** a valid database file. 
   */
   rc = SQLITE_NOTADB;
-  if( sqlite3pager_pagecount(pBt->pPager)>0 ){
+  if( sqlite3PagerPagecount(pBt->pPager)>0 ){
     u8 *page1 = pPage1->aData;
     if( memcmp(page1, zMagicHeader, 16)!=0 ){
       goto page1_init_failed;
@@ -1851,7 +1870,7 @@ static int lockBtree(BtShared *pBt){
       goto page1_init_failed;
     }
     pageSize = get2byte(&page1[16]);
-    if( ((pageSize-1)&pageSize)!=0 ){
+    if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ){
       goto page1_init_failed;
     }
     assert( (pageSize & 7)==0 );
@@ -1931,7 +1950,7 @@ static int lockBtreeWithRetry(Btree *pRef){
 */
 static void unlockBtreeIfUnused(BtShared *pBt){
   if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
-    if( sqlite3pager_refcount(pBt->pPager)>=1 ){
+    if( sqlite3PagerRefcount(pBt->pPager)>=1 ){
       if( pBt->pPage1->aData==0 ){
         MemPage *pPage = pBt->pPage1;
         pPage->aData = &((u8*)pPage)[-pBt->pageSize];
@@ -1953,11 +1972,11 @@ static int newDatabase(BtShared *pBt){
   MemPage *pP1;
   unsigned char *data;
   int rc;
-  if( sqlite3pager_pagecount(pBt->pPager)>0 ) return SQLITE_OK;
+  if( sqlite3PagerPagecount(pBt->pPager)>0 ) return SQLITE_OK;
   pP1 = pBt->pPage1;
   assert( pP1!=0 );
   data = pP1->aData;
-  rc = sqlite3pager_write(data);
+  rc = sqlite3PagerWrite(pP1->pDbPage);
   if( rc ) return rc;
   memcpy(data, zMagicHeader, sizeof(zMagicHeader));
   assert( sizeof(zMagicHeader)==16 );
@@ -2047,7 +2066,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
     }
   
     if( rc==SQLITE_OK && wrflag ){
-      rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1);
+      rc = sqlite3PagerBegin(pBt->pPage1->pDbPage, wrflag>1);
       if( rc==SQLITE_OK ){
         rc = newDatabase(pBt);
       }
@@ -2203,7 +2222,7 @@ static int relocatePage(
   /* Move page iDbPage from it's current location to page number iFreePage */
   TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", 
       iDbPage, iFreePage, iPtrPage, eType));
-  rc = sqlite3pager_movepage(pPager, pDbPage->aData, iFreePage);
+  rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage);
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -2237,11 +2256,11 @@ static int relocatePage(
   ** iPtrPage.
   */
   if( eType!=PTRMAP_ROOTPAGE ){
-    rc = getPage(pBt, iPtrPage, &pPtrPage);
+    rc = getPage(pBt, iPtrPage, &pPtrPage, 0);
     if( rc!=SQLITE_OK ){
       return rc;
     }
-    rc = sqlite3pager_write(pPtrPage->aData);
+    rc = sqlite3PagerWrite(pPtrPage->pDbPage);
     if( rc!=SQLITE_OK ){
       releasePage(pPtrPage);
       return rc;
@@ -2256,13 +2275,18 @@ static int relocatePage(
 }
 
 /* Forward declaration required by autoVacuumCommit(). */
-static int allocatePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
+static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
 
 /*
-** This routine is called prior to sqlite3pager_commit when a transaction
+** This routine is called prior to sqlite3PagerCommit when a transaction
 ** is commited for an auto-vacuum database.
+**
+** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
+** the database file should be truncated to during the commit process. 
+** i.e. the database has been reorganized so that only the first *pnTrunc
+** pages are in use.
 */
-static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
+static int autoVacuumCommit(BtShared *pBt, Pgno *pnTrunc){
   Pager *pPager = pBt->pPager;
   Pgno nFreeList;            /* Number of pages remaining on the free-list. */
   int nPtrMap;               /* Number of pointer-map pages deallocated */
@@ -2278,11 +2302,11 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
   MemPage *pFreeMemPage = 0; /* "" */
 
 #ifndef NDEBUG
-  int nRef = sqlite3pager_refcount(pPager);
+  int nRef = sqlite3PagerRefcount(pPager);
 #endif
 
   assert( pBt->autoVacuum );
-  if( PTRMAP_ISPAGE(pBt, sqlite3pager_pagecount(pPager)) ){
+  if( PTRMAP_ISPAGE(pBt, sqlite3PagerPagecount(pPager)) ){
     return SQLITE_CORRUPT_BKPT;
   }
 
@@ -2291,7 +2315,7 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
   */
   nFreeList = get4byte(&pBt->pPage1->aData[36]);
   if( nFreeList==0 ){
-    *nTrunc = 0;
+    *pnTrunc = 0;
     return SQLITE_OK;
   }
 
@@ -2304,7 +2328,7 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
   ** be required, less 1 if the pending-byte page was part of the database
   ** but is not after the truncation.
   **/
-  origSize = sqlite3pager_pagecount(pPager);
+  origSize = sqlite3PagerPagecount(pPager);
   if( origSize==PENDING_BYTE_PAGE(pBt) ){
     origSize--;
   }
@@ -2341,19 +2365,19 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
     if( eType==PTRMAP_FREEPAGE ){
       continue;
     }
-    rc = getPage(pBt, iDbPage, &pDbMemPage);
+    rc = getPage(pBt, iDbPage, &pDbMemPage, 0);
     if( rc!=SQLITE_OK ) goto autovacuum_out;
 
     /* Find the next page in the free-list that is not already at the end 
     ** of the file. A page can be pulled off the free list using the 
-    ** allocatePage() routine.
+    ** allocateBtreePage() routine.
     */
     do{
       if( pFreeMemPage ){
         releasePage(pFreeMemPage);
         pFreeMemPage = 0;
       }
-      rc = allocatePage(pBt, &pFreeMemPage, &iFreePage, 0, 0);
+      rc = allocateBtreePage(pBt, &pFreeMemPage, &iFreePage, 0, 0);
       if( rc!=SQLITE_OK ){
         releasePage(pDbMemPage);
         goto autovacuum_out;
@@ -2378,29 +2402,81 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
   ** truncate the database file to finSize pages and consider the
   ** free-list empty.
   */
-  rc = sqlite3pager_write(pBt->pPage1->aData);
+  rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
   if( rc!=SQLITE_OK ) goto autovacuum_out;
   put4byte(&pBt->pPage1->aData[32], 0);
   put4byte(&pBt->pPage1->aData[36], 0);
-  *nTrunc = finSize;
+  *pnTrunc = finSize;
   assert( finSize!=PENDING_BYTE_PAGE(pBt) );
 
 autovacuum_out:
-  assert( nRef==sqlite3pager_refcount(pPager) );
+  assert( nRef==sqlite3PagerRefcount(pPager) );
   if( rc!=SQLITE_OK ){
-    sqlite3pager_rollback(pPager);
+    sqlite3PagerRollback(pPager);
   }
   return rc;
 }
 #endif
 
+/*
+** This routine does the first phase of a two-phase commit.  This routine
+** causes a rollback journal to be created (if it does not already exist)
+** and populated with enough information so that if a power loss occurs
+** the database can be restored to its original state by playing back
+** the journal.  Then the contents of the journal are flushed out to
+** the disk.  After the journal is safely on oxide, the changes to the
+** database are written into the database file and flushed to oxide.
+** At the end of this call, the rollback journal still exists on the
+** disk and we are still holding all locks, so the transaction has not
+** committed.  See sqlite3BtreeCommit() for the second phase of the
+** commit process.
+**
+** This call is a no-op if no write-transaction is currently active on pBt.
+**
+** Otherwise, sync the database file for the btree pBt. zMaster points to
+** the name of a master journal file that should be written into the
+** individual journal file, or is NULL, indicating no master journal file 
+** (single database transaction).
+**
+** When this is called, the master journal should already have been
+** created, populated with this journal pointer and synced to disk.
+**
+** 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 sqlite3BtreeCommitPhaseOne(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
+    if( pBt->autoVacuum ){
+      rc = autoVacuumCommit(pBt, &nTrunc); 
+      if( rc!=SQLITE_OK ){
+        return rc;
+      }
+    }
+#endif
+    rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, nTrunc);
+  }
+  return rc;
+}
+
 /*
 ** Commit the transaction currently in progress.
 **
+** This routine implements the second phase of a 2-phase commit.  The
+** sqlite3BtreeSync() routine does the first phase and should be invoked
+** prior to calling this routine.  The sqlite3BtreeSync() routine did
+** all the work of writing information out to disk and flushing the
+** contents so that they are written onto the disk platter.  All this
+** routine has to do is delete or truncate the rollback journal
+** (which causes the transaction to commit) and drop locks.
+**
 ** 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 *p){
+int sqlite3BtreeCommitPhaseTwo(Btree *p){
   BtShared *pBt = p->pBt;
 
   btreeIntegrity(p);
@@ -2412,7 +2488,7 @@ int sqlite3BtreeCommit(Btree *p){
     int rc;
     assert( pBt->inTransaction==TRANS_WRITE );
     assert( pBt->nTransaction>0 );
-    rc = sqlite3pager_commit(pBt->pPager);
+    rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
     if( rc!=SQLITE_OK ){
       return rc;
     }
@@ -2443,6 +2519,18 @@ int sqlite3BtreeCommit(Btree *p){
   return SQLITE_OK;
 }
 
+/*
+** Do both phases of a commit.
+*/
+int sqlite3BtreeCommit(Btree *p){
+  int rc;
+  rc = sqlite3BtreeCommitPhaseOne(p, 0);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3BtreeCommitPhaseTwo(p);
+  }
+  return rc;
+}
+
 #ifndef NDEBUG
 /*
 ** Return the number of write-cursors open on this handle. This is for use
@@ -2517,7 +2605,7 @@ int sqlite3BtreeRollback(Btree *p){
     int rc2;
 
     assert( TRANS_WRITE==pBt->inTransaction );
-    rc2 = sqlite3pager_rollback(pBt->pPager);
+    rc2 = sqlite3PagerRollback(pBt->pPager);
     if( rc2!=SQLITE_OK ){
       rc = rc2;
     }
@@ -2525,7 +2613,7 @@ int sqlite3BtreeRollback(Btree *p){
     /* The rollback may have destroyed the pPage1->aData value.  So
     ** call getPage() on page 1 again to make sure pPage1->aData is
     ** set correctly. */
-    if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
+    if( getPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
       releasePage(pPage1);
     }
     assert( countWriteCursors(pBt)==0 );
@@ -2570,7 +2658,7 @@ int sqlite3BtreeBeginStmt(Btree *p){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
   assert( pBt->inTransaction==TRANS_WRITE );
-  rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_stmt_begin(pBt->pPager);
+  rc = pBt->readOnly ? SQLITE_OK : sqlite3PagerStmtBegin(pBt->pPager);
   pBt->inStmt = 1;
   return rc;
 }
@@ -2584,7 +2672,7 @@ int sqlite3BtreeCommitStmt(Btree *p){
   int rc;
   BtShared *pBt = p->pBt;
   if( pBt->inStmt && !pBt->readOnly ){
-    rc = sqlite3pager_stmt_commit(pBt->pPager);
+    rc = sqlite3PagerStmtCommit(pBt->pPager);
   }else{
     rc = SQLITE_OK;
   }
@@ -2605,7 +2693,7 @@ int sqlite3BtreeRollbackStmt(Btree *p){
   BtShared *pBt = p->pBt;
   sqlite3MallocDisallow();
   if( pBt->inStmt && !pBt->readOnly ){
-    rc = sqlite3pager_stmt_rollback(pBt->pPager);
+    rc = sqlite3PagerStmtRollback(pBt->pPager);
     assert( countWriteCursors(pBt)==0 );
     pBt->inStmt = 0;
   }
@@ -2643,25 +2731,16 @@ static int dfltCompare(
 **
 ** 1:  The cursor must have been opened with wrFlag==1
 **
-** 2:  No other cursors may be open with wrFlag==0 on the same table
+** 2:  Other database connections that share the same pager cache
+**     but which are not in the READ_UNCOMMITTED state may not have
+**     cursors open with wrFlag==0 on the same table.  Otherwise
+**     the changes made by this write cursor would be visible to
+**     the read cursors in the other database connection.
 **
 ** 3:  The database must be writable (not on read-only media)
 **
 ** 4:  There must be an active transaction.
 **
-** Condition 2 warrants further discussion.  If any cursor is opened
-** on a table with wrFlag==0, that prevents all other cursors from
-** writing to that table.  This is a kind of "read-lock".  When a cursor
-** is opened with wrFlag==0 it is guaranteed that the table will not
-** change as long as the cursor is open.  This allows the cursor to
-** do a sequential scan of the table without having to worry about
-** entries being inserted or deleted during the scan.  Cursors should
-** be opened with wrFlag==0 only if this read-lock property is needed.
-** That is to say, cursors should be opened with wrFlag==0 only if they
-** intend to use the sqlite3BtreeNext() system call.  All other cursors
-** should be opened with wrFlag==1 even if they never really intend
-** to write.
-** 
 ** No checking is done to make sure that page iTable really is the
 ** root page of a b-tree.  If it is not, then the cursor acquired
 ** will not work correctly.
@@ -2706,7 +2785,7 @@ int sqlite3BtreeCursor(
     goto create_cursor_exception;
   }
   pCur->pgnoRoot = (Pgno)iTable;
-  if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){
+  if( iTable==1 && sqlite3PagerPagecount(pBt->pPager)==0 ){
     rc = SQLITE_EMPTY;
     goto create_cursor_exception;
   }
@@ -2761,7 +2840,7 @@ void sqlite3BtreeSetCompare(
 */
 int sqlite3BtreeCloseCursor(BtCursor *pCur){
   BtShared *pBt = pCur->pBtree->pBt;
-  restoreOrClearCursorPosition(pCur, 0);
+  clearCursorPosition(pCur);
   if( pCur->pPrev ){
     pCur->pPrev->pNext = pCur->pNext;
   }else{
@@ -2785,7 +2864,7 @@ static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
   pTempCur->pNext = 0;
   pTempCur->pPrev = 0;
   if( pTempCur->pPage ){
-    sqlite3pager_ref(pTempCur->pPage->aData);
+    sqlite3PagerRef(pTempCur->pPage->pDbPage);
   }
 }
 
@@ -2795,7 +2874,7 @@ static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
 */
 static void releaseTempCursor(BtCursor *pCur){
   if( pCur->pPage ){
-    sqlite3pager_unref(pCur->pPage->aData);
+    sqlite3PagerUnref(pCur->pPage->pDbPage);
   }
 }
 
@@ -2828,7 +2907,7 @@ static void getCellInfo(BtCursor *pCur){
 ** itself, not the number of bytes in the key.
 */
 int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
     if( pCur->eState==CURSOR_INVALID ){
@@ -2849,7 +2928,7 @@ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
 ** the database is empty) then *pSize is set to 0.
 */
 int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
     if( pCur->eState==CURSOR_INVALID ){
@@ -2925,10 +3004,12 @@ static int getPayload(
   if( amt>0 ){
     nextPage = get4byte(&aPayload[pCur->info.nLocal]);
     while( amt>0 && nextPage ){
-      rc = sqlite3pager_get(pBt->pPager, nextPage, (void**)&aPayload);
+      DbPage *pDbPage;
+      rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
       if( rc!=0 ){
         return rc;
       }
+      aPayload = sqlite3PagerGetData(pDbPage);
       nextPage = get4byte(aPayload);
       if( offset<ovflSize ){
         int a = amt;
@@ -2942,7 +3023,7 @@ static int getPayload(
       }else{
         offset -= ovflSize;
       }
-      sqlite3pager_unref(aPayload);
+      sqlite3PagerUnref(pDbPage);
     }
   }
 
@@ -2962,7 +3043,7 @@ static int getPayload(
 ** the available payload.
 */
 int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_VALID );
     assert( pCur->pPage!=0 );
@@ -2986,7 +3067,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
 ** the available payload.
 */
 int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_VALID );
     assert( pCur->pPage!=0 );
@@ -3139,7 +3220,7 @@ static void moveToParent(BtCursor *pCur){
   pParent = pPage->pParent;
   assert( pParent!=0 );
   idxParent = pPage->idxParent;
-  sqlite3pager_ref(pParent->aData);
+  sqlite3PagerRef(pParent->pDbPage);
   releasePage(pPage);
   pCur->pPage = pParent;
   pCur->info.nSize = 0;
@@ -3155,7 +3236,9 @@ static int moveToRoot(BtCursor *pCur){
   int rc = SQLITE_OK;
   BtShared *pBt = pCur->pBtree->pBt;
 
-  restoreOrClearCursorPosition(pCur, 0);
+  if( pCur->eState==CURSOR_REQUIRESEEK ){
+    clearCursorPosition(pCur);
+  }
   pRoot = pCur->pPage;
   if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
     assert( pRoot->isInit );
@@ -3297,14 +3380,18 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
 **     *pRes>0      The cursor is left pointing at an entry that
 **                  is larger than pKey.
 */
-int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
+int sqlite3BtreeMoveto(
+  BtCursor *pCur,        /* The cursor to be moved */
+  const void *pKey,      /* The key content for indices.  Not used by tables */
+  i64 nKey,              /* Size of pKey.  Or the key for tables */
+  int biasRight,         /* If true, bias the search to the high end */
+  int *pRes              /* Search result flag */
+){
   int rc;
-  int tryRightmost;
   rc = moveToRoot(pCur);
   if( rc ) return rc;
   assert( pCur->pPage );
   assert( pCur->pPage->isInit );
-  tryRightmost = pCur->pPage->intKey;
   if( pCur->eState==CURSOR_INVALID ){
     *pRes = -1;
     assert( pCur->pPage->nCell==0 );
@@ -3320,16 +3407,17 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
     if( !pPage->intKey && pKey==0 ){
       return SQLITE_CORRUPT_BKPT;
     }
-    while( lwr<=upr ){
+    if( biasRight ){
+      pCur->idx = upr;
+    }else{
+      pCur->idx = (upr+lwr)/2;
+    }
+    if( lwr<=upr ) for(;;){
       void *pCellKey;
       i64 nCellKey;
-      pCur->idx = (lwr+upr)/2;
       pCur->info.nSize = 0;
       if( pPage->intKey ){
         u8 *pCell;
-        if( tryRightmost ){
-          pCur->idx = upr;
-        }
         pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
         if( pPage->hasData ){
           u32 dummy;
@@ -3340,7 +3428,6 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
           c = -1;
         }else if( nCellKey>nKey ){
           c = +1;
-          tryRightmost = 0;
         }else{
           c = 0;
         }
@@ -3374,6 +3461,10 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
       }else{
         upr = pCur->idx-1;
       }
+      if( lwr>upr ){
+        break;
+      }
+      pCur->idx = (lwr+upr)/2;
     }
     assert( lwr==upr+1 );
     assert( pPage->isInit );
@@ -3425,10 +3516,18 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   MemPage *pPage;
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
-  rc = restoreOrClearCursorPosition(pCur, 1);
+  rc = restoreOrClearCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }
+#endif 
+  assert( pRes!=0 );
+  pPage = pCur->pPage;
+  if( CURSOR_INVALID==pCur->eState ){
+    *pRes = 1;
+    return SQLITE_OK;
+  }
+#ifndef SQLITE_OMIT_SHARED_CACHE
   if( pCur->skip>0 ){
     pCur->skip = 0;
     *pRes = 0;
@@ -3437,12 +3536,6 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   pCur->skip = 0;
 #endif 
 
-  assert( pRes!=0 );
-  pPage = pCur->pPage;
-  if( CURSOR_INVALID==pCur->eState ){
-    *pRes = 1;
-    return SQLITE_OK;
-  }
   assert( pPage->isInit );
   assert( pCur->idx<pPage->nCell );
 
@@ -3493,10 +3586,16 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
   MemPage *pPage;
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
-  rc = restoreOrClearCursorPosition(pCur, 1);
+  rc = restoreOrClearCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }
+#endif
+  if( CURSOR_INVALID==pCur->eState ){
+    *pRes = 1;
+    return SQLITE_OK;
+  }
+#ifndef SQLITE_OMIT_SHARED_CACHE
   if( pCur->skip<0 ){
     pCur->skip = 0;
     *pRes = 0;
@@ -3505,11 +3604,6 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
   pCur->skip = 0;
 #endif
 
-  if( CURSOR_INVALID==pCur->eState ){
-    *pRes = 1;
-    return SQLITE_OK;
-  }
-
   pPage = pCur->pPage;
   assert( pPage->isInit );
   assert( pCur->idx>=0 );
@@ -3543,14 +3637,14 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
 /*
 ** Allocate a new page from the database file.
 **
-** The new page is marked as dirty.  (In other words, sqlite3pager_write()
+** The new page is marked as dirty.  (In other words, sqlite3PagerWrite()
 ** has already been called on the new page.)  The new page has also
 ** been referenced and the calling routine is responsible for calling
-** sqlite3pager_unref() on the new page when it is done.
+** sqlite3PagerUnref() on the new page when it is done.
 **
 ** SQLITE_OK is returned on success.  Any other return value indicates
 ** an error.  *ppPage and *pPgno are undefined in the event of an error.
-** Do not invoke sqlite3pager_unref() on *ppPage if an error is returned.
+** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
 **
 ** If the "nearby" parameter is not 0, then a (feeble) effort is made to 
 ** locate a page close to the page number "nearby".  This can be used in an
@@ -3561,7 +3655,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
 ** anywhere on the free-list, then it is guarenteed to be returned. This
 ** is only used by auto-vacuum databases when allocating a new table.
 */
-static int allocatePage(
+static int allocateBtreePage(
   BtShared *pBt, 
   MemPage **ppPage, 
   Pgno *pPgno, 
@@ -3603,7 +3697,7 @@ static int allocatePage(
     /* Decrement the free-list count by 1. Set iTrunk to the index of the
     ** first free-list trunk page. iPrevTrunk is initially 1.
     */
-    rc = sqlite3pager_write(pPage1->aData);
+    rc = sqlite3PagerWrite(pPage1->pDbPage);
     if( rc ) return rc;
     put4byte(&pPage1->aData[36], n-1);
 
@@ -3618,7 +3712,7 @@ static int allocatePage(
       }else{
         iTrunk = get4byte(&pPage1->aData[32]);
       }
-      rc = getPage(pBt, iTrunk, &pTrunk);
+      rc = getPage(pBt, iTrunk, &pTrunk, 0);
       if( rc ){
         pTrunk = 0;
         goto end_allocate_page;
@@ -3630,7 +3724,7 @@ static int allocatePage(
         ** So extract the trunk page itself and use it as the newly 
         ** allocated page */
         assert( pPrevTrunk==0 );
-        rc = sqlite3pager_write(pTrunk->aData);
+        rc = sqlite3PagerWrite(pTrunk->pDbPage);
         if( rc ){
           goto end_allocate_page;
         }
@@ -3651,7 +3745,7 @@ static int allocatePage(
         assert( *pPgno==iTrunk );
         *ppPage = pTrunk;
         searchList = 0;
-        rc = sqlite3pager_write(pTrunk->aData);
+        rc = sqlite3PagerWrite(pTrunk->pDbPage);
         if( rc ){
           goto end_allocate_page;
         }
@@ -3668,11 +3762,11 @@ static int allocatePage(
           */
           MemPage *pNewTrunk;
           Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
-          rc = getPage(pBt, iNewTrunk, &pNewTrunk);
+          rc = getPage(pBt, iNewTrunk, &pNewTrunk, 0);
           if( rc!=SQLITE_OK ){
             goto end_allocate_page;
           }
-          rc = sqlite3pager_write(pNewTrunk->aData);
+          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
           if( rc!=SQLITE_OK ){
             releasePage(pNewTrunk);
             goto end_allocate_page;
@@ -3684,7 +3778,7 @@ static int allocatePage(
           if( !pPrevTrunk ){
             put4byte(&pPage1->aData[32], iNewTrunk);
           }else{
-            rc = sqlite3pager_write(pPrevTrunk->aData);
+            rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
             if( rc ){
               goto end_allocate_page;
             }
@@ -3699,7 +3793,7 @@ static int allocatePage(
         int closest;
         Pgno iPage;
         unsigned char *aData = pTrunk->aData;
-        rc = sqlite3pager_write(aData);
+        rc = sqlite3PagerWrite(pTrunk->pDbPage);
         if( rc ){
           goto end_allocate_page;
         }
@@ -3723,7 +3817,7 @@ static int allocatePage(
         iPage = get4byte(&aData[8+closest*4]);
         if( !searchList || iPage==nearby ){
           *pPgno = iPage;
-          if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){
+          if( *pPgno>sqlite3PagerPagecount(pBt->pPager) ){
             /* Free page off the end of the file */
             return SQLITE_CORRUPT_BKPT;
           }
@@ -3734,10 +3828,9 @@ static int allocatePage(
             memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
           }
           put4byte(&aData[4], k-1);
-          rc = getPage(pBt, *pPgno, ppPage);
+          rc = getPage(pBt, *pPgno, ppPage, 1);
           if( rc==SQLITE_OK ){
-            sqlite3pager_dont_rollback((*ppPage)->aData);
-            rc = sqlite3pager_write((*ppPage)->aData);
+            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
             if( rc!=SQLITE_OK ){
               releasePage(*ppPage);
             }
@@ -3751,7 +3844,7 @@ static int allocatePage(
   }else{
     /* There are no pages on the freelist, so create a new page at the
     ** end of the file */
-    *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1;
+    *pPgno = sqlite3PagerPagecount(pBt->pPager) + 1;
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
@@ -3766,9 +3859,9 @@ static int allocatePage(
 #endif
 
     assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
-    rc = getPage(pBt, *pPgno, ppPage);
+    rc = getPage(pBt, *pPgno, ppPage, 0);
     if( rc ) return rc;
-    rc = sqlite3pager_write((*ppPage)->aData);
+    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
     if( rc!=SQLITE_OK ){
       releasePage(*ppPage);
     }
@@ -3786,7 +3879,7 @@ end_allocate_page:
 /*
 ** Add a page of the database file to the freelist.
 **
-** sqlite3pager_unref() is NOT called for pPage.
+** sqlite3PagerUnref() is NOT called for pPage.
 */
 static int freePage(MemPage *pPage){
   BtShared *pBt = pPage->pBt;
@@ -3800,7 +3893,7 @@ static int freePage(MemPage *pPage){
   pPage->pParent = 0;
 
   /* Increment the free page count on pPage1 */
-  rc = sqlite3pager_write(pPage1->aData);
+  rc = sqlite3PagerWrite(pPage1->pDbPage);
   if( rc ) return rc;
   n = get4byte(&pPage1->aData[36]);
   put4byte(&pPage1->aData[36], n+1);
@@ -3809,7 +3902,7 @@ static int freePage(MemPage *pPage){
   /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
   ** always fully overwrite deleted information with zeros.
   */
-  rc = sqlite3pager_write(pPage->aData);
+  rc = sqlite3PagerWrite(pPage->pDbPage);
   if( rc ) return rc;
   memset(pPage->aData, 0, pPage->pBt->pageSize);
 #endif
@@ -3826,7 +3919,7 @@ static int freePage(MemPage *pPage){
 
   if( n==0 ){
     /* This is the first free page */
-    rc = sqlite3pager_write(pPage->aData);
+    rc = sqlite3PagerWrite(pPage->pDbPage);
     if( rc ) return rc;
     memset(pPage->aData, 0, 8);
     put4byte(&pPage1->aData[32], pPage->pgno);
@@ -3835,13 +3928,13 @@ static int freePage(MemPage *pPage){
     /* Other free pages already exist.  Retrive the first trunk page
     ** of the freelist and find out how many leaves it has. */
     MemPage *pTrunk;
-    rc = getPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk);
+    rc = getPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
     if( rc ) return rc;
     k = get4byte(&pTrunk->aData[4]);
     if( k>=pBt->usableSize/4 - 8 ){
       /* The trunk is full.  Turn the page being freed into a new
       ** trunk page with no leaves. */
-      rc = sqlite3pager_write(pPage->aData);
+      rc = sqlite3PagerWrite(pPage->pDbPage);
       if( rc ) return rc;
       put4byte(pPage->aData, pTrunk->pgno);
       put4byte(&pPage->aData[4], 0);
@@ -3850,13 +3943,14 @@ static int freePage(MemPage *pPage){
               pPage->pgno, pTrunk->pgno));
     }else{
       /* Add the newly freed page as a leaf on the current trunk */
-      rc = sqlite3pager_write(pTrunk->aData);
-      if( rc ) return rc;
-      put4byte(&pTrunk->aData[4], k+1);
-      put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
+      rc = sqlite3PagerWrite(pTrunk->pDbPage);
+      if( rc==SQLITE_OK ){
+        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);
+        sqlite3PagerDontWrite(pBt->pPager, pPage->pgno);
 #endif
+      }
       TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
     }
     releasePage(pTrunk);
@@ -3872,22 +3966,29 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
   CellInfo info;
   Pgno ovflPgno;
   int rc;
+  int nOvfl;
+  int ovflPageSize;
 
   parseCellPtr(pPage, pCell, &info);
   if( info.iOverflow==0 ){
     return SQLITE_OK;  /* No overflow pages. Return without doing anything */
   }
   ovflPgno = get4byte(&pCell[info.iOverflow]);
-  while( ovflPgno!=0 ){
+  ovflPageSize = pBt->usableSize - 4;
+  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
+  assert( ovflPgno==0 || nOvfl>0 );
+  while( nOvfl-- ){
     MemPage *pOvfl;
-    if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){
+    if( ovflPgno==0 || ovflPgno>sqlite3PagerPagecount(pBt->pPager) ){
       return SQLITE_CORRUPT_BKPT;
     }
-    rc = getPage(pBt, ovflPgno, &pOvfl);
+    rc = getPage(pBt, ovflPgno, &pOvfl, 0);
     if( rc ) return rc;
-    ovflPgno = get4byte(pOvfl->aData);
+    if( nOvfl ){
+      ovflPgno = get4byte(pOvfl->aData);
+    }
     rc = freePage(pOvfl);
-    sqlite3pager_unref(pOvfl->aData);
+    sqlite3PagerUnref(pOvfl->pDbPage);
     if( rc ) return rc;
   }
   return SQLITE_OK;
@@ -3962,7 +4063,7 @@ static int fillInCell(
 #ifndef SQLITE_OMIT_AUTOVACUUM
       Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
 #endif
-      rc = allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0);
+      rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0);
 #ifndef SQLITE_OMIT_AUTOVACUUM
       /* If the database supports auto-vacuum, and the second or subsequent
       ** overflow page is being allocated, add an entry to the pointer-map
@@ -3975,7 +4076,6 @@ static int fillInCell(
 #endif
       if( rc ){
         releasePage(pToRelease);
-        /* clearCell(pPage, pCell); */
         return rc;
       }
       put4byte(pPrior, pgnoOvfl);
@@ -4012,24 +4112,24 @@ static int fillInCell(
 */
 static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
   MemPage *pThis;
-  unsigned char *aData;
+  DbPage *pDbPage;
 
   assert( pNewParent!=0 );
   if( pgno==0 ) return SQLITE_OK;
   assert( pBt->pPager!=0 );
-  aData = sqlite3pager_lookup(pBt->pPager, pgno);
-  if( aData ){
-    pThis = (MemPage*)&aData[pBt->pageSize];
-    assert( pThis->aData==aData );
+  pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
+  if( pDbPage ){
+    pThis = (MemPage *)sqlite3PagerGetExtra(pDbPage);
     if( pThis->isInit ){
+      assert( pThis->aData==(sqlite3PagerGetData(pDbPage)) );
       if( pThis->pParent!=pNewParent ){
-        if( pThis->pParent ) sqlite3pager_unref(pThis->pParent->aData);
+        if( pThis->pParent ) sqlite3PagerUnref(pThis->pParent->pDbPage);
         pThis->pParent = pNewParent;
-        sqlite3pager_ref(pNewParent->aData);
+        sqlite3PagerRef(pNewParent->pDbPage);
       }
       pThis->idxParent = idx;
     }
-    sqlite3pager_unref(aData);
+    sqlite3PagerUnref(pDbPage);
   }
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
@@ -4090,7 +4190,7 @@ static void dropCell(MemPage *pPage, int idx, int sz){
 
   assert( idx>=0 && idx<pPage->nCell );
   assert( sz==cellSize(pPage, idx) );
-  assert( sqlite3pager_iswriteable(pPage->aData) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   data = pPage->aData;
   ptr = &data[pPage->cellOffset + 2*idx];
   pc = get2byte(ptr);
@@ -4143,7 +4243,7 @@ static int insertCell(
 
   assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
   assert( sz==cellSizePtr(pPage, pCell) );
-  assert( sqlite3pager_iswriteable(pPage->aData) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   if( pPage->nOverflow || sz+2>pPage->nFree ){
     if( pTemp ){
       memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
@@ -4187,6 +4287,7 @@ static int insertCell(
       */
       CellInfo info;
       parseCellPtr(pPage, pCell, &info);
+      assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
       if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
         Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
         int rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno);
@@ -4294,7 +4395,7 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
   /* Allocate a new page. Insert the overflow cell from pPage
   ** into it. Then remove the overflow cell from pPage.
   */
-  rc = allocatePage(pBt, &pNew, &pgnoNew, 0, 0);
+  rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -4306,7 +4407,7 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
 
   /* Set the parent of the newly allocated page to pParent. */
   pNew->pParent = pParent;
-  sqlite3pager_ref(pParent->aData);
+  sqlite3PagerRef(pParent->pDbPage);
 
   /* pPage is currently the right-child of pParent. Change this
   ** so that the right-child is the new page allocated above and
@@ -4431,11 +4532,11 @@ static int balance_nonroot(MemPage *pPage){
   ** Find the parent page.
   */
   assert( pPage->isInit );
-  assert( sqlite3pager_iswriteable(pPage->aData) );
+  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   pBt = pPage->pBt;
   pParent = pPage->pParent;
   assert( pParent );
-  if( SQLITE_OK!=(rc = sqlite3pager_write(pParent->aData)) ){
+  if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
     return rc;
   }
   TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
@@ -4473,7 +4574,7 @@ static int balance_nonroot(MemPage *pPage){
   if( pParent->idxShift ){
     Pgno pgno;
     pgno = pPage->pgno;
-    assert( pgno==sqlite3pager_pagenumber(pPage->aData) );
+    assert( pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
     for(idx=0; idx<pParent->nCell; idx++){
       if( get4byte(findCell(pParent, idx))==pgno ){
         break;
@@ -4490,7 +4591,7 @@ static int balance_nonroot(MemPage *pPage){
   ** directly to balance_cleanup at any moment.
   */
   nOld = nNew = 0;
-  sqlite3pager_ref(pParent->aData);
+  sqlite3PagerRef(pParent->pDbPage);
 
   /*
   ** Find sibling pages to pPage and the cells in pParent that divide
@@ -4734,15 +4835,16 @@ static int balance_nonroot(MemPage *pPage){
       pNew = apNew[i] = apOld[i];
       pgnoNew[i] = pgnoOld[i];
       apOld[i] = 0;
-      rc = sqlite3pager_write(pNew->aData);
+      rc = sqlite3PagerWrite(pNew->pDbPage);
+      nNew++;
       if( rc ) goto balance_cleanup;
     }else{
       assert( i>0 );
-      rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
+      rc = allocateBtreePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
       if( rc ) goto balance_cleanup;
       apNew[i] = pNew;
+      nNew++;
     }
-    nNew++;
     zeroPage(pNew, pageFlags);
   }
 
@@ -4977,8 +5079,8 @@ static int balance_shallower(MemPage *pPage){
     */
     pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
     assert( pgnoChild>0 );
-    assert( pgnoChild<=sqlite3pager_pagecount(pPage->pBt->pPager) );
-    rc = getPage(pPage->pBt, pgnoChild, &pChild);
+    assert( pgnoChild<=sqlite3PagerPagecount(pPage->pBt->pPager) );
+    rc = getPage(pPage->pBt, pgnoChild, &pChild, 0);
     if( rc ) goto end_shallow_balance;
     if( pPage->pgno==1 ){
       rc = initPage(pChild, pPage);
@@ -5059,9 +5161,9 @@ static int balance_deeper(MemPage *pPage){
   assert( pPage->pParent==0 );
   assert( pPage->nOverflow>0 );
   pBt = pPage->pBt;
-  rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
+  rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
   if( rc ) return rc;
-  assert( sqlite3pager_iswriteable(pChild->aData) );
+  assert( sqlite3PagerIswriteable(pChild->pDbPage) );
   usableSize = pBt->usableSize;
   data = pPage->aData;
   hdr = pPage->hdrOffset;
@@ -5172,7 +5274,8 @@ static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
 int sqlite3BtreeInsert(
   BtCursor *pCur,                /* Insert data into the table of this cursor */
   const void *pKey, i64 nKey,    /* The key of the new record */
-  const void *pData, int nData   /* The data of the new record */
+  const void *pData, int nData,  /* The data of the new record */
+  int appendBias                 /* True if this is likely an append */
 ){
   int rc;
   int loc;
@@ -5195,10 +5298,10 @@ int sqlite3BtreeInsert(
   }
 
   /* Save the positions of any other cursors open on this table */
-  restoreOrClearCursorPosition(pCur, 0);
+  clearCursorPosition(pCur);
   if( 
     SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
-    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc))
+    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
   ){
     return rc;
   }
@@ -5210,7 +5313,7 @@ int sqlite3BtreeInsert(
           pCur->pgnoRoot, nKey, nData, pPage->pgno,
           loc==0 ? "overwrite" : "new entry"));
   assert( pPage->isInit );
-  rc = sqlite3pager_write(pPage->aData);
+  rc = sqlite3PagerWrite(pPage->pDbPage);
   if( rc ) return rc;
   newCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
   if( newCell==0 ) return SQLITE_NOMEM;
@@ -5278,13 +5381,13 @@ int sqlite3BtreeDelete(BtCursor *pCur){
 
   /* 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
+  ** open on the same table. Then call sqlite3PagerWrite() on the page
   ** that the entry will be deleted from.
   */
   if( 
-    (rc = restoreOrClearCursorPosition(pCur, 1))!=0 ||
+    (rc = restoreOrClearCursorPosition(pCur))!=0 ||
     (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
-    (rc = sqlite3pager_write(pPage->aData))!=0
+    (rc = sqlite3PagerWrite(pPage->pDbPage))!=0
   ){
     return rc;
   }
@@ -5318,13 +5421,8 @@ int sqlite3BtreeDelete(BtCursor *pCur){
     assert( !pPage->leafData );
     getTempCursor(pCur, &leafCur);
     rc = sqlite3BtreeNext(&leafCur, &notUsed);
-    if( rc!=SQLITE_OK ){
-      if( rc!=SQLITE_NOMEM ){
-        rc = SQLITE_CORRUPT_BKPT; 
-      }
-    }
     if( rc==SQLITE_OK ){
-      rc = sqlite3pager_write(leafCur.pPage->aData);
+      rc = sqlite3PagerWrite(leafCur.pPage->pDbPage);
     }
     if( rc==SQLITE_OK ){
       TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
@@ -5395,7 +5493,7 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
   }
 
 #ifdef SQLITE_OMIT_AUTOVACUUM
-  rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
+  rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
   if( rc ) return rc;
 #else
   if( pBt->autoVacuum ){
@@ -5423,17 +5521,25 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
     ** be moved to the allocated page (unless the allocated page happens
     ** to reside at pgnoRoot).
     */
-    rc = allocatePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
+    rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
     if( rc!=SQLITE_OK ){
       return rc;
     }
 
     if( pgnoMove!=pgnoRoot ){
+      /* pgnoRoot is the page that will be used for the root-page of
+      ** the new table (assuming an error did not occur). But we were
+      ** allocated pgnoMove. If required (i.e. if it was not allocated
+      ** by extending the file), the current page at position pgnoMove
+      ** is already journaled.
+      */
       u8 eType;
       Pgno iPtrPage;
 
       releasePage(pPageMove);
-      rc = getPage(pBt, pgnoRoot, &pRoot);
+
+      /* Move the page currently at pgnoRoot to pgnoMove. */
+      rc = getPage(pBt, pgnoRoot, &pRoot, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
@@ -5444,21 +5550,23 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
       }
       assert( eType!=PTRMAP_ROOTPAGE );
       assert( eType!=PTRMAP_FREEPAGE );
-      rc = sqlite3pager_write(pRoot->aData);
+      rc = sqlite3PagerWrite(pRoot->pDbPage);
       if( rc!=SQLITE_OK ){
         releasePage(pRoot);
         return rc;
       }
       rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
       releasePage(pRoot);
+
+      /* Obtain the page at pgnoRoot */
       if( rc!=SQLITE_OK ){
         return rc;
       }
-      rc = getPage(pBt, pgnoRoot, &pRoot);
+      rc = getPage(pBt, pgnoRoot, &pRoot, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
-      rc = sqlite3pager_write(pRoot->aData);
+      rc = sqlite3PagerWrite(pRoot->pDbPage);
       if( rc!=SQLITE_OK ){
         releasePage(pRoot);
         return rc;
@@ -5480,13 +5588,13 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
     }
 
   }else{
-    rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
+    rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
     if( rc ) return rc;
   }
 #endif
-  assert( sqlite3pager_iswriteable(pRoot->aData) );
+  assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
   zeroPage(pRoot, flags | PTF_LEAF);
-  sqlite3pager_unref(pRoot->aData);
+  sqlite3PagerUnref(pRoot->pDbPage);
   *piTable = (int)pgnoRoot;
   return SQLITE_OK;
 }
@@ -5506,14 +5614,12 @@ static int clearDatabasePage(
   unsigned char *pCell;
   int i;
 
-  if( pgno>sqlite3pager_pagecount(pBt->pPager) ){
+  if( pgno>sqlite3PagerPagecount(pBt->pPager) ){
     return SQLITE_CORRUPT_BKPT;
   }
 
   rc = getAndInitPage(pBt, pgno, &pPage, pParent);
   if( rc ) goto cleardatabasepage_out;
-  rc = sqlite3pager_write(pPage->aData);
-  if( rc ) goto cleardatabasepage_out;
   for(i=0; i<pPage->nCell; i++){
     pCell = findCell(pPage, i);
     if( !pPage->leaf ){
@@ -5529,7 +5635,7 @@ static int clearDatabasePage(
   }
   if( freePageFlag ){
     rc = freePage(pPage);
-  }else{
+  }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
     zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
   }
 
@@ -5605,7 +5711,7 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
     return SQLITE_LOCKED;
   }
 
-  rc = getPage(pBt, (Pgno)iTable, &pPage);
+  rc = getPage(pBt, (Pgno)iTable, &pPage, 0);
   if( rc ) return rc;
   rc = sqlite3BtreeClearTable(p, iTable);
   if( rc ){
@@ -5644,7 +5750,7 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
         */
         MemPage *pMove;
         releasePage(pPage);
-        rc = getPage(pBt, maxRootPgno, &pMove);
+        rc = getPage(pBt, maxRootPgno, &pMove, 0);
         if( rc!=SQLITE_OK ){
           return rc;
         }
@@ -5653,7 +5759,7 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
         if( rc!=SQLITE_OK ){
           return rc;
         }
-        rc = getPage(pBt, maxRootPgno, &pMove);
+        rc = getPage(pBt, maxRootPgno, &pMove, 0);
         if( rc!=SQLITE_OK ){
           return rc;
         }
@@ -5705,6 +5811,7 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
 ** free pages is not visible.  So Cookie[0] is the same as Meta[1].
 */
 int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
+  DbPage *pDbPage;
   int rc;
   unsigned char *pP1;
   BtShared *pBt = p->pBt;
@@ -5720,10 +5827,11 @@ int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
   }
 
   assert( idx>=0 && idx<=15 );
-  rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);
+  rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage);
   if( rc ) return rc;
+  pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage);
   *pMeta = get4byte(&pP1[36 + idx*4]);
-  sqlite3pager_unref(pP1);
+  sqlite3PagerUnref(pDbPage);
 
   /* If autovacuumed is disabled in this build but we are trying to 
   ** access an autovacuumed database, then make the database readonly. 
@@ -5751,7 +5859,7 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
   }
   assert( pBt->pPage1!=0 );
   pP1 = pBt->pPage1->aData;
-  rc = sqlite3pager_write(pP1);
+  rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
   if( rc ) return rc;
   put4byte(&pP1[36 + idx*4], iMeta);
   return SQLITE_OK;
@@ -5787,7 +5895,7 @@ static int btreePageDump(BtShared *pBt, int pgno, int recursive, MemPage *pParen
   char range[20];
   unsigned char payload[20];
 
-  rc = getPage(pBt, (Pgno)pgno, &pPage);
+  rc = getPage(pBt, (Pgno)pgno, &pPage, 0);
   isInit = pPage->isInit;
   if( pPage->isInit==0 ){
     initPage(pPage, pParent);
@@ -5866,7 +5974,7 @@ static int btreePageDump(BtShared *pBt, int pgno, int recursive, MemPage *pParen
     btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
   }
   pPage->isInit = isInit;
-  sqlite3pager_unref(data);
+  sqlite3PagerUnref(pPage->pDbPage);
   fflush(stdout);
   return SQLITE_OK;
 }
@@ -5899,7 +6007,7 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
   MemPage *pPage = pCur->pPage;
   BtCursor tmpCur;
 
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -5910,7 +6018,7 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
     moveToParent(&tmpCur);
   }
   pPage = tmpCur.pPage;
-  aResult[0] = sqlite3pager_pagenumber(pPage->aData);
+  aResult[0] = sqlite3PagerPagenumber(pPage->pDbPage);
   assert( aResult[0]==pPage->pgno );
   aResult[1] = tmpCur.idx;
   aResult[2] = pPage->nCell;
@@ -6071,7 +6179,8 @@ static void checkList(
   int expected = N;
   int iFirst = iPage;
   while( N-- > 0 && pCheck->mxErr ){
-    unsigned char *pOvfl;
+    DbPage *pOvflPage;
+    unsigned char *pOvflData;
     if( iPage<1 ){
       checkAppendMsg(pCheck, zContext,
          "%d of %d pages missing from overflow list starting at %d",
@@ -6079,12 +6188,13 @@ static void checkList(
       break;
     }
     if( checkRef(pCheck, iPage, zContext) ) break;
-    if( sqlite3pager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
+    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
       checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
       break;
     }
+    pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
     if( isFreeList ){
-      int n = get4byte(&pOvfl[4]);
+      int n = get4byte(&pOvflData[4]);
 #ifndef SQLITE_OMIT_AUTOVACUUM
       if( pCheck->pBt->autoVacuum ){
         checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
@@ -6096,7 +6206,7 @@ static void checkList(
         N--;
       }else{
         for(i=0; i<n; i++){
-          Pgno iFreePage = get4byte(&pOvfl[8+i*4]);
+          Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
 #ifndef SQLITE_OMIT_AUTOVACUUM
           if( pCheck->pBt->autoVacuum ){
             checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
@@ -6114,13 +6224,13 @@ static void checkList(
       ** the following page matches iPage.
       */
       if( pCheck->pBt->autoVacuum && N>0 ){
-        i = get4byte(pOvfl);
+        i = get4byte(pOvflData);
         checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
       }
     }
 #endif
-    iPage = get4byte(pOvfl);
-    sqlite3pager_unref(pOvfl);
+    iPage = get4byte(pOvflData);
+    sqlite3PagerUnref(pOvflPage);
   }
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -6168,7 +6278,7 @@ static int checkTreePage(
   usableSize = pBt->usableSize;
   if( iPage==0 ) return 0;
   if( checkRef(pCheck, iPage, zParentContext) ) return 0;
-  if( (rc = getPage(pBt, (Pgno)iPage, &pPage))!=0 ){
+  if( (rc = getPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
     checkAppendMsg(pCheck, zContext,
        "unable to get the page. error code=%d", rc);
     return 0;
@@ -6194,6 +6304,7 @@ static int checkTreePage(
     parseCellPtr(pPage, pCell, &info);
     sz = info.nData;
     if( !pPage->intKey ) sz += info.nKey;
+    assert( sz==info.nPayload );
     if( sz>info.nLocal ){
       int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
       Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
@@ -6309,13 +6420,13 @@ char *sqlite3BtreeIntegrityCheck(
   IntegrityCk sCheck;
   BtShared *pBt = p->pBt;
 
-  nRef = sqlite3pager_refcount(pBt->pPager);
+  nRef = sqlite3PagerRefcount(pBt->pPager);
   if( lockBtreeWithRetry(p)!=SQLITE_OK ){
     return sqliteStrDup("Unable to acquire a read lock on the database");
   }
   sCheck.pBt = pBt;
   sCheck.pPager = pBt->pPager;
-  sCheck.nPage = sqlite3pager_pagecount(sCheck.pPager);
+  sCheck.nPage = sqlite3PagerPagecount(sCheck.pPager);
   sCheck.mxErr = mxErr;
   sCheck.nErr = 0;
   *pnErr = 0;
@@ -6379,10 +6490,10 @@ char *sqlite3BtreeIntegrityCheck(
   /* Make sure this analysis did not leave any unref() pages
   */
   unlockBtreeIfUnused(pBt);
-  if( nRef != sqlite3pager_refcount(pBt->pPager) ){
+  if( nRef != sqlite3PagerRefcount(pBt->pPager) ){
     checkAppendMsg(&sCheck, 0, 
       "Outstanding page count goes from %d to %d during this analysis",
-      nRef, sqlite3pager_refcount(pBt->pPager)
+      nRef, sqlite3PagerRefcount(pBt->pPager)
     );
   }
 
@@ -6399,7 +6510,7 @@ char *sqlite3BtreeIntegrityCheck(
 */
 const char *sqlite3BtreeGetFilename(Btree *p){
   assert( p->pBt->pPager!=0 );
-  return sqlite3pager_filename(p->pBt->pPager);
+  return sqlite3PagerFilename(p->pBt->pPager);
 }
 
 /*
@@ -6407,7 +6518,7 @@ const char *sqlite3BtreeGetFilename(Btree *p){
 */
 const char *sqlite3BtreeGetDirname(Btree *p){
   assert( p->pBt->pPager!=0 );
-  return sqlite3pager_dirname(p->pBt->pPager);
+  return sqlite3PagerDirname(p->pBt->pPager);
 }
 
 /*
@@ -6417,7 +6528,7 @@ const char *sqlite3BtreeGetDirname(Btree *p){
 */
 const char *sqlite3BtreeGetJournalname(Btree *p){
   assert( p->pBt->pPager!=0 );
-  return sqlite3pager_journalname(p->pBt->pPager);
+  return sqlite3PagerJournalname(p->pBt->pPager);
 }
 
 #ifndef SQLITE_OMIT_VACUUM
@@ -6439,28 +6550,28 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
     return SQLITE_ERROR;
   }
   if( pBtTo->pCursor ) return SQLITE_BUSY;
-  nToPage = sqlite3pager_pagecount(pBtTo->pPager);
-  nPage = sqlite3pager_pagecount(pBtFrom->pPager);
+  nToPage = sqlite3PagerPagecount(pBtTo->pPager);
+  nPage = sqlite3PagerPagecount(pBtFrom->pPager);
   iSkip = PENDING_BYTE_PAGE(pBtTo);
   for(i=1; rc==SQLITE_OK && i<=nPage; i++){
-    void *pPage;
+    DbPage *pDbPage;
     if( i==iSkip ) continue;
-    rc = sqlite3pager_get(pBtFrom->pPager, i, &pPage);
+    rc = sqlite3PagerGet(pBtFrom->pPager, i, &pDbPage);
     if( rc ) break;
-    rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage);
-    sqlite3pager_unref(pPage);
+    rc = sqlite3PagerOverwrite(pBtTo->pPager, i, sqlite3PagerGetData(pDbPage));
+    sqlite3PagerUnref(pDbPage);
   }
   for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
-    void *pPage;
+    DbPage *pDbPage;
     if( i==iSkip ) continue;
-    rc = sqlite3pager_get(pBtTo->pPager, i, &pPage);
+    rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage);
     if( rc ) break;
-    rc = sqlite3pager_write(pPage);
-    sqlite3pager_unref(pPage);
-    sqlite3pager_dont_write(pBtTo->pPager, i);
+    rc = sqlite3PagerWrite(pDbPage);
+    sqlite3PagerUnref(pDbPage);
+    sqlite3PagerDontWrite(pBtTo->pPager, i);
   }
   if( !rc && nPage<nToPage ){
-    rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
+    rc = sqlite3PagerTruncate(pBtTo->pPager, nPage);
   }
   if( rc ){
     sqlite3BtreeRollback(pTo);
@@ -6490,38 +6601,6 @@ int sqlite3BtreeIsInReadTrans(Btree *p){
   return (p && (p->inTrans!=TRANS_NONE));
 }
 
-/*
-** This call is a no-op if no write-transaction is currently active on pBt.
-**
-** Otherwise, sync the database file for the btree pBt. zMaster points to
-** the name of a master journal file that should be written into the
-** individual journal file, or is NULL, indicating no master journal file 
-** (single database transaction).
-**
-** When this is called, the master journal should already have been
-** created, populated with this journal pointer and synced to disk.
-**
-** 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 *p, const char *zMaster){
-  int rc = SQLITE_OK;
-  if( p->inTrans==TRANS_WRITE ){
-    BtShared *pBt = p->pBt;
-    Pgno nTrunc = 0;
-#ifndef SQLITE_OMIT_AUTOVACUUM
-    if( pBt->autoVacuum ){
-      rc = autoVacuumCommit(pBt, &nTrunc); 
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
-    }
-#endif
-    rc = sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
-  }
-  return rc;
-}
-
 /*
 ** 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
@@ -6592,7 +6671,7 @@ int sqlite3_shared_cache_report(
     BtShared *pBt;
     Tcl_Obj *pRet = Tcl_NewObj();
     for(pBt=pTd->pBtree; pBt; pBt=pBt->pNext){
-      const char *zFile = sqlite3pager_filename(pBt->pPager);
+      const char *zFile = sqlite3PagerFilename(pBt->pPager);
       Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
       Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
     }
index 2f573e27f858ae6b89871c04f15417262fadddfd..59c9b855b029d27c4c01de5898e62c0259e6f62e 100644 (file)
@@ -67,6 +67,8 @@ int sqlite3BtreeGetReserve(Btree*);
 int sqlite3BtreeSetAutoVacuum(Btree *, int);
 int sqlite3BtreeGetAutoVacuum(Btree *);
 int sqlite3BtreeBeginTrans(Btree*,int);
+int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
+int sqlite3BtreeCommitPhaseTwo(Btree*);
 int sqlite3BtreeCommit(Btree*);
 int sqlite3BtreeRollback(Btree*);
 int sqlite3BtreeBeginStmt(Btree*);
@@ -76,7 +78,6 @@ int sqlite3BtreeCreateTable(Btree*, int*, int flags);
 int sqlite3BtreeIsInTrans(Btree*);
 int sqlite3BtreeIsInStmt(Btree*);
 int sqlite3BtreeIsInReadTrans(Btree*);
-int sqlite3BtreeSync(Btree*, const char *zMaster);
 void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
 int sqlite3BtreeSchemaLocked(Btree *);
 int sqlite3BtreeLockTable(Btree *, int, u8);
@@ -114,10 +115,10 @@ void sqlite3BtreeSetCompare(
 );
 
 int sqlite3BtreeCloseCursor(BtCursor*);
-int sqlite3BtreeMoveto(BtCursor*, const void *pKey, i64 nKey, int *pRes);
+int sqlite3BtreeMoveto(BtCursor*,const void *pKey,i64 nKey,int bias,int *pRes);
 int sqlite3BtreeDelete(BtCursor*);
 int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
-                                  const void *pData, int nData);
+                                  const void *pData, int nData, int bias);
 int sqlite3BtreeFirst(BtCursor*, int *pRes);
 int sqlite3BtreeLast(BtCursor*, int *pRes);
 int sqlite3BtreeNext(BtCursor*, int *pRes);
index b2da7fb548e258bc3ec2deea8b01d956e4e5556d..250c968aa947560c0df5e795abb36fe10ecd8f4c 100644 (file)
@@ -82,7 +82,7 @@ void sqlite3TableLock(
   }
 
   nBytes = sizeof(TableLock) * (pParse->nTableLock+1);
-  sqliteReallocOrFree((void **)&pParse->aTableLock, nBytes);
+  pParse->aTableLock = sqliteReallocOrFree(pParse->aTableLock, nBytes);
   if( pParse->aTableLock ){
     p = &pParse->aTableLock[pParse->nTableLock++];
     p->iDb = iDb;
@@ -442,17 +442,6 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
   }
 }
 
-/*
-** This routine is called whenever a rollback occurs.  If there were
-** schema changes during the transaction, then we have to reset the
-** internal hash tables and reload them from disk.
-*/
-void sqlite3RollbackInternalChanges(sqlite3 *db){
-  if( db->flags & SQLITE_InternChanges ){
-    sqlite3ResetInternalSchema(db, 0);
-  }
-}
-
 /*
 ** This routine is called when a commit occurs.
 */
@@ -887,7 +876,7 @@ void sqlite3StartTable(
     sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
     sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
     sqlite3VdbeAddOp(v, OP_Null, 0, 0);
-    sqlite3VdbeAddOp(v, OP_Insert, 0, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, 0, OPFLAG_APPEND);
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
     sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
   }
@@ -2357,17 +2346,17 @@ void sqlite3CreateIndex(
     }
     if( !db->init.busy ){
       if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
-      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 ){
         sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
         goto exit_create_index;
       }
     }
+    if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
+      if( !ifNotExist ){
+        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+      }
+      goto exit_create_index;
+    }
   }else{
     char zBuf[30];
     int n;
@@ -2783,44 +2772,46 @@ exit_drop_index:
 }
 
 /*
-** ppArray points into a structure where there is an array pointer
-** followed by two integers. The first integer is the
-** number of elements in the structure array.  The second integer
-** is the number of allocated slots in the array.
-**
-** In other words, the structure looks something like this:
-**
-**        struct Example1 {
-**          struct subElem *aEntry;
-**          int nEntry;
-**          int nAlloc;
-**        }
+** pArray is a pointer to an array of objects.  Each object in the
+** array is szEntry bytes in size.  This routine allocates a new
+** object on the end of the array.
 **
-** The pnEntry parameter points to the equivalent of Example1.nEntry.
+** *pnEntry is the number of entries already in use.  *pnAlloc is
+** the previously allocated size of the array.  initSize is the
+** suggested initial array size allocation.
 **
-** This routine allocates a new slot in the array, zeros it out,
-** and returns its index.  If malloc fails a negative number is returned.
+** The index of the new entry is returned in *pIdx.
 **
-** szEntry is the sizeof of a single array entry.  initSize is the 
-** number of array entries allocated on the initial allocation.
+** This routine returns a pointer to the array of objects.  This
+** might be the same as the pArray parameter or it might be a different
+** pointer if the array was resized.
 */
-int sqlite3ArrayAllocate(void **ppArray, int szEntry, int initSize){
-  char *p;
-  int *an = (int*)&ppArray[1];
-  if( an[0]>=an[1] ){
+void *sqlite3ArrayAllocate(
+  void *pArray,     /* Array of objects.  Might be reallocated */
+  int szEntry,      /* Size of each object in the array */
+  int initSize,     /* Suggested initial allocation, in elements */
+  int *pnEntry,     /* Number of objects currently in use */
+  int *pnAlloc,     /* Current size of the allocation, in elements */
+  int *pIdx         /* Write the index of a new slot here */
+){
+  char *z;
+  if( *pnEntry >= *pnAlloc ){
     void *pNew;
     int newSize;
-    newSize = an[1]*2 + initSize;
-    pNew = sqliteRealloc(*ppArray, newSize*szEntry);
+    newSize = (*pnAlloc)*2 + initSize;
+    pNew = sqliteRealloc(pArray, newSize*szEntry);
     if( pNew==0 ){
-      return -1;
+      *pIdx = -1;
+      return pArray;
     }
-    an[1] = newSize;
-    *ppArray = pNew;
+    *pnAlloc = newSize;
+    pArray = pNew;
   }
-  p = *ppArray;
-  memset(&p[an[0]*szEntry], 0, szEntry);
-  return an[0]++;
+  z = (char*)pArray;
+  memset(&z[*pnEntry * szEntry], 0, szEntry);
+  *pIdx = *pnEntry;
+  ++*pnEntry;
+  return pArray;
 }
 
 /*
@@ -2836,7 +2827,14 @@ IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){
     if( pList==0 ) return 0;
     pList->nAlloc = 0;
   }
-  i = sqlite3ArrayAllocate((void**)&pList->a, sizeof(pList->a[0]), 5);
+  pList->a = sqlite3ArrayAllocate(
+      pList->a,
+      sizeof(pList->a[0]),
+      5,
+      &pList->nId,
+      &pList->nAlloc,
+      &i
+  );
   if( i<0 ){
     sqlite3IdListDelete(pList);
     return 0;
index a8cbd2630cf6060f010dc167e90fd0825b52f42b..a5446e128e3a54c2f4b0b539b948650e8e72f8b4 100644 (file)
@@ -565,7 +565,7 @@ static int parseModifier(const char *zMod, DateTime *p){
     case '8':
     case '9': {
       n = getValue(z, &r);
-      if( n<=0 ) break;
+      assert( n>=1 );
       if( z[n]==':' ){
         /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
         ** specified number of hours, minutes, seconds, and fractional seconds
@@ -815,7 +815,7 @@ static void strftimeFunc(
         case 'f': {
           double s = x.s;
           if( s>59.999 ) s = 59.999;
-          sqlite3_snprintf(7, &z[j],"%02.3f", s);
+          sqlite3_snprintf(7, &z[j],"%06.3f", s);
           j += strlen(&z[j]);
           break;
         }
index 6d21918cd08fbb17743b76a41d6ccd4772a11fe2..54a9f6abe140db170e1208e311955d26eaf856f5 100644 (file)
@@ -131,7 +131,7 @@ static char comparisonAffinity(Expr *pExpr){
     aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff);
   }
   else if( !aff ){
-    aff = SQLITE_AFF_NUMERIC;
+    aff = SQLITE_AFF_NONE;
   }
   return aff;
 }
@@ -404,7 +404,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
       pExpr->iTable = ++pParse->nVar;
       if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
         pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
-        sqliteReallocOrFree((void**)&pParse->apVarExpr,
+        pParse->apVarExpr = sqliteReallocOrFree(pParse->apVarExpr,
                        pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
       }
       if( !sqlite3MallocFailed() ){
@@ -1518,6 +1518,31 @@ static void codeInteger(Vdbe *v, const char *z, int n){
   }
 }
 
+
+/*
+** Generate code that will extract the iColumn-th column from
+** table pTab and push that column value on the stack.  There
+** is an open cursor to pTab in iTable.  If iColumn<0 then
+** code is generated that extracts the rowid.
+*/
+void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){
+  if( iColumn<0 ){
+    int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
+    sqlite3VdbeAddOp(v, op, iTable, 0);
+  }else if( pTab==0 ){
+    sqlite3VdbeAddOp(v, OP_Column, iTable, iColumn);
+  }else{
+    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
+    sqlite3VdbeAddOp(v, op, iTable, iColumn);
+    sqlite3ColumnDefault(v, pTab, iColumn);
+#ifndef SQLITE_OMIT_FLOATING_POINT
+    if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
+      sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0);
+    }
+#endif
+  }
+}
+
 /*
 ** Generate code into the current Vdbe to evaluate the given
 ** expression and leave the result on the top of stack.
@@ -1558,21 +1583,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
         /* 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;
-        int op = (pTab && IsVirtual(pTab)) ? OP_VColumn : OP_Column;
-        sqlite3VdbeAddOp(v, op, 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{
-        Table *pTab = pExpr->pTab;
-        int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
-        sqlite3VdbeAddOp(v, op, pExpr->iTable, 0);
+        sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);
       }
       break;
     }
@@ -2175,6 +2187,16 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
 /*
 ** Do a deep comparison of two expression trees.  Return TRUE (non-zero)
 ** if they are identical and return FALSE if they differ in any way.
+**
+** Sometimes this routine will return FALSE even if the two expressions
+** really are equivalent.  If we cannot prove that the expressions are
+** identical, we return FALSE just to be safe.  So if this routine
+** returns false, then you do not really know for certain if the two
+** expressions are the same.  But if you get a TRUE return, then you
+** can be sure the expressions are the same.  In the places where
+** this routine is used, it does not hurt to get an extra FALSE - that
+** just might result in some slightly slower code.  But returning
+** an incorrect TRUE could lead to a malfunction.
 */
 int sqlite3ExprCompare(Expr *pA, Expr *pB){
   int i;
@@ -2198,7 +2220,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
   }
   if( pA->pSelect || pB->pSelect ) return 0;
   if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
-  if( pA->token.z ){
+  if( pA->op!=TK_COLUMN && pA->token.z ){
     if( pB->token.z==0 ) return 0;
     if( pB->token.n!=pA->token.n ) return 0;
     if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){
@@ -2215,10 +2237,14 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
 */
 static int addAggInfoColumn(AggInfo *pInfo){
   int i;
-  i = sqlite3ArrayAllocate((void**)&pInfo->aCol, sizeof(pInfo->aCol[0]), 3);
-  if( i<0 ){
-    return -1;
-  }
+  pInfo->aCol = sqlite3ArrayAllocate(
+       pInfo->aCol,
+       sizeof(pInfo->aCol[0]),
+       3,
+       &pInfo->nColumn,
+       &pInfo->nColumnAlloc,
+       &i
+  );
   return i;
 }    
 
@@ -2228,10 +2254,14 @@ static int addAggInfoColumn(AggInfo *pInfo){
 */
 static int addAggInfoFunc(AggInfo *pInfo){
   int i;
-  i = sqlite3ArrayAllocate((void**)&pInfo->aFunc, sizeof(pInfo->aFunc[0]), 2);
-  if( i<0 ){
-    return -1;
-  }
+  pInfo->aFunc = sqlite3ArrayAllocate(
+       pInfo->aFunc,
+       sizeof(pInfo->aFunc[0]),
+       3,
+       &pInfo->nFunc,
+       &pInfo->nFuncAlloc,
+       &i
+  );
   return i;
 }    
 
@@ -2266,15 +2296,17 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){
             ** Make an entry for the column in pAggInfo->aCol[] if there
             ** is not an entry there already.
             */
+            int k;
             pCol = pAggInfo->aCol;
-            for(i=0; i<pAggInfo->nColumn; i++, pCol++){
+            for(k=0; k<pAggInfo->nColumn; k++, pCol++){
               if( pCol->iTable==pExpr->iTable &&
                   pCol->iColumn==pExpr->iColumn ){
                 break;
               }
             }
-            if( i>=pAggInfo->nColumn && (i = addAggInfoColumn(pAggInfo))>=0 ){
-              pCol = &pAggInfo->aCol[i];
+            if( k>=pAggInfo->nColumn && (k = addAggInfoColumn(pAggInfo))>=0 ){
+              pCol = &pAggInfo->aCol[k];
+              pCol->pTab = pExpr->pTab;
               pCol->iTable = pExpr->iTable;
               pCol->iColumn = pExpr->iColumn;
               pCol->iMem = pParse->nMem++;
@@ -2305,7 +2337,7 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){
             */
             pExpr->pAggInfo = pAggInfo;
             pExpr->op = TK_AGG_COLUMN;
-            pExpr->iAgg = i;
+            pExpr->iAgg = k;
             break;
           } /* endif pExpr->iTable==pItem->iCursor */
         } /* end loop over pSrcList */
index 455bd2beb0a0d7f360e845044675a08055e12092..567a4fbff84b1aeb8045cd57dc426e54752d4ba1 100644 (file)
@@ -668,6 +668,114 @@ static void hexFunc(
   sqlite3_result_text(context, zHex, n*2, sqlite3_free);
 }
 
+/*
+** The replace() function.  Three arguments are all strings: call
+** them A, B, and C. The result is also a string which is derived
+** from A by replacing every occurance of B with C.  The match
+** must be exact.  Collating sequences are not used.
+*/
+static void replaceFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  const unsigned char *zStr;        /* The input string A */
+  const unsigned char *zPattern;    /* The pattern string B */
+  const unsigned char *zRep;        /* The replacement string C */
+  unsigned char *zOut;              /* The output */
+  int nStr;                /* Size of zStr */
+  int nPattern;            /* Size of zPattern */
+  int nRep;                /* Size of zRep */
+  int nOut;                /* Maximum size of zOut */
+  int loopLimit;           /* Last zStr[] that might match zPattern[] */
+  int i, j;                /* Loop counters */
+
+  assert( argc==3 );
+  if( sqlite3_value_type(argv[0])==SQLITE_NULL ||
+      sqlite3_value_type(argv[1])==SQLITE_NULL ||
+      sqlite3_value_type(argv[2])==SQLITE_NULL ){
+    return;
+  }
+  zStr = sqlite3_value_text(argv[0]);
+  nStr = sqlite3_value_bytes(argv[0]);
+  zPattern = sqlite3_value_text(argv[1]);
+  nPattern = sqlite3_value_bytes(argv[1]);
+  zRep = sqlite3_value_text(argv[2]);
+  nRep = sqlite3_value_bytes(argv[2]);
+  if( nPattern>=nRep ){
+    nOut = nStr;
+  }else{
+    nOut = (nStr/nPattern + 1)*nRep;
+  }
+  zOut = sqlite3_malloc(nOut+1);
+  if( zOut==0 ) return;
+  loopLimit = nStr - nPattern;  
+  for(i=j=0; i<=loopLimit; i++){
+    if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
+      zOut[j++] = zStr[i];
+    }else{
+      memcpy(&zOut[j], zRep, nRep);
+      j += nRep;
+      i += nPattern-1;
+    }
+  }
+  memcpy(&zOut[j], &zStr[i], nStr-i);
+  j += nStr - i;
+  assert( j<=nOut );
+  zOut[j] = 0;
+  sqlite3_result_text(context, (char*)zOut, j, sqlite3_free);
+}
+
+/*
+** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
+** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
+*/
+static void trimFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  const unsigned char *zIn;         /* Input string */
+  const unsigned char *zCharSet;    /* Set of characters to trim */
+  int nIn;                          /* Number of bytes in input */
+  int flags;
+  int i;
+  unsigned char cFirst, cNext;
+  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+    return;
+  }
+  zIn = sqlite3_value_text(argv[0]);
+  nIn = sqlite3_value_bytes(argv[0]);
+  if( argc==1 ){
+    static const unsigned char zSpace[] = " ";
+    zCharSet = zSpace;
+  }else if( sqlite3_value_type(argv[1])==SQLITE_NULL ){
+    return;
+  }else{
+    zCharSet = sqlite3_value_text(argv[1]);
+  }
+  cFirst = zCharSet[0];
+  if( cFirst ){
+    flags = (int)sqlite3_user_data(context);
+    if( flags & 1 ){
+      for(; nIn>0; nIn--, zIn++){
+        if( cFirst==zIn[0] ) continue;
+        for(i=1; zCharSet[i] && zCharSet[i]!=zIn[0]; i++){}
+        if( zCharSet[i]==0 ) break;
+      }
+    }
+    if( flags & 2 ){
+      for(; nIn>0; nIn--){
+        cNext = zIn[nIn-1];
+        if( cFirst==cNext ) continue;
+        for(i=1; zCharSet[i] && zCharSet[i]!=cNext; i++){}
+        if( zCharSet[i]==0 ) break;
+      }
+    }
+  }
+  sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
+}
+
 #ifdef SQLITE_SOUNDEX
 /*
 ** Compute the soundex encoding of a word.
@@ -1019,7 +1127,7 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
     ** Therefore the next statement sets variable 'max' to 1 for the max()
     ** aggregate, or 0 for min().
     */
-    max = ((sqlite3_user_data(context)==(void *)-1)?1:0);
+    max = sqlite3_user_data(context)!=0;
     cmp = sqlite3MemCompare(pBest, pArg, pColl);
     if( (max && cmp<0) || (!max && cmp>0) ){
       sqlite3VdbeMemCopy(pBest, pArg);
@@ -1049,15 +1157,15 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
   static const struct {
      char *zName;
      signed char nArg;
-     u8 argType;           /* 0: none.  1: db  2: (-1) */
+     u8 argType;           /* ff: db   1: 0, 2: 1, 3: 2,...  N:  N-1. */
      u8 eTextRep;          /* 1: UTF-16.  0: UTF-8 */
      u8 needCollSeq;
      void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
   } aFuncs[] = {
     { "min",               -1, 0, SQLITE_UTF8,    1, minmaxFunc },
     { "min",                0, 0, SQLITE_UTF8,    1, 0          },
-    { "max",               -1, 2, SQLITE_UTF8,    1, minmaxFunc },
-    { "max",                0, 2, SQLITE_UTF8,    1, 0          },
+    { "max",               -1, 1, SQLITE_UTF8,    1, minmaxFunc },
+    { "max",                0, 1, SQLITE_UTF8,    1, 0          },
     { "typeof",             1, 0, SQLITE_UTF8,    0, typeofFunc },
     { "length",             1, 0, SQLITE_UTF8,    0, lengthFunc },
     { "substr",             3, 0, SQLITE_UTF8,    0, substrFunc },
@@ -1079,22 +1187,29 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
     { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
     { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
-    { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
-    { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
-    { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
+    { "last_insert_rowid",  0, 0xff, SQLITE_UTF8, 0, last_insert_rowid },
+    { "changes",            0, 0xff, SQLITE_UTF8, 0, changes           },
+    { "total_changes",      0, 0xff, SQLITE_UTF8, 0, total_changes     },
+    { "replace",            3, 0, SQLITE_UTF8,    0, replaceFunc       },
+    { "ltrim",              1, 1, SQLITE_UTF8,    0, trimFunc          },
+    { "ltrim",              2, 1, SQLITE_UTF8,    0, trimFunc          },
+    { "rtrim",              1, 2, SQLITE_UTF8,    0, trimFunc          },
+    { "rtrim",              2, 2, SQLITE_UTF8,    0, trimFunc          },
+    { "trim",               1, 3, SQLITE_UTF8,    0, trimFunc          },
+    { "trim",               2, 3, SQLITE_UTF8,    0, trimFunc          },
 #ifdef SQLITE_SOUNDEX
-    { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
+    { "soundex",            1, 0, SQLITE_UTF8,    0, soundexFunc},
 #endif
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
-    { "load_extension",     1, 1, SQLITE_UTF8,    0, loadExt },
-    { "load_extension",     2, 1, SQLITE_UTF8,    0, loadExt },
+    { "load_extension",     1, 0xff, SQLITE_UTF8, 0, loadExt },
+    { "load_extension",     2, 0xff, SQLITE_UTF8, 0, loadExt },
 #endif
 #ifdef SQLITE_TEST
-    { "randstr",               2, 0, SQLITE_UTF8, 0, randStr    },
-    { "test_destructor",       1, 1, SQLITE_UTF8, 0, test_destructor},
-    { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
-    { "test_auxdata",         -1, 0, SQLITE_UTF8, 0, test_auxdata},
-    { "test_error",            1, 0, SQLITE_UTF8, 0, test_error},
+    { "randstr",               2, 0,    SQLITE_UTF8, 0, randStr    },
+    { "test_destructor",       1, 0xff, SQLITE_UTF8, 0, test_destructor},
+    { "test_destructor_count", 0, 0,    SQLITE_UTF8, 0, test_destructor_count},
+    { "test_auxdata",         -1, 0,    SQLITE_UTF8, 0, test_auxdata},
+    { "test_error",            1, 0,    SQLITE_UTF8, 0, test_error},
 #endif
   };
   static const struct {
@@ -1106,7 +1221,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     void (*xFinalize)(sqlite3_context*);
   } aAggs[] = {
     { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
-    { "max",    1, 2, 1, minmaxStep,   minMaxFinalize },
+    { "max",    1, 1, 1, minmaxStep,   minMaxFinalize },
     { "sum",    1, 0, 0, sumStep,      sumFinalize    },
     { "total",  1, 0, 0, sumStep,      totalFinalize    },
     { "avg",    1, 0, 0, sumStep,      avgFinalize    },
@@ -1116,10 +1231,12 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
   int i;
 
   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-    void *pArg = 0;
-    switch( aFuncs[i].argType ){
-      case 1: pArg = db; break;
-      case 2: pArg = (void *)(-1); break;
+    void *pArg;
+    u8 argType = aFuncs[i].argType;
+    if( argType==0xff ){
+      pArg = db;
+    }else{
+      pArg = (void*)(int)argType;
     }
     sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
         aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
@@ -1138,11 +1255,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
   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;
-    }
+    void *pArg = (void*)(int)aAggs[i].argType;
     sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
         pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
     if( aAggs[i].needCollSeq ){
index 1c32c1b7cc9916768c4889c11fd8e91b5a78d4bc..8f34caba42d918726a04a59f683ab831e30bf86a 100644 (file)
@@ -291,7 +291,7 @@ static void removeElementGivenHash(
   if( pEntry->count<=0 ){
     pEntry->chain = 0;
   }
-  if( pH->copyKey && elem->pKey ){
+  if( pH->copyKey ){
     pH->xFree(elem->pKey);
   }
   pH->xFree( elem );
@@ -378,6 +378,9 @@ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
     rehash(pH,8);
     if( pH->htsize==0 ){
       pH->count = 0;
+      if( pH->copyKey ){
+        pH->xFree(new_elem->pKey);
+      }
       pH->xFree(new_elem);
       return data;
     }
index adcc37a4cbbf615497aa226e6a57056509bf0a08..035730de182130e9eed6838ced80433bf229fc1c 100644 (file)
@@ -118,6 +118,117 @@ static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
   return 0;
 }
 
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+/*
+** Write out code to initialize the autoincrement logic.  This code
+** looks up the current autoincrement value in the sqlite_sequence
+** table and stores that value in a memory cell.  Code generated by
+** autoIncStep() will keep that memory cell holding the largest
+** rowid value.  Code generated by autoIncEnd() will write the new
+** largest value of the counter back into the sqlite_sequence table.
+**
+** This routine returns the index of the mem[] cell that contains
+** the maximum rowid counter.
+**
+** Two memory cells are allocated.  The next memory cell after the
+** one returned holds the rowid in sqlite_sequence where we will
+** write back the revised maximum rowid.
+*/
+static int autoIncBegin(
+  Parse *pParse,      /* Parsing context */
+  int iDb,            /* Index of the database holding pTab */
+  Table *pTab         /* The table we are writing to */
+){
+  int memId = 0;
+  if( pTab->autoInc ){
+    Vdbe *v = pParse->pVdbe;
+    Db *pDb = &pParse->db->aDb[iDb];
+    int iCur = pParse->nTab;
+    int addr;
+    assert( v );
+    addr = sqlite3VdbeCurrentAddr(v);
+    memId = pParse->nMem+1;
+    pParse->nMem += 2;
+    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, 0x100, addr+12);
+    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+    sqlite3VdbeAddOp(v, OP_MemStore, memId-1, 1);
+    sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
+    sqlite3VdbeAddOp(v, OP_MemStore, memId, 1);
+    sqlite3VdbeAddOp(v, OP_Goto, 0, addr+13);
+    sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4);
+    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+  }
+  return memId;
+}
+
+/*
+** Update the maximum rowid for an autoincrement calculation.
+**
+** This routine should be called when the top of the stack holds a
+** new rowid that is about to be inserted.  If that new rowid is
+** larger than the maximum rowid in the memId memory cell, then the
+** memory cell is updated.  The stack is unchanged.
+*/
+static void autoIncStep(Parse *pParse, int memId){
+  if( memId>0 ){
+    sqlite3VdbeAddOp(pParse->pVdbe, OP_MemMax, memId, 0);
+  }
+}
+
+/*
+** After doing one or more inserts, the maximum rowid is stored
+** in mem[memId].  Generate code to write this value back into the
+** the sqlite_sequence table.
+*/
+static void autoIncEnd(
+  Parse *pParse,     /* The parsing context */
+  int iDb,           /* Index of the database holding pTab */
+  Table *pTab,       /* Table we are inserting into */
+  int memId          /* Memory cell holding the maximum rowid */
+){
+  if( pTab->autoInc ){
+    int iCur = pParse->nTab;
+    Vdbe *v = pParse->pVdbe;
+    Db *pDb = &pParse->db->aDb[iDb];
+    int addr;
+    assert( v );
+    addr = sqlite3VdbeCurrentAddr(v);
+    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
+    sqlite3VdbeAddOp(v, OP_MemLoad, memId-1, 0);
+    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);
+    sqlite3VdbeAddOp(v, OP_MemLoad, memId, 0);
+    sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, iCur, OPFLAG_APPEND);
+    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+  }
+}
+#else
+/*
+** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
+** above are all no-ops
+*/
+# define autoIncBegin(A,B,C) (0)
+# define autoIncStep(A,B)
+# define autoIncEnd(A,B,C,D)
+#endif /* SQLITE_OMIT_AUTOINCREMENT */
+
+
+/* Forward declaration */
+static int xferOptimization(
+  Parse *pParse,        /* Parser context */
+  Table *pDest,         /* The table we are inserting into */
+  Select *pSelect,      /* A SELECT statement to use as the data source */
+  int onError,          /* How to handle constraint errors */
+  int iDbDest           /* The database of pDest */
+);
+
 /*
 ** This routine is call to handle SQL of the following forms:
 **
@@ -133,7 +244,7 @@ static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
 ** NULL and pSelect is a pointer to the select statement used to generate
 ** data for the insert.
 **
-** The code generated follows one of three templates.  For a simple
+** The code generated follows one of four templates.  For a simple
 ** select with data coming from a VALUES clause, the code executes
 ** once straight down through.  The template looks like this:
 **
@@ -142,16 +253,37 @@ static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
 **         write the resulting record into <table>
 **         cleanup
 **
-** If the statement is of the form
+** The three remaining templates assume the statement is of the form
 **
 **   INSERT INTO <table> SELECT ...
 **
-** And the SELECT clause does not read from <table> at any time, then
-** the generated code follows this template:
+** If the SELECT clause is of the restricted form "SELECT * FROM <table2>" -
+** in other words if the SELECT pulls all columns from a single table
+** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and
+** if <table2> and <table1> are distinct tables but have identical
+** schemas, including all the same indices, then a special optimization
+** is invoked that copies raw records from <table2> over to <table1>.
+** See the xferOptimization() function for the implementation of this
+** template.  This is the second template.
+**
+**         open a write cursor to <table>
+**         open read cursor on <table2>
+**         transfer all records in <table2> over to <table>
+**         close cursors
+**         foreach index on <table>
+**           open a write cursor on the <table> index
+**           open a read cursor on the corresponding <table2> index
+**           transfer all records from the read to the write cursors
+**           close cursors
+**         end foreach
+**
+** The third template is for when the second template does not apply
+** and the SELECT clause does not read from <table> at any time.
+** The generated code follows this template:
 **
 **         goto B
 **      A: setup for the SELECT
-**         loop over the tables in the SELECT
+**         loop over the rows in the SELECT
 **           gosub C
 **         end loop
 **         cleanup after the SELECT
@@ -162,7 +294,7 @@ static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
 **         return
 **      D: cleanup
 **
-** The third template is used if the insert statement takes its
+** The fourth template is used if the insert statement takes its
 ** values from a SELECT but the data is being inserted into a table
 ** that is also read as part of the SELECT.  In the third form,
 ** we have to use a intermediate table to store the results of
@@ -214,6 +346,7 @@ void sqlite3Insert(
   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 appendFlag = 0;   /* True if the insert is likely to be an append */
   int iDb;
 
 #ifndef SQLITE_OMIT_TRIGGER
@@ -221,10 +354,6 @@ void sqlite3Insert(
   int triggers_exist = 0;     /* True if there are FOR EACH ROW triggers */
 #endif
 
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-  int counterRowid = 0;  /* Memory cell holding rowid of autoinc counter */
-#endif
-
   if( pParse->nErr || sqlite3MallocFailed() ){
     goto insert_cleanup;
   }
@@ -291,31 +420,27 @@ void sqlite3Insert(
     newIdx = pParse->nTab++;
   }
 
-#ifndef SQLITE_OMIT_AUTOINCREMENT
+#ifndef SQLITE_OMIT_XFER_OPT
+  /* If the statement is of the form
+  **
+  **       INSERT INTO <table1> SELECT * FROM <table2>;
+  **
+  ** Then special optimizations can be applied that make the transfer
+  ** very fast and which reduce fragmentation of indices.
+  */
+  if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
+    assert( !triggers_exist );
+    assert( pList==0 );
+    goto insert_cleanup;
+  }
+#endif /* SQLITE_OMIT_XFER_OPT */
+
   /* If this is an AUTOINCREMENT table, look up the sequence number in the
   ** sqlite_sequence table and store it in memory cell counterMem.  Also
   ** remember the rowid of the sqlite_sequence table entry in memory cell
   ** counterRowid.
   */
-  if( pTab->autoInc ){
-    int iCur = pParse->nTab;
-    int addr = sqlite3VdbeCurrentAddr(v);
-    counterRowid = pParse->nMem++;
-    counterMem = pParse->nMem++;
-    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, 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, addr+13);
-    sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4);
-    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
-  }
-#endif /* SQLITE_OMIT_AUTOINCREMENT */
+  counterMem = autoIncBegin(pParse, iDb, pTab);
 
   /* Figure out how many columns of data are supplied.  If the data
   ** is coming from a SELECT statement, then this step also generates
@@ -365,7 +490,7 @@ void sqlite3Insert(
       sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
       sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-      sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, srcTab, OPFLAG_APPEND);
       sqlite3VdbeAddOp(v, OP_Return, 0, 0);
 
       /* The following code runs first because the GOTO at the very top
@@ -577,25 +702,32 @@ void sqlite3Insert(
       }else if( pSelect ){
         sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
       }else{
+        VdbeOp *pOp;
         sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
+        pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1);
+        if( pOp->opcode==OP_Null ){
+          appendFlag = 1;
+          pOp->opcode = OP_NewRowid;
+          pOp->p1 = base;
+          pOp->p2 = counterMem;
+        }
       }
       /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
       ** to generate a unique primary key value.
       */
-      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
-      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
-      sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
-      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+      if( !appendFlag ){
+        sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
+        sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+        sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
+        sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+      }
     }else if( IsVirtual(pTab) ){
       sqlite3VdbeAddOp(v, OP_Null, 0, 0);
     }else{
       sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
+      appendFlag = 1;
     }
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-    if( pTab->autoInc ){
-      sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0);
-    }
-#endif /* SQLITE_OMIT_AUTOINCREMENT */
+    autoIncStep(pParse, counterMem);
 
     /* Push onto the stack, data for all columns of the new entry, beginning
     ** with the first column.
@@ -641,7 +773,8 @@ void sqlite3Insert(
       sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
                                      0, onError, endOfLoop);
       sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
-                            (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1);
+                            (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1,
+                            appendFlag);
     }
   }
 
@@ -688,26 +821,11 @@ void sqlite3Insert(
     }
   }
 
-#ifndef SQLITE_OMIT_AUTOINCREMENT
   /* Update the sqlite_sequence table by storing the content of the
   ** counter value in memory counterMem back into the sqlite_sequence
   ** table.
   */
-  if( pTab->autoInc ){
-    int iCur = pParse->nTab;
-    int addr = sqlite3VdbeCurrentAddr(v);
-    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
-    sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
-    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);
-    sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
-    sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
-    sqlite3VdbeAddOp(v, OP_Insert, iCur, 0);
-    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
-  }
-#endif
+  autoIncEnd(pParse, iDb, pTab, counterMem);
 
   /*
   ** Return the number of rows inserted. If this routine is 
@@ -1067,7 +1185,8 @@ void sqlite3CompleteInsertion(
   char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
   int rowidChng,      /* True if the record number will change */
   int isUpdate,       /* True for UPDATE, False for INSERT */
-  int newIdx          /* Index of NEW table for triggers.  -1 if none */
+  int newIdx,         /* Index of NEW table for triggers.  -1 if none */
+  int appendBias      /* True if this is likely to be an append */
 ){
   int i;
   Vdbe *v;
@@ -1098,6 +1217,9 @@ void sqlite3CompleteInsertion(
     pik_flags = OPFLAG_NCHANGE;
     pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
   }
+  if( appendBias ){
+    pik_flags |= OPFLAG_APPEND;
+  }
   sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
   if( !pParse->nested ){
     sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
@@ -1140,3 +1262,327 @@ void sqlite3OpenTableAndIndices(
     pParse->nTab = base+i;
   }
 }
+
+
+#ifdef SQLITE_TEST
+/*
+** The following global variable is incremented whenever the
+** transfer optimization is used.  This is used for testing
+** purposes only - to make sure the transfer optimization really
+** is happening when it is suppose to.
+*/
+int sqlite3_xferopt_count;
+#endif /* SQLITE_TEST */
+
+
+#ifndef SQLITE_OMIT_XFER_OPT
+/*
+** Check to collation names to see if they are compatible.
+*/
+static int xferCompatibleCollation(const char *z1, const char *z2){
+  if( z1==0 ){
+    return z2==0;
+  }
+  if( z2==0 ){
+    return 0;
+  }
+  return sqlite3StrICmp(z1, z2)==0;
+}
+
+
+/*
+** Check to see if index pSrc is compatible as a source of data
+** for index pDest in an insert transfer optimization.  The rules
+** for a compatible index:
+**
+**    *   The index is over the same set of columns
+**    *   The same DESC and ASC markings occurs on all columns
+**    *   The same onError processing (OE_Abort, OE_Ignore, etc)
+**    *   The same collating sequence on each column
+*/
+static int xferCompatibleIndex(Index *pDest, Index *pSrc){
+  int i;
+  assert( pDest && pSrc );
+  assert( pDest->pTable!=pSrc->pTable );
+  if( pDest->nColumn!=pSrc->nColumn ){
+    return 0;   /* Different number of columns */
+  }
+  if( pDest->onError!=pSrc->onError ){
+    return 0;   /* Different conflict resolution strategies */
+  }
+  for(i=0; i<pSrc->nColumn; i++){
+    if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
+      return 0;   /* Different columns indexed */
+    }
+    if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
+      return 0;   /* Different sort orders */
+    }
+    if( pSrc->azColl[i]!=pDest->azColl[i] ){
+      return 0;   /* Different sort orders */
+    }
+  }
+
+  /* If no test above fails then the indices must be compatible */
+  return 1;
+}
+
+/*
+** Attempt the transfer optimization on INSERTs of the form
+**
+**     INSERT INTO tab1 SELECT * FROM tab2;
+**
+** This optimization is only attempted if
+**
+**    (1)  tab1 and tab2 have identical schemas including all the
+**         same indices and constraints
+**
+**    (2)  tab1 and tab2 are different tables
+**
+**    (3)  There must be no triggers on tab1
+**
+**    (4)  The result set of the SELECT statement is "*"
+**
+**    (5)  The SELECT statement has no WHERE, HAVING, ORDER BY, GROUP BY,
+**         or LIMIT clause.
+**
+**    (6)  The SELECT statement is a simple (not a compound) select that
+**         contains only tab2 in its FROM clause
+**
+** This method for implementing the INSERT transfers raw records from
+** tab2 over to tab1.  The columns are not decoded.  Raw records from
+** the indices of tab2 are transfered to tab1 as well.  In so doing,
+** the resulting tab1 has much less fragmentation.
+**
+** This routine returns TRUE if the optimization is attempted.  If any
+** of the conditions above fail so that the optimization should not
+** be attempted, then this routine returns FALSE.
+*/
+static int xferOptimization(
+  Parse *pParse,        /* Parser context */
+  Table *pDest,         /* The table we are inserting into */
+  Select *pSelect,      /* A SELECT statement to use as the data source */
+  int onError,          /* How to handle constraint errors */
+  int iDbDest           /* The database of pDest */
+){
+  ExprList *pEList;                /* The result set of the SELECT */
+  Table *pSrc;                     /* The table in the FROM clause of SELECT */
+  Index *pSrcIdx, *pDestIdx;       /* Source and destination indices */
+  struct SrcList_item *pItem;      /* An element of pSelect->pSrc */
+  int i;                           /* Loop counter */
+  int iDbSrc;                      /* The database of pSrc */
+  int iSrc, iDest;                 /* Cursors from source and destination */
+  int addr1, addr2;                /* Loop addresses */
+  int emptyDestTest;               /* Address of test for empty pDest */
+  int emptySrcTest;                /* Address of test for empty pSrc */
+  int memRowid = 0;                /* A memcell containing a rowid from pSrc */
+  Vdbe *v;                         /* The VDBE we are building */
+  KeyInfo *pKey;                   /* Key information for an index */
+  int counterMem;                  /* Memory register used by AUTOINC */
+
+  if( pSelect==0 ){
+    return 0;   /* Must be of the form  INSERT INTO ... SELECT ... */
+  }
+  if( pDest->pTrigger ){
+    return 0;   /* tab1 must not have triggers */
+  }
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+  if( pDest->isVirtual ){
+    return 0;   /* tab1 must not be a virtual table */
+  }
+#endif
+  if( onError==OE_Default ){
+    onError = OE_Abort;
+  }
+  if( onError!=OE_Abort && onError!=OE_Rollback ){
+    return 0;   /* Cannot do OR REPLACE or OR IGNORE or OR FAIL */
+  }
+  if( pSelect->pSrc==0 ){
+    return 0;   /* SELECT must have a FROM clause */
+  }
+  if( pSelect->pSrc->nSrc!=1 ){
+    return 0;   /* FROM clause must have exactly one term */
+  }
+  if( pSelect->pSrc->a[0].pSelect ){
+    return 0;   /* FROM clause cannot contain a subquery */
+  }
+  if( pSelect->pWhere ){
+    return 0;   /* SELECT may not have a WHERE clause */
+  }
+  if( pSelect->pOrderBy ){
+    return 0;   /* SELECT may not have an ORDER BY clause */
+  }
+  /* Do not need to test for a HAVING clause.  If HAVING is present but
+  ** there is no ORDER BY, we will get an error. */
+  if( pSelect->pGroupBy ){
+    return 0;   /* SELECT may not have a GROUP BY clause */
+  }
+  if( pSelect->pLimit ){
+    return 0;   /* SELECT may not have a LIMIT clause */
+  }
+  assert( pSelect->pOffset==0 );  /* Must be so if pLimit==0 */
+  if( pSelect->pPrior ){
+    return 0;   /* SELECT may not be a compound query */
+  }
+  if( pSelect->isDistinct ){
+    return 0;   /* SELECT may not be DISTINCT */
+  }
+  pEList = pSelect->pEList;
+  assert( pEList!=0 );
+  if( pEList->nExpr!=1 ){
+    return 0;   /* The result set must have exactly one column */
+  }
+  assert( pEList->a[0].pExpr );
+  if( pEList->a[0].pExpr->op!=TK_ALL ){
+    return 0;   /* The result set must be the special operator "*" */
+  }
+
+  /* At this point we have established that the statement is of the
+  ** correct syntactic form to participate in this optimization.  Now
+  ** we have to check the semantics.
+  */
+  pItem = pSelect->pSrc->a;
+  pSrc = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
+  if( pSrc==0 ){
+    return 0;   /* FROM clause does not contain a real table */
+  }
+  if( pSrc==pDest ){
+    return 0;   /* tab1 and tab2 may not be the same table */
+  }
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+  if( pSrc->isVirtual ){
+    return 0;   /* tab2 must not be a virtual table */
+  }
+#endif
+  if( pSrc->pSelect ){
+    return 0;   /* tab2 may not be a view */
+  }
+  if( pDest->nCol!=pSrc->nCol ){
+    return 0;   /* Number of columns must be the same in tab1 and tab2 */
+  }
+  if( pDest->iPKey!=pSrc->iPKey ){
+    return 0;   /* Both tables must have the same INTEGER PRIMARY KEY */
+  }
+  for(i=0; i<pDest->nCol; i++){
+    if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){
+      return 0;    /* Affinity must be the same on all columns */
+    }
+    if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){
+      return 0;    /* Collating sequence must be the same on all columns */
+    }
+    if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){
+      return 0;    /* tab2 must be NOT NULL if tab1 is */
+    }
+  }
+  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
+    for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
+      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
+    }
+    if( pSrcIdx==0 ){
+      return 0;    /* pDestIdx has no corresponding index in pSrc */
+    }
+  }
+#ifndef SQLITE_OMIT_CHECK
+  if( pDest->pCheck && !sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){
+    return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
+  }
+#endif
+
+  /* If we get this far, it means either:
+  **
+  **    *   We can always do the transfer if the table contains an
+  **        an integer primary key
+  **
+  **    *   We can conditionally do the transfer if the destination
+  **        table is empty.
+  */
+#ifdef SQLITE_TEST
+  sqlite3_xferopt_count++;
+#endif
+  iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
+  v = sqlite3GetVdbe(pParse);
+  iSrc = pParse->nTab++;
+  iDest = pParse->nTab++;
+  counterMem = autoIncBegin(pParse, iDbDest, pDest);
+  sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
+  if( pDest->iPKey<0 && pDest->pIndex!=0 ){
+    /* If tables do not have an INTEGER PRIMARY KEY and there
+    ** are indices to be copied and the destination is not empty,
+    ** we have to disallow the transfer optimization because the
+    ** the rowids might change which will mess up indexing.
+    */
+    addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iDest, 0);
+    emptyDestTest = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
+    sqlite3VdbeJumpHere(v, addr1);
+  }else{
+    emptyDestTest = 0;
+  }
+  sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
+  emptySrcTest = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0);
+  if( pDest->pIndex!=0 ){
+    sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
+    memRowid = pParse->nMem++;
+    sqlite3VdbeAddOp(v, OP_MemStore, memRowid, pDest->iPKey>=0);
+  }
+  if( pDest->iPKey>=0 ){
+    addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
+    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+    addr2 = sqlite3VdbeAddOp(v, OP_NotExists, iDest, 0);
+    sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, 
+                      "PRIMARY KEY must be unique", P3_STATIC);
+    sqlite3VdbeJumpHere(v, addr2);
+    autoIncStep(pParse, counterMem);
+  }else if( pDest->pIndex==0 ){
+    addr1 = sqlite3VdbeAddOp(v, OP_NewRowid, iDest, 0);
+  }else{
+    addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
+    assert( pDest->autoInc==0 );
+  }
+  sqlite3VdbeAddOp(v, OP_RowData, iSrc, 0);
+  sqlite3VdbeOp3(v, OP_Insert, iDest,
+                    OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND,
+                    pDest->zName, 0);
+  sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1);
+  autoIncEnd(pParse, iDbDest, pDest, counterMem);
+  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
+    for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
+      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
+    }
+    assert( pSrcIdx );
+    sqlite3VdbeAddOp(v, OP_Close, iSrc, 0);
+    sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
+    sqlite3VdbeAddOp(v, OP_Integer, iDbSrc, 0);
+    pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
+    VdbeComment((v, "# %s", pSrcIdx->zName));
+    sqlite3VdbeOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, 
+                   (char*)pKey, P3_KEYINFO_HANDOFF);
+    sqlite3VdbeAddOp(v, OP_Integer, iDbDest, 0);
+    pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
+    VdbeComment((v, "# %s", pDestIdx->zName));
+    sqlite3VdbeOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, 
+                   (char*)pKey, P3_KEYINFO_HANDOFF);
+    addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0);
+    sqlite3VdbeAddOp(v, OP_RowKey, iSrc, 0);
+    if( pDestIdx->onError!=OE_None ){
+      sqlite3VdbeAddOp(v, OP_MemLoad, memRowid, 0);
+      addr2 = sqlite3VdbeAddOp(v, OP_IsUnique, iDest, 0);
+      sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, 
+                    "UNIQUE constraint failed", P3_STATIC);
+      sqlite3VdbeJumpHere(v, addr2);
+    }
+    sqlite3VdbeAddOp(v, OP_IdxInsert, iDest, 1);
+    sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1+1);
+    sqlite3VdbeJumpHere(v, addr1);
+  }
+  sqlite3VdbeJumpHere(v, emptySrcTest);
+  sqlite3VdbeAddOp(v, OP_Close, iSrc, 0);
+  sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
+  if( emptyDestTest ){
+    sqlite3VdbeAddOp(v, OP_Halt, SQLITE_OK, 0);
+    sqlite3VdbeJumpHere(v, emptyDestTest);
+    sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
+    return 0;
+  }else{
+    return 1;
+  }
+}
+#endif /* SQLITE_OMIT_XFER_OPT */
index bc0898f3be676e753bd676e01089e4631488e3a6..67b774bf476031d44a227ec112156edf71414990 100644 (file)
@@ -1,85 +1,98 @@
-/* Hash score: 167 */
+/***** This file contains automatically generated code ******
+**
+** The code in this file has been automatically generated by
+**
+**     $Header$
+**
+** The code in this file implements a function that determines whether
+** or not a given identifier is really an SQL keyword.  The same thing
+** might be implemented more directly using a hand-written hash table.
+** But by using this automatically generated code, the size of the code
+** is substantially reduced.  This is important for embedded applications
+** on platforms with limited memory.
+*/
+/* Hash score: 165 */
 static int keywordCode(const char *z, int n){
-  static const char zText[544] =
+  static const char zText[536] =
     "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER"
     "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYANALYZE"
-    "XCLUSIVEXISTSTATEMENTANDEFERRABLEATTACHAVINGLOBEFOREIGNOREINDEX"
-    "AUTOINCREMENTBEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETE"
-    "CASECASTCOLLATECOLUMNCOMMITCONFLICTCONSTRAINTERSECTCREATECROSS"
-    "CURRENT_DATECURRENT_TIMESTAMPLANDESCDETACHDISTINCTDROPRAGMATCH"
-    "FAILIMITFROMFULLGROUPDATEIFIMMEDIATEINSERTINSTEADINTOFFSETISNULL"
-    "JOINORDEREPLACEOUTERESTRICTPRIMARYQUERYRIGHTROLLBACKROWHENUNION"
-    "UNIQUEUSINGVACUUMVALUESVIEWHEREVIRTUAL";
+    "XCLUSIVEXISTSANDEFERRABLEATTACHAVINGLOBEFOREIGNOREINDEXAUTOINCREMENT"
+    "BEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETECASECASTCOLLATE"
+    "COLUMNCOMMITCONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATECURRENT_TIMESTAMP"
+    "LANDESCDETACHDISTINCTDROPRAGMATCHFAILIMITFROMFULLGROUPDATEIFIMMEDIATE"
+    "INSERTINSTEADINTOFFSETISNULLJOINORDEREPLACEOUTERESTRICTPRIMARY"
+    "QUERYRIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEWHEREVIRTUAL"
+  ;
   static const unsigned char aHash[127] = {
-      92,  80, 107,  91,   0,   4,   0,   0, 114,   0,  83,   0,   0,
-      95,  44,  76,  93,   0, 106, 109,  97,  90,   0,  10,   0,   0,
-     113,   0, 117, 103,   0,  28,  48,   0,  41,   0,   0,  65,  71,
-       0,  63,  19,   0, 105,  36, 104,   0, 108,  74,   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,
-      75,  26,   0,  72,   0,   0,   0,  64,  47,  67,  22,  87,  29,
-      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,
+      91,  79, 106,  90,   0,   4,   0,   0, 113,   0,  82,   0,   0,
+      94,  43,  75,  92,   0, 105, 108,  96,  89,   0,  10,   0,   0,
+     112,   0, 116, 102,   0,  28,  47,   0,  40,   0,   0,  64,  70,
+       0,  62,  19,   0, 104,  35, 103,   0, 107,  73,   0,   0,  33,
+       0,  60,  36,   0,   8,   0, 114,  37,  12,   0,  76,  39,  25,
+      65,   0,   0,  31,  80,  52,  30,  49,  20,  87,   0,  34,   0,
+      74,  26,   0,  71,   0,   0,   0,  63,  46,  66,  22,  86,  29,
+      68,  85,   0,   1,   0,   9, 100,  57,  18,   0, 111,  81,  98,
+      53,   6,  84,   0,   0,  48,  93,   0, 101,   0,  69,   0,   0,
+      15,   0, 115,  50,  55,   0,   2,  54,   0, 110,
   };
-  static const unsigned char aNext[117] = {
+  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,
-       0,   0,   0,   0,   0,   0,   0,  43,   0,   0,   0,   0,   0,
-       0,   0,  16,   0,  23,  52,   0,   0,   0,   0,  45,   0,  59,
-       0,   0,   0,   0,   0,   0,   0,   0,  73,  42,   0,  24,  60,
-      21,   0,  79,   0,   0,  68,   0,   0,  84,  46,   0,   0,   0,
-       0,   0,   0,   0,   0,  39,  96,  98,   0,   0, 100,   0,  32,
-       0,  14,  27,  78,   0,  57,  89,   0,  35,   0,  62,   0, 110,
+       0,  11,   0,   0,   0,   0,   5,  13,   7,   0,   0,   0,   0,
+       0,   0,   0,   0,   0,   0,  42,   0,   0,   0,   0,   0,   0,
+       0,  16,   0,  23,  51,   0,   0,   0,   0,  44,   0,  58,   0,
+       0,   0,   0,   0,   0,   0,   0,  72,  41,   0,  24,  59,  21,
+       0,  78,   0,   0,  67,   0,   0,  83,  45,   0,   0,   0,   0,
+       0,   0,   0,   0,  38,  95,  97,   0,   0,  99,   0,  32,   0,
+      14,  27,  77,   0,  56,  88,   0,   0,   0,  61,   0, 109,
   };
-  static const unsigned char aLen[117] = {
+  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,  12,  17,   4,   4,   6,
-       8,   2,   4,   6,   5,   4,   5,   4,   4,   5,   6,   2,   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,   7,
+       7,   6,   7,   9,   3,   7,   9,   6,   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,  12,  17,   4,   4,   6,   8,
+       2,   4,   6,   5,   4,   5,   4,   4,   5,   6,   2,   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,   7,
   };
-  static const unsigned short int aOffset[117] = {
+  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, 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, 536,
+      99, 105, 108, 113, 118, 122, 128, 136, 142, 144, 154, 159, 164,
+     167, 169, 169, 173, 177, 179, 184, 186, 188, 197, 200, 204, 210,
+     216, 216, 219, 222, 226, 228, 229, 233, 240, 246, 250, 254, 261,
+     267, 273, 281, 288, 297, 303, 308, 320, 320, 336, 340, 344, 350,
+     351, 358, 361, 365, 370, 373, 378, 382, 386, 389, 395, 397, 406,
+     412, 419, 422, 422, 425, 428, 434, 438, 442, 449, 453, 461, 468,
+     473, 478, 486, 488, 492, 497, 503, 508, 514, 520, 523, 528,
   };
-  static const unsigned char aCode[117] = {
+  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,         
     TK_JOIN_KW,    TK_ALTER,      TK_RAISE,      TK_EACH,       TK_CHECK,      
     TK_KEY,        TK_AFTER,      TK_REFERENCES, TK_ESCAPE,     TK_ELSE,       
     TK_EXCEPT,     TK_TRIGGER,    TK_LIKE_KW,    TK_EXPLAIN,    TK_INITIALLY,  
-    TK_ALL,        TK_ANALYZE,    TK_EXCLUSIVE,  TK_EXISTS,     TK_STATEMENT,  
-    TK_AND,        TK_DEFERRABLE, TK_ATTACH,     TK_HAVING,     TK_LIKE_KW,    
-    TK_BEFORE,     TK_FOR,        TK_FOREIGN,    TK_IGNORE,     TK_REINDEX,    
-    TK_INDEX,      TK_AUTOINCR,   TK_TO,         TK_IN,         TK_BEGIN,      
-    TK_JOIN_KW,    TK_RENAME,     TK_BETWEEN,    TK_NOT,        TK_NOTNULL,    
-    TK_NULL,       TK_LIKE_KW,    TK_BY,         TK_CASCADE,    TK_ASC,        
-    TK_DEFERRED,   TK_DELETE,     TK_CASE,       TK_CAST,       TK_COLLATE,    
-    TK_COLUMNKW,   TK_COMMIT,     TK_CONFLICT,   TK_CONSTRAINT, TK_INTERSECT,  
-    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_IF,         
-    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_VIRTUAL,    
+    TK_ALL,        TK_ANALYZE,    TK_EXCLUSIVE,  TK_EXISTS,     TK_AND,        
+    TK_DEFERRABLE, TK_ATTACH,     TK_HAVING,     TK_LIKE_KW,    TK_BEFORE,     
+    TK_FOR,        TK_FOREIGN,    TK_IGNORE,     TK_REINDEX,    TK_INDEX,      
+    TK_AUTOINCR,   TK_TO,         TK_IN,         TK_BEGIN,      TK_JOIN_KW,    
+    TK_RENAME,     TK_BETWEEN,    TK_NOT,        TK_NOTNULL,    TK_NULL,       
+    TK_LIKE_KW,    TK_BY,         TK_CASCADE,    TK_ASC,        TK_DEFERRED,   
+    TK_DELETE,     TK_CASE,       TK_CAST,       TK_COLLATE,    TK_COLUMNKW,   
+    TK_COMMIT,     TK_CONFLICT,   TK_CONSTRAINT, TK_INTERSECT,  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_IF,         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_VIRTUAL,    
   };
   int h, i;
   if( n<2 ) return TK_ID;
index 6af99a6416ed8225173621c531a3b69cf750c341..dc4dc7e28ed8af5b62603d76fd7f8cda2d4a1cee 100644 (file)
@@ -229,6 +229,13 @@ const sqlite3_api_routines sqlite3_apis = {
   *************************************************************************
   */
   sqlite3_overload_function,
+
+  /*
+  ** Added after 3.3.13
+  */
+  sqlite3_prepare_v2,
+  sqlite3_prepare16_v2,
+  sqlite3_clear_bindings,
 };
 
 /*
index c1f8f9ed6f593e5494f4f7b6138302cb2cd3bfeb..9f996136f0ef7c278219f432a7a2bfa61708878f 100644 (file)
 #include "os.h"
 #include <ctype.h>
 
-/*
-** The following constant value is used by the SQLITE_BIGENDIAN and
-** SQLITE_LITTLEENDIAN macros.
-*/
-const int sqlite3one = 1;
-
 /*
 ** The version of the library
 */
@@ -33,6 +27,24 @@ const char sqlite3_version[] = SQLITE_VERSION;
 const char *sqlite3_libversion(void){ return sqlite3_version; }
 int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
 
+/*
+** If the following function pointer is not NULL and if
+** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
+** I/O active are written using this function.  These messages
+** are intended for debugging activity only.
+*/
+void (*sqlite3_io_trace)(const char*, ...) = 0;
+
+/*
+** 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;
+
+
 /*
 ** This is the default collating function named "BINARY" which is always
 ** available.
@@ -128,6 +140,9 @@ int sqlite3_close(sqlite3 *db){
   ** cannot be opened for some reason. So this routine needs to run in
   ** that case. But maybe there should be an extra magic value for the
   ** "failed to open" state.
+  **
+  ** TODO: Coverage tests do not test the case where this condition is
+  ** true. It's hard to see how to cause it without messing with threads.
   */
   if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
     /* printf("DID NOT CLOSE\n"); fflush(stdout); */
@@ -239,7 +254,6 @@ const char *sqlite3ErrStr(int rc){
     case SQLITE_CORRUPT:    z = "database disk image is malformed";      break;
     case SQLITE_FULL:       z = "database or disk is full";              break;
     case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
-    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
     case SQLITE_EMPTY:      z = "table contains no data";                break;
     case SQLITE_SCHEMA:     z = "database schema has changed";           break;
     case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
@@ -722,7 +736,8 @@ int sqlite3BtreeFactory(
 */
 const char *sqlite3_errmsg(sqlite3 *db){
   const char *z;
-  if( !db || sqlite3MallocFailed() ){
+  assert( !sqlite3MallocFailed() );
+  if( !db ){
     return sqlite3ErrStr(SQLITE_NOMEM);
   }
   if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
@@ -761,7 +776,8 @@ const void *sqlite3_errmsg16(sqlite3 *db){
   };
 
   const void *z;
-  if( sqlite3MallocFailed() ){
+  assert( !sqlite3MallocFailed() );
+  if( !db ){
     return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
   }
   if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
@@ -876,6 +892,9 @@ static int openDatabase(
   db->flags |= SQLITE_ShortColNames
 #if SQLITE_DEFAULT_FILE_FORMAT<4
                  | SQLITE_LegacyFileFmt
+#endif
+#ifdef SQLITE_ENABLE_LOAD_EXTENSION
+                 | SQLITE_LoadExtension
 #endif
       ;
   sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
@@ -958,6 +977,16 @@ static int openDatabase(
   }
 #endif
 
+  /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
+  ** mode.  -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
+  ** mode.  Doing nothing at all also makes NORMAL the default.
+  */
+#ifdef SQLITE_DEFAULT_LOCKING_MODE
+  db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
+  sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
+                          SQLITE_DEFAULT_LOCKING_MODE);
+#endif
+
 opendb_out:
   if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
     sqlite3_close(db);
index aa562721ef4d72798ad680685c3e9414ebece38b..d9628521489d2579ebb66a036ac6ada07e005de9 100644 (file)
@@ -61,31 +61,31 @@ const char *const sqlite3OpcodeNames[] = { "?",
  /*  57 */ "Function",
  /*  58 */ "NewRowid",
  /*  59 */ "Blob",
- /*  60 */ "Next",
- /*  61 */ "Or",
- /*  62 */ "And",
+ /*  60 */ "Or",
+ /*  61 */ "And",
+ /*  62 */ "Next",
  /*  63 */ "ForceInt",
  /*  64 */ "ReadCookie",
- /*  65 */ "Halt",
- /*  66 */ "IsNull",
- /*  67 */ "NotNull",
- /*  68 */ "Ne",
- /*  69 */ "Eq",
- /*  70 */ "Gt",
- /*  71 */ "Le",
- /*  72 */ "Lt",
- /*  73 */ "Ge",
- /*  74 */ "Expire",
- /*  75 */ "BitAnd",
- /*  76 */ "BitOr",
- /*  77 */ "ShiftLeft",
- /*  78 */ "ShiftRight",
- /*  79 */ "Add",
- /*  80 */ "Subtract",
- /*  81 */ "Multiply",
- /*  82 */ "Divide",
- /*  83 */ "Remainder",
- /*  84 */ "Concat",
+ /*  65 */ "IsNull",
+ /*  66 */ "NotNull",
+ /*  67 */ "Ne",
+ /*  68 */ "Eq",
+ /*  69 */ "Gt",
+ /*  70 */ "Le",
+ /*  71 */ "Lt",
+ /*  72 */ "Ge",
+ /*  73 */ "Halt",
+ /*  74 */ "BitAnd",
+ /*  75 */ "BitOr",
+ /*  76 */ "ShiftLeft",
+ /*  77 */ "ShiftRight",
+ /*  78 */ "Add",
+ /*  79 */ "Subtract",
+ /*  80 */ "Multiply",
+ /*  81 */ "Divide",
+ /*  82 */ "Remainder",
+ /*  83 */ "Concat",
+ /*  84 */ "Expire",
  /*  85 */ "Negative",
  /*  86 */ "DropIndex",
  /*  87 */ "BitNot",
@@ -126,9 +126,9 @@ const char *const sqlite3OpcodeNames[] = { "?",
  /* 122 */ "MakeRecord",
  /* 123 */ "Variable",
  /* 124 */ "CreateTable",
- /* 125 */ "Insert",
- /* 126 */ "Real",
- /* 127 */ "HexBlob",
+ /* 125 */ "Real",
+ /* 126 */ "HexBlob",
+ /* 127 */ "Insert",
  /* 128 */ "IdxGE",
  /* 129 */ "OpenRead",
  /* 130 */ "IdxRowid",
@@ -139,11 +139,10 @@ const char *const sqlite3OpcodeNames[] = { "?",
  /* 135 */ "NotUsed_135",
  /* 136 */ "NotUsed_136",
  /* 137 */ "NotUsed_137",
- /* 138 */ "NotUsed_138",
- /* 139 */ "ToText",
- /* 140 */ "ToBlob",
- /* 141 */ "ToNumeric",
- /* 142 */ "ToInt",
- /* 143 */ "ToReal",
+ /* 138 */ "ToText",
+ /* 139 */ "ToBlob",
+ /* 140 */ "ToNumeric",
+ /* 141 */ "ToInt",
+ /* 142 */ "ToReal",
 };
 #endif
index 2e18d8342572389452bf1c19a1d9490ac9afb430..f8c0f19fbd76219066cc738d2e068243d84fb0bd 100644 (file)
@@ -3,9 +3,9 @@
 #define OP_NotExists                            1
 #define OP_Dup                                  2
 #define OP_MoveLt                               3
-#define OP_Multiply                            81   /* same as TK_STAR     */
+#define OP_Multiply                            80   /* same as TK_STAR     */
 #define OP_VCreate                              4
-#define OP_BitAnd                              75   /* same as TK_BITAND   */
+#define OP_BitAnd                              74   /* same as TK_BITAND   */
 #define OP_DropTrigger                          5
 #define OP_OpenPseudo                           6
 #define OP_MemInt                               7
@@ -14,9 +14,9 @@
 #define OP_LoadAnalysis                        10
 #define OP_IdxGT                               11
 #define OP_Last                                12
-#define OP_Subtract                            80   /* same as TK_MINUS    */
+#define OP_Subtract                            79   /* same as TK_MINUS    */
 #define OP_MemLoad                             13
-#define OP_Remainder                           83   /* same as TK_REM      */
+#define OP_Remainder                           82   /* same as TK_REM      */
 #define OP_SetCookie                           14
 #define OP_Sequence                            15
 #define OP_Pull                                17
 #define OP_DropTable                           20
 #define OP_MemStore                            21
 #define OP_ContextPush                         22
-#define OP_NotNull                             67   /* same as TK_NOTNULL  */
+#define OP_NotNull                             66   /* same as TK_NOTNULL  */
 #define OP_Rowid                               23
-#define OP_Real                               126   /* same as TK_FLOAT    */
-#define OP_String8                             89   /* same as TK_STRING   */
-#define OP_And                                 62   /* same as TK_AND      */
-#define OP_BitNot                              88   /* same as TK_BITNOT   */
+#define OP_Real                               125   /* same as TK_FLOAT    */
+#define OP_String8                             88   /* same as TK_STRING   */
+#define OP_And                                 61   /* same as TK_AND      */
+#define OP_BitNot                              87   /* same as TK_BITNOT   */
 #define OP_VFilter                             24
 #define OP_NullRow                             25
 #define OP_Noop                                26
 #define OP_VRowid                              27
-#define OP_Ge                                  73   /* same as TK_GE       */
-#define OP_HexBlob                            127   /* same as TK_BLOB     */
+#define OP_Ge                                  72   /* same as TK_GE       */
+#define OP_HexBlob                            126   /* same as TK_BLOB     */
 #define OP_ParseSchema                         28
 #define OP_Statement                           29
 #define OP_CollSeq                             30
 #define OP_ContextPop                          31
-#define OP_ToText                             139   /* same as TK_TO_TEXT  */
+#define OP_ToText                             138   /* same as TK_TO_TEXT  */
 #define OP_MemIncr                             32
 #define OP_MoveGe                              33
-#define OP_Eq                                  69   /* same as TK_EQ       */
-#define OP_ToNumeric                          141   /* same as TK_TO_NUMERIC*/
+#define OP_Eq                                  68   /* same as TK_EQ       */
+#define OP_ToNumeric                          140   /* same as TK_TO_NUMERIC*/
 #define OP_If                                  34
 #define OP_IfNot                               35
-#define OP_ShiftRight                          78   /* same as TK_RSHIFT   */
+#define OP_ShiftRight                          77   /* same as TK_RSHIFT   */
 #define OP_Destroy                             36
 #define OP_Distinct                            37
 #define OP_CreateIndex                         38
 #define OP_SetNumColumns                       39
 #define OP_Not                                 16   /* same as TK_NOT      */
-#define OP_Gt                                  70   /* same as TK_GT       */
+#define OP_Gt                                  69   /* same as TK_GT       */
 #define OP_ResetCount                          40
 #define OP_MakeIdxRec                          41
 #define OP_Goto                                42
 #define OP_AutoCommit                          51
 #define OP_String                              52
 #define OP_FifoWrite                           53
-#define OP_ToInt                              142   /* same as TK_TO_INT   */
+#define OP_ToInt                              141   /* same as TK_TO_INT   */
 #define OP_Return                              54
 #define OP_Callback                            55
 #define OP_AddImm                              56
 #define OP_Function                            57
-#define OP_Concat                              84   /* same as TK_CONCAT   */
+#define OP_Concat                              83   /* same as TK_CONCAT   */
 #define OP_NewRowid                            58
 #define OP_Blob                                59
-#define OP_IsNull                              66   /* same as TK_ISNULL   */
-#define OP_Next                                60
+#define OP_IsNull                              65   /* same as TK_ISNULL   */
+#define OP_Next                                62
 #define OP_ForceInt                            63
 #define OP_ReadCookie                          64
-#define OP_Halt                                65
-#define OP_Expire                              74
-#define OP_Or                                  61   /* same as TK_OR       */
-#define OP_DropIndex                           85
-#define OP_IdxInsert                           87
-#define OP_ShiftLeft                           77   /* same as TK_LSHIFT   */
+#define OP_Halt                                73
+#define OP_Expire                              84
+#define OP_Or                                  60   /* same as TK_OR       */
+#define OP_DropIndex                           86
+#define OP_IdxInsert                           89
+#define OP_ShiftLeft                           76   /* same as TK_LSHIFT   */
 #define OP_FifoRead                            90
 #define OP_Column                              91
 #define OP_Int64                               92
 #define OP_Gosub                               93
 #define OP_IfMemNeg                            94
 #define OP_RowData                             95
-#define OP_BitOr                               76   /* same as TK_BITOR    */
+#define OP_BitOr                               75   /* same as TK_BITOR    */
 #define OP_MemMax                              96
 #define OP_Close                               97
-#define OP_ToReal                             143   /* same as TK_TO_REAL  */
+#define OP_ToReal                             142   /* same as TK_TO_REAL  */
 #define OP_VerifyCookie                        98
 #define OP_IfMemPos                            99
 #define OP_Null                               100
 #define OP_Integer                            101
 #define OP_Transaction                        102
-#define OP_Divide                              82   /* same as TK_SLASH    */
+#define OP_Divide                              81   /* same as TK_SLASH    */
 #define OP_IdxLT                              103
 #define OP_Delete                             104
 #define OP_Rewind                             105
 #define OP_VOpen                              114
 #define OP_AggFinal                           115
 #define OP_OpenWrite                          116
-#define OP_Negative                            86   /* same as TK_UMINUS   */
-#define OP_Le                                  71   /* same as TK_LE       */
+#define OP_Negative                            85   /* same as TK_UMINUS   */
+#define OP_Le                                  70   /* same as TK_LE       */
 #define OP_VNext                              117
 #define OP_AbsValue                           118
 #define OP_Sort                               119
 #define OP_NotFound                           120
 #define OP_MoveLe                             121
 #define OP_MakeRecord                         122
-#define OP_Add                                 79   /* same as TK_PLUS     */
-#define OP_Ne                                  68   /* same as TK_NE       */
+#define OP_Add                                 78   /* same as TK_PLUS     */
+#define OP_Ne                                  67   /* same as TK_NE       */
 #define OP_Variable                           123
 #define OP_CreateTable                        124
-#define OP_Insert                             125
+#define OP_Insert                             127
 #define OP_IdxGE                              128
 #define OP_OpenRead                           129
 #define OP_IdxRowid                           130
-#define OP_ToBlob                             140   /* same as TK_TO_BLOB  */
+#define OP_ToBlob                             139   /* same as TK_TO_BLOB  */
 #define OP_VBegin                             131
 #define OP_TableLock                          132
 #define OP_OpenEphemeral                      133
-#define OP_Lt                                  72   /* same as TK_LT       */
+#define OP_Lt                                  71   /* same as TK_LT       */
 #define OP_Pop                                134
 
 /* The following opcode values are never used */
 #define OP_NotUsed_135                        135
 #define OP_NotUsed_136                        136
 #define OP_NotUsed_137                        137
-#define OP_NotUsed_138                        138
 
 /* Opcodes that are guaranteed to never push a value onto the stack
 ** contain a 1 their corresponding position of the following mask
 #define NOPUSH_MASK_2 0xedaf
 #define NOPUSH_MASK_3 0xf1eb
 #define NOPUSH_MASK_4 0xfffe
-#define NOPUSH_MASK_5 0x61ef
+#define NOPUSH_MASK_5 0x62f7
 #define NOPUSH_MASK_6 0xbfcf
-#define NOPUSH_MASK_7 0x23bf
-#define NOPUSH_MASK_8 0xf87b
+#define NOPUSH_MASK_7 0x83bf
+#define NOPUSH_MASK_8 0x7c7b
 #define NOPUSH_MASK_9 0x0000
index ec482fe0e7c2754eb4a80be142784ba22170eb36..bc65ae32b2e71ed613f1eb075d35271e8fb94205 100644 (file)
@@ -16,6 +16,7 @@
 #define _SQLITE_OS_C_ 1
 #include "sqliteInt.h"
 #include "os.h"
+#undef _SQLITE_OS_C_
 
 /*
 ** The following routines are convenience wrappers around methods
@@ -75,6 +76,10 @@ int sqlite3OsLockState(OsFile *id){
 int sqlite3OsCheckReservedLock(OsFile *id){
   return id->pMethod->xCheckReservedLock(id);
 }
+int sqlite3OsSectorSize(OsFile *id){
+  int (*xSectorSize)(OsFile*) = id->pMethod->xSectorSize;
+  return xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE;
+}
 
 #ifdef SQLITE_ENABLE_REDEF_IO
 /*
index 0fe7b156ee917c7319efcf7ad83d11d56703b64f..006ed5e1311532c94c238aedd19c84f4a798b1d1 100644 (file)
 ** Figure out if we are dealing with Unix, Windows, or some other
 ** operating system.
 */
+#if defined(OS_OTHER)
+# if OS_OTHER==1
+#   undef OS_UNIX
+#   define OS_UNIX 0
+#   undef OS_WIN
+#   define OS_WIN 0
+#   undef OS_OS2
+#   define OS_OS2 0
+# else
+#   undef OS_OTHER
+# endif
+#endif
 #if !defined(OS_UNIX) && !defined(OS_OTHER)
 # define OS_OTHER 0
 # ifndef OS_WIN
 # define SET_FULLSYNC(x,y)
 #endif
 
+/*
+** The default size of a disk sector
+*/
+#ifndef SQLITE_DEFAULT_SECTOR_SIZE
+# define SQLITE_DEFAULT_SECTOR_SIZE 512
+#endif
+
 /*
 ** Temporary files are named starting with this prefix followed by 16 random
 ** alphanumeric characters, and no file extension. They are stored in the
@@ -216,6 +235,7 @@ struct IoMethod {
   int (*xUnlock)(OsFile*, int);
   int (*xLockState)(OsFile *id);
   int (*xCheckReservedLock)(OsFile *id);
+  int (*xSectorSize)(OsFile *id);
 };
 
 /*
@@ -346,6 +366,7 @@ int sqlite3OsFileExists(const char*);
 char *sqlite3OsFullPathname(const char*);
 int sqlite3OsIsDirWritable(char*);
 int sqlite3OsSyncDirectory(const char*);
+int sqlite3OsSectorSize(OsFile *id);
 int sqlite3OsTempFileName(char*);
 int sqlite3OsRandomSeed(char*);
 int sqlite3OsSleep(int ms);
@@ -426,9 +447,12 @@ struct sqlite3OsVtbl {
 #endif
 
 
-#ifdef _SQLITE_OS_C_
+#if defined(_SQLITE_OS_C_) || defined(SQLITE_AMALGAMATION)
   /*
   ** The os.c file implements the global virtual function table.
+  ** We have to put this file here because the initializers
+  ** (ex: sqlite3OsRandomSeed) are macros that are about to be
+  ** redefined.
   */
   struct sqlite3OsVtbl sqlite3Os = {
     IF_DISKIO( sqlite3OsOpenReadWrite ),
index 863e3cde2b727f851210d5d96c58fd8a734fdb29..6aa244f9c81f77271b5204e48eb3f0677148c71a 100644 (file)
@@ -38,25 +38,23 @@ unsigned int sqlite3_pending_byte = 0x40000000;
 
 int sqlite3_os_trace = 0;
 #ifdef SQLITE_DEBUG
-static int last_page = 0;
-#define SEEK(X)           last_page=(X)
-#define TRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
-#define TRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
-#define TRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
-#define TRACE4(X,Y,Z,A)   if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
-#define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
-#define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
-#define TRACE7(X,Y,Z,A,B,C,D) \
+#define OSTRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
+#define OSTRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
+#define OSTRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)   if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C) \
+    if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D) \
     if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
 #else
-#define SEEK(X)
-#define TRACE1(X)
-#define TRACE2(X,Y)
-#define TRACE3(X,Y,Z)
-#define TRACE4(X,Y,Z,A)
-#define TRACE5(X,Y,Z,A,B)
-#define TRACE6(X,Y,Z,A,B,C)
-#define TRACE7(X,Y,Z,A,B,C,D)
+#define OSTRACE1(X)
+#define OSTRACE2(X,Y)
+#define OSTRACE3(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D)
 #endif
 
 /*
@@ -90,19 +88,23 @@ static unsigned int elapse;
 #ifdef SQLITE_TEST
 int sqlite3_io_error_hit = 0;
 int sqlite3_io_error_pending = 0;
+int sqlite3_io_error_persist = 0;
 int sqlite3_diskfull_pending = 0;
 int sqlite3_diskfull = 0;
 #define SimulateIOError(CODE)  \
-   if( sqlite3_io_error_pending ) \
-     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); CODE; }
+  if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \
+     if( sqlite3_io_error_pending-- == 1 \
+         || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \
+                { local_ioerr(); CODE; }
 static void local_ioerr(){
-  sqlite3_io_error_hit = 1;  /* Really just a place to set a breakpoint */
+  sqlite3_io_error_hit = 1;
 }
 #define SimulateDiskfullError(CODE) \
    if( sqlite3_diskfull_pending ){ \
      if( sqlite3_diskfull_pending == 1 ){ \
        local_ioerr(); \
        sqlite3_diskfull = 1; \
+       sqlite3_io_error_hit = 1; \
        CODE; \
      }else{ \
        sqlite3_diskfull_pending--; \
@@ -186,3 +188,10 @@ void sqlite3GenericFree(void *p){
 /* Never actually used, but needed for the linker */
 int sqlite3GenericAllocationSize(void *p){ return 0; }
 #endif
+
+/*
+** The default size of a disk sector
+*/
+#ifndef PAGER_SECTOR_SIZE
+# define PAGER_SECTOR_SIZE 512
+#endif
index 8ac272e5e258c44255a06439d22ea8feac580f7e..281348b79db27349af3cbf058e3dfad3b797b77b 100644 (file)
 ** If we are to be thread-safe, include the pthreads header and define
 ** the SQLITE_UNIX_THREADS macro.
 */
-#if defined(THREADSAFE) && THREADSAFE
+#ifndef THREADSAFE
+# define THREADSAFE 1
+#endif
+#if THREADSAFE
 # include <pthread.h>
 # define SQLITE_UNIX_THREADS 1
 #endif
@@ -457,7 +460,7 @@ static int lockTrace(int fd, int op, struct flock *p){
   sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
      threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
      (int)p->l_pid, s);
-  if( s && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
+  if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
     struct flock l2;
     l2 = *p;
     fcntl(fd, F_GETLK, &l2);
@@ -753,19 +756,20 @@ static int transferOwnership(unixFile *pFile){
   hSelf = pthread_self();
   if( pthread_equal(pFile->tid, hSelf) ){
     /* We are still in the same thread */
-    TRACE1("No-transfer, same thread\n");
+    OSTRACE1("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);
+  OSTRACE4("Transfer ownership of %d from %d to %d\n",
+            pFile->h, pFile->tid, hSelf);
   pFile->tid = hSelf;
   if (pFile->pLock != NULL) {
     releaseLockInfo(pFile->pLock);
     rc = findLockInfo(pFile->h, &pFile->pLock, 0);
-    TRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
+    OSTRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
            locktypeName(pFile->locktype),
            locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
     return rc;
@@ -782,6 +786,7 @@ static int transferOwnership(unixFile *pFile){
 ** Delete the named file
 */
 int sqlite3UnixDelete(const char *zFilename){
+  SimulateIOError(return SQLITE_IOERR_DELETE);
   unlink(zFilename);
   return SQLITE_OK;
 }
@@ -864,7 +869,7 @@ int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
   assert( 0==*pId );
   h = open(zFilename,
                 O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY,
-                SQLITE_DEFAULT_FILE_PERMISSIONS);
+                delFlag ? 0600 : SQLITE_DEFAULT_FILE_PERMISSIONS);
   if( h<0 ){
     return SQLITE_CANTOPEN;
   }
@@ -914,30 +919,17 @@ static int unixOpenDirectory(
   const char *zDirname
 ){
   unixFile *pFile = (unixFile*)id;
-  if( pFile==0 ){
-    /* Do not open the directory if the corresponding file is not already
-    ** open. */
-    return SQLITE_CANTOPEN;
-  }
+  assert( pFile!=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", pFile->dirfd, zDirname);
+  OSTRACE3("OPENDIR %-3d %s\n", pFile->dirfd, zDirname);
   return SQLITE_OK;
 }
 
-/*
-** 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;
-
 /*
 ** Create a temporary file name in zBuf.  zBuf must be big enough to
 ** hold at least SQLITE_TEMPNAME_SIZE characters.
@@ -1001,15 +993,23 @@ int sqlite3UnixIsDirWritable(char *zBuf){
 static int seekAndRead(unixFile *id, void *pBuf, int cnt){
   int got;
   i64 newOffset;
-#ifdef USE_PREAD
+  TIMER_START;
+#if defined(USE_PREAD)
   got = pread(id->h, pBuf, cnt, id->offset);
+  SimulateIOError( got = -1 );
+#elif defined(USE_PREAD64)
+  got = pread64(id->h, pBuf, cnt, id->offset);
+  SimulateIOError( got = -1 );
 #else
   newOffset = lseek(id->h, id->offset, SEEK_SET);
+  SimulateIOError( newOffset-- );
   if( newOffset!=id->offset ){
     return -1;
   }
   got = read(id->h, pBuf, cnt);
 #endif
+  TIMER_END;
+  OSTRACE5("READ    %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED);
   if( got>0 ){
     id->offset += got;
   }
@@ -1024,13 +1024,7 @@ static int seekAndRead(unixFile *id, void *pBuf, int cnt){
 static int unixRead(OsFile *id, void *pBuf, int amt){
   int got;
   assert( id );
-  TIMER_START;
   got = seekAndRead((unixFile*)id, pBuf, amt);
-  TIMER_END;
-  TRACE5("READ    %-3d %5d %7d %d\n", ((unixFile*)id)->h, got,
-          last_page, TIMER_ELAPSED);
-  SEEK(0);
-  SimulateIOError( got = -1 );
   if( got==amt ){
     return SQLITE_OK;
   }else if( got<0 ){
@@ -1048,8 +1042,11 @@ static int unixRead(OsFile *id, void *pBuf, int amt){
 static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){
   int got;
   i64 newOffset;
-#ifdef USE_PREAD
+  TIMER_START;
+#if defined(USE_PREAD)
   got = pwrite(id->h, pBuf, cnt, id->offset);
+#elif defined(USE_PREAD64)
+  got = pwrite64(id->h, pBuf, cnt, id->offset);
 #else
   newOffset = lseek(id->h, id->offset, SEEK_SET);
   if( newOffset!=id->offset ){
@@ -1057,6 +1054,8 @@ static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){
   }
   got = write(id->h, pBuf, cnt);
 #endif
+  TIMER_END;
+  OSTRACE5("WRITE   %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED);
   if( got>0 ){
     id->offset += got;
   }
@@ -1072,15 +1071,10 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
   int wrote = 0;
   assert( id );
   assert( amt>0 );
-  TIMER_START;
   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", ((unixFile*)id)->h, wrote,
-          last_page, TIMER_ELAPSED);
-  SEEK(0);
   SimulateIOError(( wrote=(-1), amt=1 ));
   SimulateDiskfullError(( wrote=0, amt=1 ));
   if( amt>0 ){
@@ -1098,7 +1092,6 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
 */
 static int unixSeek(OsFile *id, i64 offset){
   assert( id );
-  SEEK(offset/1024 + 1);
 #ifdef SQLITE_TEST
   if( offset ) SimulateDiskfullError(return SQLITE_FULL);
 #endif
@@ -1212,14 +1205,14 @@ static int unixSync(OsFile *id, int dataOnly){
   int rc;
   unixFile *pFile = (unixFile*)id;
   assert( pFile );
-  TRACE2("SYNC    %-3d\n", pFile->h);
+  OSTRACE2("SYNC    %-3d\n", pFile->h);
   rc = full_fsync(pFile->h, pFile->fullSync, dataOnly);
   SimulateIOError( rc=1 );
   if( rc ){
     return SQLITE_IOERR_FSYNC;
   }
   if( pFile->dirfd>=0 ){
-    TRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
+    OSTRACE4("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
@@ -1257,7 +1250,7 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
   int fd;
   int r;
   fd = open(zDirname, O_RDONLY|O_BINARY, 0);
-  TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
+  OSTRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
   if( fd<0 ){
     return SQLITE_CANTOPEN; 
   }
@@ -1336,7 +1329,7 @@ static int unixCheckReservedLock(OsFile *id){
   }
   
   sqlite3OsLeaveMutex();
-  TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
+  OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
 
   return r;
 }
@@ -1411,7 +1404,7 @@ static int unixLock(OsFile *id, int locktype){
   int s;
 
   assert( pFile );
-  TRACE7("LOCK    %d %s was %s(%s,%d) pid=%d\n", pFile->h,
+  OSTRACE7("LOCK    %d %s was %s(%s,%d) pid=%d\n", pFile->h,
       locktypeName(locktype), locktypeName(pFile->locktype),
       locktypeName(pLock->locktype), pLock->cnt , getpid());
 
@@ -1420,7 +1413,7 @@ static int unixLock(OsFile *id, int locktype){
   ** sqlite3OsEnterMutex() hasn't been called yet.
   */
   if( pFile->locktype>=locktype ){
-    TRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
+    OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
             locktypeName(locktype));
     return SQLITE_OK;
   }
@@ -1483,7 +1476,7 @@ static int unixLock(OsFile *id, int locktype){
     lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
     lock.l_start = PENDING_BYTE;
     s = fcntl(pFile->h, F_SETLK, &lock);
-    if( s ){
+    if( s==(-1) ){
       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
       goto end_lock;
     }
@@ -1510,7 +1503,7 @@ static int unixLock(OsFile *id, int locktype){
       rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
       goto end_lock;
     }
-    if( s ){
+    if( s==(-1) ){
       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
     }else{
       pFile->locktype = SHARED_LOCK;
@@ -1540,7 +1533,7 @@ static int unixLock(OsFile *id, int locktype){
         assert(0);
     }
     s = fcntl(pFile->h, F_SETLK, &lock);
-    if( s ){
+    if( s==(-1) ){
       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
     }
   }
@@ -1555,7 +1548,7 @@ static int unixLock(OsFile *id, int locktype){
 
 end_lock:
   sqlite3OsLeaveMutex();
-  TRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
+  OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
       rc==SQLITE_OK ? "ok" : "failed");
   return rc;
 }
@@ -1574,7 +1567,7 @@ static int unixUnlock(OsFile *id, int locktype){
   unixFile *pFile = (unixFile*)id;
 
   assert( pFile );
-  TRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
+  OSTRACE7("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 );
@@ -1594,7 +1587,7 @@ static int unixUnlock(OsFile *id, int locktype){
       lock.l_whence = SEEK_SET;
       lock.l_start = SHARED_FIRST;
       lock.l_len = SHARED_SIZE;
-      if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
+      if( fcntl(pFile->h, F_SETLK, &lock)==(-1) ){
         /* This should never happen */
         rc = SQLITE_IOERR_RDLOCK;
       }
@@ -1603,7 +1596,7 @@ static int unixUnlock(OsFile *id, int locktype){
     lock.l_whence = SEEK_SET;
     lock.l_start = PENDING_BYTE;
     lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
-    if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
+    if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){
       pLock->locktype = SHARED_LOCK;
     }else{
       rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
@@ -1621,7 +1614,7 @@ static int unixUnlock(OsFile *id, int locktype){
       lock.l_type = F_UNLCK;
       lock.l_whence = SEEK_SET;
       lock.l_start = lock.l_len = 0L;
-      if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
+      if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){
         pLock->locktype = NO_LOCK;
       }else{
         rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
@@ -1687,7 +1680,7 @@ static int unixClose(OsFile **pId){
 
   sqlite3OsLeaveMutex();
   id->isOpen = 0;
-  TRACE2("CLOSE   %-3d\n", id->h);
+  OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
   sqlite3ThreadSafeFree(id);
   *pId = 0;
@@ -1734,11 +1727,11 @@ static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset,
   pb.offset = offset;
   pb.length = length; 
   pb.fd = fd;
-  TRACE5("AFPLOCK setting lock %s for %d in range %llx:%llx\n", 
+  OSTRACE5("AFPLOCK setting lock %s for %d in range %llx:%llx\n", 
     (setLockFlag?"ON":"OFF"), fd, offset, length);
   err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
   if ( err==-1 ) {
-    TRACE4("AFPLOCK failed to fsctl() '%s' %d %s\n", path, errno, 
+    OSTRACE4("AFPLOCK failed to fsctl() '%s' %d %s\n", path, errno, 
       strerror(errno));
     return 1; // error
   } else {
@@ -1778,7 +1771,7 @@ static int afpUnixCheckReservedLock(OsFile *id){
       _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0);
     }
   }
-  TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
+  OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
   
   return r;
 }
@@ -1793,14 +1786,14 @@ static int afpUnixLock(OsFile *id, int locktype)
   int gotPendingLock = 0;
   
   assert( pFile );
-  TRACE5("LOCK    %d %s was %s pid=%d\n", pFile->h,
+  OSTRACE5("LOCK    %d %s was %s pid=%d\n", pFile->h,
          locktypeName(locktype), locktypeName(pFile->locktype), getpid());  
   /* If there is already a lock of this type or more restrictive on the
     ** OsFile, do nothing. Don't use the afp_end_lock: exit path, as
     ** sqlite3OsEnterMutex() hasn't been called yet.
     */
   if( pFile->locktype>=locktype ){
-    TRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
+    OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
            locktypeName(locktype));
     return SQLITE_OK;
   }
@@ -1907,7 +1900,7 @@ static int afpUnixLock(OsFile *id, int locktype)
   
 afp_end_lock:
     sqlite3OsLeaveMutex();
-  TRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
+  OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
          rc==SQLITE_OK ? "ok" : "failed");
   return rc;
 }
@@ -1926,7 +1919,7 @@ static int afpUnixUnlock(OsFile *id, int locktype) {
   afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
 
   assert( pFile );
-  TRACE5("UNLOCK  %d %d was %d pid=%d\n", pFile->h, locktype,
+  OSTRACE5("UNLOCK  %d %d was %d pid=%d\n", pFile->h, locktype,
          pFile->locktype, getpid());
   
   assert( locktype<=SHARED_LOCK );
@@ -2003,7 +1996,7 @@ static int afpUnixClose(OsFile **pId) {
   id->dirfd = -1;
   close(id->h);
   id->isOpen = 0;
-  TRACE2("CLOSE   %-3d\n", id->h);
+  OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
   sqlite3ThreadSafeFree(id);
   *pId = 0;
@@ -2099,7 +2092,7 @@ static int flockUnixClose(OsFile **pId) {
   close(id->h);  
   sqlite3OsLeaveMutex();
   id->isOpen = 0;
-  TRACE2("CLOSE   %-3d\n", id->h);
+  OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
   sqlite3ThreadSafeFree(id);
   *pId = 0;
@@ -2218,7 +2211,7 @@ static int dotlockUnixClose(OsFile **pId) {
   
   sqlite3OsLeaveMutex();
   id->isOpen = 0;
-  TRACE2("CLOSE   %-3d\n", id->h);
+  OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
   sqlite3ThreadSafeFree(id);
   *pId = 0;
@@ -2260,7 +2253,7 @@ static int nolockUnixClose(OsFile **pId) {
   
   sqlite3OsLeaveMutex();
   id->isOpen = 0;
-  TRACE2("CLOSE   %-3d\n", id->h);
+  OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
   sqlite3ThreadSafeFree(id);
   *pId = 0;
@@ -2341,6 +2334,20 @@ static int unixLockState(OsFile *id){
   return ((unixFile*)id)->locktype;
 }
 
+/*
+** Return the sector size in bytes of the underlying block device for
+** the specified file. This is almost always 512 bytes, but may be
+** larger for some devices.
+**
+** SQLite code assumes this function cannot fail. It also assumes that
+** if two files are created in the same file-system directory (i.e.
+** a database and it's journal file) that the sector size will be the
+** same for both.
+*/
+static int unixSectorSize(OsFile *id){
+  return SQLITE_DEFAULT_SECTOR_SIZE;
+}
+
 /*
 ** This vector defines all the methods that can operate on an OsFile
 ** for unix.
@@ -2360,6 +2367,7 @@ static const IoMethod sqlite3UnixIoMethod = {
   unixUnlock,
   unixLockState,
   unixCheckReservedLock,
+  unixSectorSize,
 };
 
 #ifdef SQLITE_ENABLE_LOCKING_STYLE
@@ -2382,6 +2390,7 @@ static const IoMethod sqlite3AFPLockingUnixIoMethod = {
     afpUnixUnlock,
     unixLockState,
     afpUnixCheckReservedLock,
+    unixSectorSize,
 };
 
 /*
@@ -2403,6 +2412,7 @@ static const IoMethod sqlite3FlockLockingUnixIoMethod = {
     flockUnixUnlock,
     unixLockState,
     flockUnixCheckReservedLock,
+    unixSectorSize,
 };
 
 /*
@@ -2424,6 +2434,7 @@ static const IoMethod sqlite3DotlockLockingUnixIoMethod = {
     dotlockUnixUnlock,
     unixLockState,
     dotlockUnixCheckReservedLock,
+    unixSectorSize,
 };
 
 /*
@@ -2445,6 +2456,7 @@ static const IoMethod sqlite3NolockLockingUnixIoMethod = {
   nolockUnixUnlock,
   unixLockState,
   nolockUnixCheckReservedLock,
+  unixSectorSize,
 };
 
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
@@ -2472,6 +2484,7 @@ static int allocateUnixFile(
   unixFile f;
   int rc;
 
+  memset(&f, 0, sizeof(f));
   lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
   if ( lockingStyle == posixLockingStyle ) {
     sqlite3OsEnterMutex();
@@ -2491,9 +2504,6 @@ static int allocateUnixFile(
     unlink(zFilename);
   }
   f.dirfd = -1;
-  f.fullSync = 0;
-  f.locktype = 0;
-  f.offset = 0;
   f.h = h;
   SET_THREADID(&f);
   pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) );
@@ -2560,6 +2570,7 @@ static int allocateUnixFile(
   unixFile f;
   int rc;
 
+  memset(&f, 0, sizeof(f));
   sqlite3OsEnterMutex();
   rc = findLockInfo(h, &f.pLock, &f.pOpen);
   sqlite3OsLeaveMutex();
@@ -2570,11 +2581,8 @@ static int allocateUnixFile(
     close(h);
     return SQLITE_NOMEM;
   }
-  TRACE3("OPEN    %-3d %s\n", h, zFilename);
+  OSTRACE3("OPEN    %-3d %s\n", h, zFilename);
   f.dirfd = -1;
-  f.fullSync = 0;
-  f.locktype = 0;
-  f.offset = 0;
   f.h = h;
   SET_THREADID(&f);
   pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) );
@@ -2899,8 +2907,7 @@ int sqlite3UnixCurrentTime(double *prNow){
   *prNow = t/86400.0 + 2440587.5;
 #else
   struct timeval sNow;
-  struct timezone sTz;  /* Not used */
-  gettimeofday(&sNow, &sTz);
+  gettimeofday(&sNow, 0);
   *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0;
 #endif
 #ifdef SQLITE_TEST
index 2fcc245709f5a50f6c346fe988b1f288486e10e7..9da53e9feeef6d3f9ccfbba94c546fc5f48f6f68 100644 (file)
@@ -596,6 +596,7 @@ int sqlite3WinDelete(const char *zFilename){
   if( zConverted==0 ){
     return SQLITE_NOMEM;
   }
+  SimulateIOError(return SQLITE_IOERR_DELETE);
   if( isNT() ){
     do{
       rc = DeleteFileW(zConverted);
@@ -612,7 +613,7 @@ int sqlite3WinDelete(const char *zFilename){
 #endif
   }
   sqliteFree(zConverted);
-  TRACE2("DELETE \"%s\"\n", zFilename);
+  OSTRACE2("DELETE \"%s\"\n", zFilename);
   return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
 }
 
@@ -738,7 +739,7 @@ int sqlite3WinOpenReadWrite(
 #if OS_WINCE
   f.zDeleteOnClose = 0;
 #endif
-  TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
+  OSTRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
   return allocateWinFile(&f, pId);
 }
 
@@ -819,7 +820,7 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
     return SQLITE_CANTOPEN;
   }
   f.h = h;
-  TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
+  OSTRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
   return allocateWinFile(&f, pId);
 }
 
@@ -870,7 +871,7 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
   f.zDeleteOnClose = 0;
   f.hMutex = NULL;
 #endif
-  TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
+  OSTRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
   return allocateWinFile(&f, pId);
 }
 
@@ -897,13 +898,6 @@ static int winOpenDirectory(
   return SQLITE_OK;
 }
 
-/*
-** 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.
-*/
-char *sqlite3_temp_directory = 0;
-
 /*
 ** Create a temporary file name in zBuf.  zBuf must be big enough to
 ** hold at least SQLITE_TEMPNAME_SIZE characters.
@@ -955,7 +949,7 @@ int sqlite3WinTempFileName(char *zBuf){
     zBuf[j] = 0;
     if( !sqlite3OsFileExists(zBuf) ) break;
   }
-  TRACE2("TEMP FILENAME: %s\n", zBuf);
+  OSTRACE2("TEMP FILENAME: %s\n", zBuf);
   return SQLITE_OK; 
 }
 
@@ -975,7 +969,7 @@ static int winClose(OsFile **pId){
   int rc = 1;
   if( pId && (pFile = (winFile*)*pId)!=0 ){
     int rc, cnt = 0;
-    TRACE2("CLOSE %d\n", pFile->h);
+    OSTRACE2("CLOSE %d\n", pFile->h);
     do{
       rc = CloseHandle(pFile->h);
     }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
@@ -1002,7 +996,7 @@ static int winRead(OsFile *id, void *pBuf, int amt){
   DWORD got;
   assert( id!=0 );
   SimulateIOError(return SQLITE_IOERR_READ);
-  TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
+  OSTRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
   if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
     return SQLITE_IOERR_READ;
   }
@@ -1024,7 +1018,7 @@ static int winWrite(OsFile *id, const void *pBuf, int amt){
   assert( id!=0 );
   SimulateIOError(return SQLITE_IOERR_READ);
   SimulateDiskfullError(return SQLITE_FULL);
-  TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
+  OSTRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
   assert( amt>0 );
   while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
          && wrote>0 ){
@@ -1055,9 +1049,8 @@ static int winSeek(OsFile *id, i64 offset){
 #ifdef SQLITE_TEST
   if( offset ) SimulateDiskfullError(return SQLITE_FULL);
 #endif
-  SEEK(offset/1024 + 1);
   rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
-  TRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
+  OSTRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
   if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
     return SQLITE_FULL;
   }
@@ -1069,7 +1062,7 @@ static int winSeek(OsFile *id, i64 offset){
 */
 static int winSync(OsFile *id, int dataOnly){
   assert( id!=0 );
-  TRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
+  OSTRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
   if( FlushFileBuffers(((winFile*)id)->h) ){
     return SQLITE_OK;
   }else{
@@ -1092,7 +1085,7 @@ int sqlite3WinSyncDirectory(const char *zDirname){
 static int winTruncate(OsFile *id, i64 nByte){
   LONG upperBits = nByte>>32;
   assert( id!=0 );
-  TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
+  OSTRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
   SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
   SetEndOfFile(((winFile*)id)->h);
@@ -1220,7 +1213,7 @@ static int winLock(OsFile *id, int locktype){
   winFile *pFile = (winFile*)id;
 
   assert( pFile!=0 );
-  TRACE5("LOCK %d %d was %d(%d)\n",
+  OSTRACE5("LOCK %d %d was %d(%d)\n",
           pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
 
   /* If there is already a lock of this type or more restrictive on the
@@ -1250,7 +1243,7 @@ static int winLock(OsFile *id, int locktype){
       /* Try 3 times to get the pending lock.  The pending lock might be
       ** held by another reader process who will release it momentarily.
       */
-      TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
+      OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
       Sleep(1);
     }
     gotPendingLock = res;
@@ -1288,12 +1281,12 @@ static int winLock(OsFile *id, int locktype){
   if( locktype==EXCLUSIVE_LOCK && res ){
     assert( pFile->locktype>=SHARED_LOCK );
     res = unlockReadLock(pFile);
-    TRACE2("unreadlock = %d\n", res);
+    OSTRACE2("unreadlock = %d\n", res);
     res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
     if( res ){
       newLocktype = EXCLUSIVE_LOCK;
     }else{
-      TRACE2("error-code = %d\n", GetLastError());
+      OSTRACE2("error-code = %d\n", GetLastError());
     }
   }
 
@@ -1310,7 +1303,7 @@ static int winLock(OsFile *id, int locktype){
   if( res ){
     rc = SQLITE_OK;
   }else{
-    TRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
+    OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
            locktype, newLocktype);
     rc = SQLITE_BUSY;
   }
@@ -1329,14 +1322,14 @@ static int winCheckReservedLock(OsFile *id){
   assert( pFile!=0 );
   if( pFile->locktype>=RESERVED_LOCK ){
     rc = 1;
-    TRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
+    OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
   }else{
     rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
     if( rc ){
       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
     }
     rc = !rc;
-    TRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
+    OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
   }
   return rc;
 }
@@ -1358,7 +1351,7 @@ static int winUnlock(OsFile *id, int locktype){
   winFile *pFile = (winFile*)id;
   assert( pFile!=0 );
   assert( locktype<=SHARED_LOCK );
-  TRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
+  OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
           pFile->locktype, pFile->sharedLockByte);
   type = pFile->locktype;
   if( type>=EXCLUSIVE_LOCK ){
@@ -1454,6 +1447,20 @@ static int winLockState(OsFile *id){
   return ((winFile*)id)->locktype;
 }
 
+/*
+** Return the sector size in bytes of the underlying block device for
+** the specified file. This is almost always 512 bytes, but may be
+** larger for some devices.
+**
+** SQLite code assumes this function cannot fail. It also assumes that
+** if two files are created in the same file-system directory (i.e.
+** a database and it's journal file) that the sector size will be the
+** same for both.
+*/
+static int winSectorSize(OsFile *id){
+  return SQLITE_DEFAULT_SECTOR_SIZE;
+}
+
 /*
 ** This vector defines all the methods that can operate on an OsFile
 ** for win32.
@@ -1473,6 +1480,7 @@ static const IoMethod sqlite3WinIoMethod = {
   winUnlock,
   winLockState,
   winCheckReservedLock,
+  winSectorSize,
 };
 
 /*
index cb042cf3298f5b70ab25c206c8e8642b04c1468c..a39a43172026f70cb10991a72729a599dd2be64b 100644 (file)
 */
 #if 0
 #define sqlite3DebugPrintf printf
-#define TRACE1(X)       sqlite3DebugPrintf(X)
-#define TRACE2(X,Y)     sqlite3DebugPrintf(X,Y)
-#define TRACE3(X,Y,Z)   sqlite3DebugPrintf(X,Y,Z)
-#define TRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W)
-#define TRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V)
+#define PAGERTRACE1(X)       sqlite3DebugPrintf(X)
+#define PAGERTRACE2(X,Y)     sqlite3DebugPrintf(X,Y)
+#define PAGERTRACE3(X,Y,Z)   sqlite3DebugPrintf(X,Y,Z)
+#define PAGERTRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W)
+#define PAGERTRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V)
 #else
-#define TRACE1(X)
-#define TRACE2(X,Y)
-#define TRACE3(X,Y,Z)
-#define TRACE4(X,Y,Z,W)
-#define TRACE5(X,Y,Z,W,V)
+#define PAGERTRACE1(X)
+#define PAGERTRACE2(X,Y)
+#define PAGERTRACE3(X,Y,Z)
+#define PAGERTRACE4(X,Y,Z,W)
+#define PAGERTRACE5(X,Y,Z,W,V)
 #endif
 
 /*
-** The following two macros are used within the TRACEX() macros above
+** The following two macros are used within the PAGERTRACEX() macros above
 ** to print out file-descriptors. 
 **
 ** PAGERID() takes a pointer to a Pager struct as it's argument. The
 **   PAGER_SYNCED        The pager moves to this state from PAGER_EXCLUSIVE
 **                       after all dirty pages have been written to the
 **                       database file and the file has been synced to
-**                       disk. All that remains to do is to remove the
-**                       journal file and the transaction will be
-**                       committed.
+**                       disk. All that remains to do is to remove or
+**                       truncate the journal file and the transaction 
+**                       will be committed.
 **
 ** The page cache comes up in PAGER_UNLOCK.  The first time a
-** sqlite3pager_get() occurs, the state transitions to PAGER_SHARED.
+** sqlite3PagerGet() occurs, the state transitions to PAGER_SHARED.
 ** After all pages have been released using sqlite_page_unref(),
 ** the state transitions back to PAGER_UNLOCK.  The first time
-** that sqlite3pager_write() is called, the state transitions to
-** PAGER_RESERVED.  (Note that sqlite_page_write() can only be
+** that sqlite3PagerWrite() is called, the state transitions to
+** PAGER_RESERVED.  (Note that sqlite3PagerWrite() can only be
 ** called on an outstanding page which means that the pager must
 ** be in PAGER_SHARED before it transitions to PAGER_RESERVED.)
-** The transition to PAGER_EXCLUSIVE occurs when before any changes
-** are made to the database file.  After an sqlite3pager_rollback()
-** or sqlite_pager_commit(), the state goes back to PAGER_SHARED.
+** PAGER_RESERVED means that there is an open rollback journal.
+** The transition to PAGER_EXCLUSIVE occurs before any changes
+** are made to the database file, though writes to the rollback
+** journal occurs with just PAGER_RESERVED.  After an sqlite3PagerRollback()
+** or sqlite3PagerCommitPhaseTwo(), the state can go back to PAGER_SHARED,
+** or it can stay at PAGER_EXCLUSIVE if we are in exclusive access mode.
 */
 #define PAGER_UNLOCK      0
 #define PAGER_SHARED      1   /* same as SHARED_LOCK */
 ** This header is only visible to this pager module.  The client
 ** code that calls pager sees only the data that follows the header.
 **
-** Client code should call sqlite3pager_write() on a page prior to making
-** any modifications to that page.  The first time sqlite3pager_write()
+** Client code should call sqlite3PagerWrite() on a page prior to making
+** any modifications to that page.  The first time sqlite3PagerWrite()
 ** is called, the original page contents are written into the rollback
 ** journal and PgHdr.inJournal and PgHdr.needSync are set.  Later, once
 ** the journal page has made it onto the disk surface, PgHdr.needSync
 ** database file until the journal pages has been synced to disk and the
 ** PgHdr.needSync has been cleared.
 **
-** The PgHdr.dirty flag is set when sqlite3pager_write() is called and
+** The PgHdr.dirty flag is set when sqlite3PagerWrite() is called and
 ** is cleared again when the page content is written back to the original
 ** database file.
 */
@@ -155,12 +158,10 @@ struct PgHdr {
   PgHdr *pNextHash, *pPrevHash;  /* Hash collision chain for PgHdr.pgno */
   PgHdr *pNextFree, *pPrevFree;  /* Freelist of pages where nRef==0 */
   PgHdr *pNextAll;               /* A list of all pages */
-  PgHdr *pNextStmt, *pPrevStmt;  /* List of pages in the statement journal */
   u8 inJournal;                  /* TRUE if has been written to journal */
-  u8 inStmt;                     /* TRUE if in the statement subjournal */
   u8 dirty;                      /* TRUE if we need to write back changes */
   u8 needSync;                   /* Sync journal before writing this page */
-  u8 alwaysRollback;             /* Disable dont_rollback() for this page */
+  u8 alwaysRollback;             /* Disable DontRollback() for this page */
   short int nRef;                /* Number of users of this page */
   PgHdr *pDirty, *pPrevDirty;    /* Dirty pages */
   u32 notUsed;                   /* Buffer space */
@@ -186,6 +187,8 @@ typedef struct PgHistory PgHistory;
 struct PgHistory {
   u8 *pOrig;     /* Original page text.  Restore to this on a full rollback */
   u8 *pStmt;     /* Text as it was at the beginning of the current statement */
+  PgHdr *pNextStmt, *pPrevStmt;  /* List of pages in the statement journal */
+  u8 inStmt;                     /* TRUE if in the statement subjournal */
 };
 
 /*
@@ -212,12 +215,12 @@ struct PgHistory {
 /*
 ** A open page cache is an instance of the following structure.
 **
-** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, SQLITE_PROTOCOL
+** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or
 ** 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()
+** SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup()
 ** APIs, they may still be used successfully.
 */
 struct Pager {
@@ -236,9 +239,12 @@ struct Pager {
   u8 readOnly;                /* True for a read-only database */
   u8 needSync;                /* True if an fsync() is needed on the journal */
   u8 dirtyCache;              /* True if cached pages have changed */
-  u8 alwaysRollback;          /* Disable dont_rollback() for all pages */
+  u8 alwaysRollback;          /* Disable DontRollback() for all pages */
   u8 memDb;                   /* True to inhibit all file I/O */
   u8 setMaster;               /* True if a m-j name has been written to jrnl */
+  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
+  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
+  u8 changeCountDone;         /* Set after incrementing the change-counter */
   int errCode;                /* One of several kinds of errors */
   int dbSize;                 /* Number of pages in the file */
   int origDbSize;             /* dbSize before the current change */
@@ -272,18 +278,22 @@ struct Pager {
   i64 stmtJSize;              /* Size of journal at stmt_begin() */
   int sectorSize;             /* Assumed sector size during rollback */
 #ifdef SQLITE_TEST
-  int nHit, nMiss, nOvfl;     /* Cache hits, missing, and LRU overflows */
-  int nRead,nWrite;           /* Database pages read/written */
+  int nHit, nMiss;            /* Cache hits and missing */
+  int nRead, nWrite;          /* Database pages read/written */
 #endif
-  void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
-  void (*xReiniter)(void*,int);   /* Call this routine when reloading pages */
+  void (*xDestructor)(DbPage*,int); /* Call this routine when freeing pages */
+  void (*xReiniter)(DbPage*,int);   /* Call this routine when reloading pages */
+#ifdef SQLITE_HAS_CODEC
   void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
   void *pCodecArg;            /* First argument to xCodec() */
+#endif
   int nHash;                  /* Size of the pager hash table */
   PgHdr **aHash;              /* Hash table to map page number to PgHdr */
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   Pager *pNext;               /* Linked list of pagers in this thread */
 #endif
+  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
+  u32 iChangeCount;           /* Db change-counter for which cache is valid */
 };
 
 /*
@@ -348,13 +358,6 @@ static const unsigned char aJournalMagic[] = {
 # define MEMDB pPager->memDb
 #endif
 
-/*
-** The default size of a disk sector
-*/
-#ifndef PAGER_SECTOR_SIZE
-# define PAGER_SECTOR_SIZE 512
-#endif
-
 /*
 ** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
 ** reserved for working around a windows/posix incompatibility). It is
@@ -373,7 +376,7 @@ static const unsigned char aJournalMagic[] = {
 /*
 ** Enable reference count tracking (for debugging) here:
 */
-#ifdef SQLITE_TEST
+#ifdef SQLITE_DEBUG
   int pager3_refinfo_enable = 0;
   static void pager_refinfo(PgHdr *p){
     static int cnt = 0;
@@ -389,6 +392,21 @@ static const unsigned char aJournalMagic[] = {
 # define REFINFO(X)
 #endif
 
+/*
+** Return true if page *pPg has already been written to the statement
+** journal (or statement snapshot has been created, if *pPg is part
+** of an in-memory database).
+*/
+static int pageInStatement(PgHdr *pPg){
+  Pager *pPager = pPg->pPager;
+  if( MEMDB ){
+    return PGHDR_TO_HIST(pPg, pPager)->inStmt;
+  }else{
+    Pgno pgno = pPg->pgno;
+    u8 *a = pPager->aInStmt;
+    return (a && (int)pgno<=pPager->stmtSize && (a[pgno/8] & (1<<(pgno&7))));
+  }
+}
 
 /*
 ** Change the size of the pager hash table to N.  N must be a power
@@ -474,18 +492,17 @@ static u32 retrieve32bits(PgHdr *p, int offset){
 ** 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,
+** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL
 ** the error becomes persistent. All subsequent API calls on this Pager
 ** will immediately return the same error code.
 */
 static int pager_error(Pager *pPager, int rc){
   int rc2 = rc & 0xff;
   assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK );
-  if( 
+  if(
     rc2==SQLITE_FULL ||
     rc2==SQLITE_IOERR ||
-    rc2==SQLITE_CORRUPT ||
-    rc2==SQLITE_PROTOCOL
+    rc2==SQLITE_CORRUPT
   ){
     pPager->errCode = rc;
   }
@@ -634,14 +651,16 @@ static int seekJournalHdr(Pager *pPager){
 */
 static int writeJournalHdr(Pager *pPager){
   char zHeader[sizeof(aJournalMagic)+16];
+  int rc;
 
-  int rc = seekJournalHdr(pPager);
+  if( pPager->stmtHdrOff==0 ){
+    pPager->stmtHdrOff = pPager->journalOff;
+  }
+
+  rc = seekJournalHdr(pPager);
   if( rc ) return rc;
 
   pPager->journalHdr = pPager->journalOff;
-  if( pPager->stmtHdrOff==0 ){
-    pPager->stmtHdrOff = pPager->journalHdr;
-  }
   pPager->journalOff += JOURNAL_HDR_SZ(pPager);
 
   /* FIX ME: 
@@ -662,12 +681,14 @@ static int writeJournalHdr(Pager *pPager){
   put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize);
   /* The assumed sector size for this process */
   put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
+  IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader)))
   rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader));
 
   /* The journal header has been written successfully. Seek the journal
   ** file descriptor to the end of the journal header sector.
   */
   if( rc==SQLITE_OK ){
+    IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1))
     rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff-1);
     if( rc==SQLITE_OK ){
       rc = sqlite3OsWrite(pPager->jfd, "\000", 1);
@@ -802,38 +823,23 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
 ** statement journal.
 **
 ** The Pager keeps a separate list of pages that are currently in
-** the statement journal.  This helps the sqlite3pager_stmt_commit()
+** the statement journal.  This helps the sqlite3PagerStmtCommit()
 ** routine run MUCH faster for the common case where there are many
 ** pages in memory but only a few are in the statement journal.
 */
 static void page_add_to_stmt_list(PgHdr *pPg){
   Pager *pPager = pPg->pPager;
-  if( pPg->inStmt ) return;
-  assert( pPg->pPrevStmt==0 && pPg->pNextStmt==0 );
-  pPg->pPrevStmt = 0;
-  if( pPager->pStmt ){
-    pPager->pStmt->pPrevStmt = pPg;
-  }
-  pPg->pNextStmt = pPager->pStmt;
-  pPager->pStmt = pPg;
-  pPg->inStmt = 1;
-}
-static void page_remove_from_stmt_list(PgHdr *pPg){
-  if( !pPg->inStmt ) return;
-  if( pPg->pPrevStmt ){
-    assert( pPg->pPrevStmt->pNextStmt==pPg );
-    pPg->pPrevStmt->pNextStmt = pPg->pNextStmt;
-  }else{
-    assert( pPg->pPager->pStmt==pPg );
-    pPg->pPager->pStmt = pPg->pNextStmt;
-  }
-  if( pPg->pNextStmt ){
-    assert( pPg->pNextStmt->pPrevStmt==pPg );
-    pPg->pNextStmt->pPrevStmt = pPg->pPrevStmt;
+  PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+  assert( MEMDB );
+  if( !pHist->inStmt ){
+    assert( pHist->pPrevStmt==0 && pHist->pNextStmt==0 );
+    if( pPager->pStmt ){
+      PGHDR_TO_HIST(pPager->pStmt, pPager)->pPrevStmt = pPg;
+    }
+    pHist->pNextStmt = pPager->pStmt;
+    pPager->pStmt = pPg;
+    pHist->inStmt = 1;
   }
-  pPg->pNextStmt = 0;
-  pPg->pPrevStmt = 0;
-  pPg->inStmt = 0;
 }
 
 /*
@@ -852,23 +858,38 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
 
 /*
 ** Unlock the database file.
-**
-** Once all locks have been removed from the database file, other
-** processes or threads might change the file.  So make sure all of
-** our internal cache is invalidated.
 */
 static void pager_unlock(Pager *pPager){
-  if( !MEMDB ){
-    sqlite3OsUnlock(pPager->fd, NO_LOCK);
-    pPager->dbSize = -1;
+  if( !pPager->exclusiveMode ){
+    if( !MEMDB ){
+      sqlite3OsUnlock(pPager->fd, NO_LOCK);
+      pPager->dbSize = -1;
+      IOTRACE(("UNLOCK %p\n", pPager))
+    }
+    pPager->state = PAGER_UNLOCK;
+    pPager->changeCountDone = 0;
   }
-  pPager->state = PAGER_UNLOCK;
-  assert( pPager->pAll==0 );
+}
+
+/*
+** Execute a rollback if a transaction is active and unlock the 
+** database file. This is a no-op if the pager has already entered
+** the error-state.
+*/
+static void pagerUnlockAndRollback(Pager *p){
+  if( p->errCode ) return;
+  assert( p->state>=PAGER_RESERVED || p->journalOpen==0 );
+  if( p->state>=PAGER_RESERVED ){
+    sqlite3PagerRollback(p);
+  }
+  pager_unlock(p);
+  assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) );
+  assert( p->errCode || !p->stmtOpen || p->exclusiveMode );
 }
 
 
 /*
-** Unlock the database and clear the in-memory cache.  This routine
+** Clear the in-memory cache.  This routine
 ** sets the state of the pager back to what it was when it was first
 ** opened.  Any outstanding pages are invalidated and subsequent attempts
 ** to access those pages will likely result in a coredump.
@@ -880,6 +901,7 @@ static void pager_reset(Pager *pPager){
     pNext = pPg->pNextAll;
     sqliteFree(pPg);
   }
+  pPager->pStmt = 0;
   pPager->pFirst = 0;
   pPager->pFirstSynced = 0;
   pPager->pLast = 0;
@@ -888,46 +910,59 @@ static void pager_reset(Pager *pPager){
   sqliteFree(pPager->aHash);
   pPager->nPage = 0;
   pPager->aHash = 0;
-  if( pPager->state>=PAGER_RESERVED ){
-    sqlite3pager_rollback(pPager);
-  }
-  pager_unlock(pPager);
   pPager->nRef = 0;
-  assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
 }
 
 /*
+** This routine ends a transaction.  A transaction is ended by either
+** a COMMIT or a ROLLBACK.
+**
 ** 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
-** file is deleted and closed.
+** a RESERVED or EXCLUSIVE lock on the database.  This routine will release
+** the database lock and acquires a SHARED lock in its place if that is
+** the appropriate thing to do.  Release locks usually is appropriate,
+** unless we are in exclusive access mode or unless this is a 
+** COMMIT AND BEGIN or ROLLBACK AND BEGIN operation.
+**
+** The journal file is either deleted or truncated.
 **
 ** TODO: Consider keeping the journal file open for temporary databases.
 ** This might give a performance improvement on windows where opening
 ** a file is an expensive operation.
 */
-static int pager_unwritelock(Pager *pPager){
+static int pager_end_transaction(Pager *pPager){
   PgHdr *pPg;
-  int rc;
+  int rc = SQLITE_OK;
+  int rc2 = SQLITE_OK;
   assert( !MEMDB );
   if( pPager->state<PAGER_RESERVED ){
     return SQLITE_OK;
   }
-  sqlite3pager_stmt_commit(pPager);
-  if( pPager->stmtOpen ){
+  sqlite3PagerStmtCommit(pPager);
+  if( pPager->stmtOpen && !pPager->exclusiveMode ){
     sqlite3OsClose(&pPager->stfd);
     pPager->stmtOpen = 0;
   }
   if( pPager->journalOpen ){
-    sqlite3OsClose(&pPager->jfd);
-    pPager->journalOpen = 0;
-    sqlite3OsDelete(pPager->zJournal);
+    if( pPager->exclusiveMode 
+          && (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){;
+      sqlite3OsSeek(pPager->jfd, 0);
+      pPager->journalOff = 0;
+      pPager->journalStarted = 0;
+    }else{
+      sqlite3OsClose(&pPager->jfd);
+      pPager->journalOpen = 0;
+      if( rc==SQLITE_OK ){
+        rc = sqlite3OsDelete(pPager->zJournal);
+      }
+    }
     sqliteFree( pPager->aInJournal );
     pPager->aInJournal = 0;
     for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
       pPg->inJournal = 0;
       pPg->dirty = 0;
       pPg->needSync = 0;
+      pPg->alwaysRollback = 0;
 #ifdef SQLITE_CHECK_PAGES
       pPg->pageHash = pager_pagehash(pPg);
 #endif
@@ -939,14 +974,20 @@ static int pager_unwritelock(Pager *pPager){
     assert( pPager->aInJournal==0 );
     assert( pPager->dirtyCache==0 || pPager->useJournal==0 );
   }
-  rc = sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
-  pPager->state = PAGER_SHARED;
+
+  if( !pPager->exclusiveMode ){
+    rc2 = sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
+    pPager->state = PAGER_SHARED;
+  }else if( pPager->state==PAGER_SYNCED ){
+    pPager->state = PAGER_EXCLUSIVE;
+  }
   pPager->origDbSize = 0;
   pPager->setMaster = 0;
   pPager->needSync = 0;
   pPager->pFirstSynced = pPager->pFirst;
   pPager->dbSize = -1;
-  return rc;
+
+  return (rc==SQLITE_OK?rc2:rc);
 }
 
 /*
@@ -995,17 +1036,17 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
   PgHdr *pPg;                   /* An existing page in the cache */
   Pgno pgno;                    /* The page number of a page in journal */
   u32 cksum;                    /* Checksum used for sanity checking */
-  u8 aData[SQLITE_MAX_PAGE_SIZE];  /* Temp storage for a page */
+  u8 *aData = (u8 *)pPager->pTmpSpace;   /* Temp storage for a page */
 
   /* 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( aData );
 
   rc = read32bits(jfd, &pgno);
   if( rc!=SQLITE_OK ) return rc;
-  rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
+  rc = sqlite3OsRead(jfd, aData, pPager->pageSize);
   if( rc!=SQLITE_OK ) return rc;
   pPager->journalOff += pPager->pageSize + 4;
 
@@ -1053,7 +1094,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
   */
   pPg = pager_lookup(pPager, pgno);
   assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 );
-  TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno);
+  PAGERTRACE3("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);
     if( rc==SQLITE_OK ){
@@ -1068,19 +1109,24 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
     ** for page 1 which is held in use in order to keep the lock on the
     ** database active. However such a page may be rolled back as a result
     ** of an internal error resulting in an automatic call to
-    ** sqlite3pager_rollback().
+    ** sqlite3PagerRollback().
     */
     void *pData;
     /* assert( pPg->nRef==0 || pPg->pgno==1 ); */
     pData = PGHDR_TO_DATA(pPg);
     memcpy(pData, aData, pPager->pageSize);
-    if( pPager->xDestructor ){  /*** FIX ME:  Should this be xReinit? ***/
-      pPager->xDestructor(pData, pPager->pageSize);
+    if( pPager->xReiniter ){
+      pPager->xReiniter(pPg, pPager->pageSize);
     }
 #ifdef SQLITE_CHECK_PAGES
     pPg->pageHash = pager_pagehash(pPg);
 #endif
     CODEC1(pPager, pData, pPg->pgno, 3);
+
+    /* If this was page 1, then restore the value of Pager.iChangeCount */
+    if( pgno==1 ){
+      pPager->iChangeCount = retrieve32bits(pPg, 24);
+    }
   }
   return rc;
 }
@@ -1107,6 +1153,7 @@ static int pager_delmaster(const char *zMaster){
   ** is running this routine also. Not that it makes too much difference.
   */
   rc = sqlite3OsOpenReadOnly(zMaster, &master);
+  assert( rc!=SQLITE_OK || master );
   if( rc!=SQLITE_OK ) goto delmaster_out;
   master_open = 1;
   rc = sqlite3OsFileSize(master, &nMasterJournal);
@@ -1138,6 +1185,7 @@ static int pager_delmaster(const char *zMaster){
         int c;
 
         rc = sqlite3OsOpenReadOnly(zJournal, &journal);
+        assert( rc!=SQLITE_OK || journal );
         if( rc!=SQLITE_OK ){
           goto delmaster_out;
         }
@@ -1159,7 +1207,7 @@ static int pager_delmaster(const char *zMaster){
     }
   }
   
-  sqlite3OsDelete(zMaster);
+  rc = sqlite3OsDelete(zMaster);
 
 delmaster_out:
   if( zMasterJournal ){
@@ -1171,6 +1219,7 @@ delmaster_out:
   return rc;
 }
 
+#if 0
 /*
 ** Make every page in the cache agree with what is on disk.  In other words,
 ** reread the disk to reset the state of the cache.
@@ -1184,14 +1233,14 @@ static int pager_reload_cache(Pager *pPager){
   PgHdr *pPg;
   int rc = SQLITE_OK;
   for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
-    char zBuf[SQLITE_MAX_PAGE_SIZE];
+    char *zBuf = pPager->pTmpSpace;        /* Temp storage for one page */
     if( !pPg->dirty ) continue;
     if( (int)pPg->pgno <= pPager->origDbSize ){
       rc = sqlite3OsSeek(pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));
       if( rc==SQLITE_OK ){
         rc = sqlite3OsRead(pPager->fd, zBuf, pPager->pageSize);
       }
-      TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
+      PAGERTRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
       if( rc ) break;
       CODEC1(pPager, zBuf, pPg->pgno, 2);
     }else{
@@ -1200,7 +1249,7 @@ static int pager_reload_cache(Pager *pPager){
     if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
       memcpy(PGHDR_TO_DATA(pPg), zBuf, pPager->pageSize);
       if( pPager->xReiniter ){
-        pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize);
+        pPager->xReiniter(pPg, pPager->pageSize);
       }else{
         memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
       }
@@ -1214,14 +1263,24 @@ static int pager_reload_cache(Pager *pPager){
   pPager->pDirty = 0;
   return rc;
 }
+#endif
+
+static void pager_truncate_cache(Pager *pPager);
 
 /*
 ** Truncate the main file of the given pager to the number of pages
-** indicated.
+** indicated. Also truncate the cached representation of the file.
 */
 static int pager_truncate(Pager *pPager, int nPage){
-  assert( pPager->state>=PAGER_EXCLUSIVE );
-  return sqlite3OsTruncate(pPager->fd, pPager->pageSize*(i64)nPage);
+  int rc = SQLITE_OK;
+  if( pPager->state>=PAGER_EXCLUSIVE ){
+    rc = sqlite3OsTruncate(pPager->fd, pPager->pageSize*(i64)nPage);
+  }
+  if( rc==SQLITE_OK ){
+    pPager->dbSize = nPage;
+    pager_truncate_cache(pPager);
+  }
+  return rc;
 }
 
 /*
@@ -1277,7 +1336,7 @@ static int pager_truncate(Pager *pPager, int nPage){
 ** If an I/O or malloc() error occurs, the journal-file is not deleted
 ** and an error code is returned.
 */
-static int pager_playback(Pager *pPager){
+static int pager_playback(Pager *pPager, int isHot){
   i64 szJ;                 /* Size of the journal file in bytes */
   u32 nRec;                /* Number of Records in the journal */
   int i;                   /* Loop counter */
@@ -1290,7 +1349,7 @@ static int pager_playback(Pager *pPager){
   */
   assert( pPager->journalOpen );
   rc = sqlite3OsFileSize(pPager->jfd, &szJ);
-  if( rc!=SQLITE_OK ){
+  if( rc!=SQLITE_OK || szJ==0 ){
     goto end_playback;
   }
 
@@ -1337,17 +1396,22 @@ static int pager_playback(Pager *pPager){
       nRec = (szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager);
     }
 
+    /* If nRec is 0 and this rollback is of a transaction created by this
+    ** process. In this case the rest of the journal file consists of
+    ** journalled copies of pages that need to be read back into the cache.
+    */
+    if( nRec==0 && !isHot ){
+      nRec = (szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager);
+    }
+
     /* If this is the first header read from the journal, truncate the
     ** database file back to it's original size.
     */
-    if( pPager->state>=PAGER_EXCLUSIVE && 
-        pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
-      assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
+    if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
       rc = pager_truncate(pPager, mxPg);
       if( rc!=SQLITE_OK ){
         goto end_playback;
       }
-      pPager->dbSize = mxPg;
     }
 
     /* Copy original pages out of the journal and back into the database file.
@@ -1360,10 +1424,6 @@ static int pager_playback(Pager *pPager){
           pPager->journalOff = szJ;
           break;
         }else{
-          /* If we are unable to rollback a hot journal, then the database
-          ** is probably not recoverable.  Return CORRUPT.
-          */
-          rc = SQLITE_CORRUPT;
           goto end_playback;
         }
       }
@@ -1374,10 +1434,10 @@ static int pager_playback(Pager *pPager){
 
 end_playback:
   if( rc==SQLITE_OK ){
-    rc = pager_unwritelock(pPager);
+    rc = pager_end_transaction(pPager);
   }
   if( zMaster ){
-    /* If there was a master journal and this routine will return true,
+    /* If there was a master journal and this routine will return success,
     ** see if it is possible to delete the master journal.
     */
     if( rc==SQLITE_OK ){
@@ -1387,10 +1447,10 @@ end_playback:
   }
 
   /* The Pager.sectorSize variable may have been updated while rolling
-  ** back a journal created by a process with a different PAGER_SECTOR_SIZE
+  ** back a journal created by a process with a different sector size
   ** value. Reset it to the correct value for this process.
   */
-  pPager->sectorSize = PAGER_SECTOR_SIZE;
+  pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
   return rc;
 }
 
@@ -1425,8 +1485,9 @@ static int pager_stmt_playback(Pager *pPager){
   }
 #endif
 
-  /* Set hdrOff to be the offset to the first journal header written
-  ** this statement transaction, or the end of the file if no journal
+  /* Set hdrOff to be the offset just after the end of the last journal
+  ** page written before the first journal-header for this statement
+  ** transaction was written, or the end of the file if no journal
   ** header was written.
   */
   hdrOff = pPager->stmtHdrOff;
@@ -1437,11 +1498,8 @@ static int pager_stmt_playback(Pager *pPager){
   
   /* Truncate the database back to its original size.
   */
-  if( pPager->state>=PAGER_EXCLUSIVE ){
-    rc = pager_truncate(pPager, pPager->stmtSize);
-  }
+  rc = pager_truncate(pPager, pPager->stmtSize);
   assert( pPager->state>=PAGER_SHARED );
-  pPager->dbSize = pPager->stmtSize;
 
   /* Figure out how many records are in the statement journal.
   */
@@ -1474,8 +1532,7 @@ static int pager_stmt_playback(Pager *pPager){
   }
   pPager->journalOff = pPager->stmtJSize;
   pPager->cksumInit = pPager->stmtCksum;
-  assert( JOURNAL_HDR_SZ(pPager)<(pPager->pageSize+8) );
-  while( pPager->journalOff <= (hdrOff-(pPager->pageSize+8)) ){
+  while( pPager->journalOff < hdrOff ){
     rc = pager_playback_one_page(pPager, pPager->jfd, 1);
     assert( rc!=SQLITE_DONE );
     if( rc!=SQLITE_OK ) goto end_stmt_playback;
@@ -1512,7 +1569,7 @@ end_stmt_playback:
 /*
 ** Change the maximum number of in-memory pages that are allowed.
 */
-void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
+void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
   if( mxPage>10 ){
     pPager->mxPage = mxPage;
   }else{
@@ -1547,7 +1604,7 @@ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
 ** and FULL=3.
 */
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
-void sqlite3pager_set_safety_level(Pager *pPager, int level, int full_fsync){
+void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int full_fsync){
   pPager->noSync =  level==1 || pPager->tempFile;
   pPager->fullSync = level==3 && !pPager->tempFile;
   pPager->full_fsync = full_fsync;
@@ -1565,17 +1622,19 @@ int sqlite3_opentemp_count = 0;
 #endif
 
 /*
-** Open a temporary file.  Write the name of the file into zFile
-** (zFile must be at least SQLITE_TEMPNAME_SIZE bytes long.)  Write
-** the file descriptor into *fd.  Return SQLITE_OK on success or some
+** Open a temporary file. 
+**
+** Write the file descriptor into *fd.  Return SQLITE_OK on success or some
 ** other error code if we fail.
 **
 ** The OS will automatically delete the temporary file when it is
 ** closed.
 */
-static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){
+static int sqlite3PagerOpentemp(OsFile **pFd){
   int cnt = 8;
   int rc;
+  char zFile[SQLITE_TEMPNAME_SIZE];
+
 #ifdef SQLITE_TEST
   sqlite3_opentemp_count++;  /* Used for testing and analysis only */
 #endif
@@ -1583,6 +1642,7 @@ static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){
     cnt--;
     sqlite3OsTempFileName(zFile);
     rc = sqlite3OsOpenExclusive(zFile, pFd, 1);
+    assert( rc!=SQLITE_OK || *pFd );
   }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
   return rc;
 }
@@ -1590,8 +1650,8 @@ static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){
 /*
 ** Create a new page cache and put a pointer to the page cache in *ppPager.
 ** The file to be cached need not exist.  The file is not locked until
-** the first call to sqlite3pager_get() and is only held open until the
-** last page is released using sqlite3pager_unref().
+** the first call to sqlite3PagerGet() and is only held open until the
+** last page is released using sqlite3PagerUnref().
 **
 ** If zFilename is NULL then a randomly-named temporary file is created
 ** and used as the file to be cached.  The file will be deleted
@@ -1601,7 +1661,7 @@ static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){
 ** It is never written to disk.  This can be used to implement an
 ** in-memory database.
 */
-int sqlite3pager_open(
+int sqlite3PagerOpen(
   Pager **ppPager,         /* Return the Pager structure here */
   const char *zFilename,   /* Name of the database file to open */
   int nExtra,              /* Extra bytes append to each in-memory page */
@@ -1610,7 +1670,7 @@ int sqlite3pager_open(
   Pager *pPager = 0;
   char *zFullPathname = 0;
   int nameLen;  /* Compiler is wrong. This is always initialized before use */
-  OsFile *fd;
+  OsFile *fd = 0;
   int rc = SQLITE_OK;
   int i;
   int tempFile = 0;
@@ -1631,15 +1691,13 @@ int sqlite3pager_open(
   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. 
+  /* We used to test if malloc() had already failed before proceeding. 
+  ** But the way this function is used in SQLite means that can never
+  ** happen. Furthermore, if the malloc-failed flag is already set, 
+  ** either the call to sqliteStrDup() or sqliteMalloc() below will
+  ** fail shortly and SQLITE_NOMEM returned anyway.
   */
   *ppPager = 0;
-  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).
@@ -1655,10 +1713,12 @@ int sqlite3pager_open(
       zFullPathname = sqlite3OsFullPathname(zFilename);
       if( zFullPathname ){
         rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
+        assert( rc!=SQLITE_OK || fd );
       }
     }
   }else{
-    rc = sqlite3pager_opentemp(zTemp, &fd);
+    rc = sqlite3PagerOpentemp(&fd);
+    sqlite3OsTempFileName(zTemp);
     zFilename = zTemp;
     zFullPathname = sqlite3OsFullPathname(zFilename);
     if( rc==SQLITE_OK ){
@@ -1673,21 +1733,26 @@ int sqlite3pager_open(
   if( zFullPathname ){
     nameLen = strlen(zFullPathname);
     pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
+    if( pPager && rc==SQLITE_OK ){
+      pPager->pTmpSpace = (char *)sqliteMallocRaw(SQLITE_DEFAULT_PAGE_SIZE);
+    }
   }
 
+
   /* 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 ){
+  if( !pPager || !zFullPathname || !pPager->pTmpSpace || rc!=SQLITE_OK ){
     sqlite3OsClose(&fd);
     sqliteFree(zFullPathname);
     sqliteFree(pPager);
     return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
   }
 
-  TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
+  PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
+  IOTRACE(("OPEN %p %s\n", pPager, zFullPathname))
   pPager->zFilename = (char*)&pPager[1];
   pPager->zDirectory = &pPager->zFilename[nameLen+1];
   pPager->zJournal = &pPager->zDirectory[nameLen+1];
@@ -1717,6 +1782,10 @@ int sqlite3pager_open(
   /* pPager->state = PAGER_UNLOCK; */
   /* pPager->errMask = 0; */
   pPager->tempFile = tempFile;
+  assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
+          || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
+  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
+  pPager->exclusiveMode = tempFile; 
   pPager->memDb = memDb;
   pPager->readOnly = readOnly;
   /* pPager->needSync = 0; */
@@ -1726,7 +1795,10 @@ int sqlite3pager_open(
   /* pPager->pFirstSynced = 0; */
   /* pPager->pLast = 0; */
   pPager->nExtra = FORCE_ALIGNMENT(nExtra);
-  pPager->sectorSize = PAGER_SECTOR_SIZE;
+  assert(fd||memDb);
+  if( !memDb ){
+    pPager->sectorSize = sqlite3OsSectorSize(fd);
+  }
   /* pPager->pBusyHandler = 0; */
   /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
   *ppPager = pPager;
@@ -1740,7 +1812,7 @@ int sqlite3pager_open(
 /*
 ** Set the busy handler function.
 */
-void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
+void sqlite3PagerSetBusyhandler(Pager *pPager, BusyHandler *pBusyHandler){
   pPager->pBusyHandler = pBusyHandler;
 }
 
@@ -1749,10 +1821,10 @@ void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
 ** when the reference count on each page reaches zero.  The destructor can
 ** be used to clean up information in the extra segment appended to each page.
 **
-** The destructor is not called as a result sqlite3pager_close().  
-** Destructors are only called by sqlite3pager_unref().
+** The destructor is not called as a result sqlite3PagerClose().  
+** Destructors are only called by sqlite3PagerUnref().
 */
-void sqlite3pager_set_destructor(Pager *pPager, void (*xDesc)(void*,int)){
+void sqlite3PagerSetDestructor(Pager *pPager, void (*xDesc)(DbPage*,int)){
   pPager->xDestructor = xDesc;
 }
 
@@ -1763,7 +1835,7 @@ void sqlite3pager_set_destructor(Pager *pPager, void (*xDesc)(void*,int)){
 ** an opportunity to restore the EXTRA section to agree with the restored
 ** page data.
 */
-void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
+void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*,int)){
   pPager->xReiniter = xReinit;
 }
 
@@ -1772,10 +1844,12 @@ void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
 ** size is inappropriate, then an alternative page size is selected
 ** and returned.
 */
-int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
+int sqlite3PagerSetPagesize(Pager *pPager, int pageSize){
   assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
-  if( !pPager->memDb ){
+  if( !pPager->memDb && pPager->nRef==0 ){
+    pager_reset(pPager);
     pPager->pageSize = pageSize;
+    pPager->pTmpSpace = sqlite3ReallocOrFree(pPager->pTmpSpace, pageSize);
   }
   return pPager->pageSize;
 }
@@ -1792,9 +1866,6 @@ int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
 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;
@@ -1803,7 +1874,6 @@ 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
@@ -1818,13 +1888,14 @@ void enable_simulated_io_errors(void){
 ** 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).
 */
-int sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
+int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
   int rc = SQLITE_OK;
   memset(pDest, 0, N);
   if( MEMDB==0 ){
     disable_simulated_io_errors();
     sqlite3OsSeek(pPager->fd, 0);
     enable_simulated_io_errors();
+    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
     rc = sqlite3OsRead(pPager->fd, pDest, N);
     if( rc==SQLITE_IOERR_SHORT_READ ){
       rc = SQLITE_OK;
@@ -1842,10 +1913,13 @@ int sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
 ** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
 ** file is 4096 bytes, 5 is returned instead of 4.
 */
-int sqlite3pager_pagecount(Pager *pPager){
+int sqlite3PagerPagecount(Pager *pPager){
   i64 n;
   int rc;
   assert( pPager!=0 );
+  if( pPager->errCode ){
+    return 0;
+  }
   if( pPager->dbSize>=0 ){
     n = pPager->dbSize;
   } else {
@@ -1891,7 +1965,7 @@ static int syncJournal(Pager*);
 /*
 ** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate
 ** that the page is not part of any hash chain. This is required because the
-** sqlite3pager_movepage() routine can leave a page in the 
+** sqlite3PagerMovepage() routine can leave a page in the 
 ** pNextFree/pPrevFree list that is not a part of any hash-chain.
 */
 static void unlinkHashChain(Pager *pPager, PgHdr *pPg){
@@ -1949,13 +2023,19 @@ static void unlinkPage(PgHdr *pPg){
   unlinkHashChain(pPager, pPg);
 }
 
-#ifndef SQLITE_OMIT_MEMORYDB
 /*
-** This routine is used to truncate an in-memory database.  Delete
-** all pages whose pgno is larger than pPager->dbSize and is unreferenced.
+** This routine is used to truncate the cache when a database
+** is truncated.  Drop from the cache all pages whose pgno is
+** larger than pPager->dbSize and is unreferenced.
+**
 ** Referenced pages larger than pPager->dbSize are zeroed.
+**
+** Actually, at the point this routine is called, it would be
+** an error to have a referenced page.  But rather than delete
+** that page and guarantee a subsequent segfault, it seems better
+** to zero it and hope that we error out sanely.
 */
-static void memoryTruncate(Pager *pPager){
+static void pager_truncate_cache(Pager *pPager){
   PgHdr *pPg;
   PgHdr **ppPg;
   int dbSize = pPager->dbSize;
@@ -1976,9 +2056,6 @@ static void memoryTruncate(Pager *pPager){
     }
   }
 }
-#else
-#define memoryTruncate(p)
-#endif
 
 /*
 ** Try to obtain a lock on a file.  Invoke the busy callback if the lock
@@ -2007,6 +2084,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
     }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) );
     if( rc==SQLITE_OK ){
       pPager->state = locktype;
+      IOTRACE(("LOCK %p %d\n", pPager, locktype))
     }
   }
   return rc;
@@ -2015,10 +2093,10 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
 /*
 ** Truncate the file to the number of pages specified.
 */
-int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
+int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){
   int rc;
   assert( pPager->state>=PAGER_SHARED || MEMDB );
-  sqlite3pager_pagecount(pPager);
+  sqlite3PagerPagecount(pPager);
   if( pPager->errCode ){
     rc = pPager->errCode;
     return rc;
@@ -2028,7 +2106,7 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
   }
   if( MEMDB ){
     pPager->dbSize = nPage;
-    memoryTruncate(pPager);
+    pager_truncate_cache(pPager);
     return SQLITE_OK;
   }
   rc = syncJournal(pPager);
@@ -2043,9 +2121,6 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
   }
 
   rc = pager_truncate(pPager, nPage);
-  if( rc==SQLITE_OK ){
-    pPager->dbSize = nPage;
-  }
   return rc;
 }
 
@@ -2063,7 +2138,7 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
 ** a hot journal may be left in the filesystem but no error is returned
 ** to the caller.
 */
-int sqlite3pager_close(Pager *pPager){
+int sqlite3PagerClose(Pager *pPager){
 #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
@@ -2077,9 +2152,12 @@ int sqlite3pager_close(Pager *pPager){
 
   disable_simulated_io_errors();
   pPager->errCode = 0;
+  pPager->exclusiveMode = 0;
   pager_reset(pPager);
+  pagerUnlockAndRollback(pPager);
   enable_simulated_io_errors();
-  TRACE2("CLOSE %d\n", PAGERID(pPager));
+  PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
+  IOTRACE(("CLOSE %p\n", pPager))
   assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
   if( pPager->journalOpen ){
     sqlite3OsClose(&pPager->jfd);
@@ -2108,6 +2186,7 @@ int sqlite3pager_close(Pager *pPager){
   }
 #endif
   sqliteFree(pPager->aHash);
+  sqliteFree(pPager->pTmpSpace);
   sqliteFree(pPager);
   return SQLITE_OK;
 }
@@ -2115,8 +2194,7 @@ int sqlite3pager_close(Pager *pPager){
 /*
 ** Return the page number for the given page data.
 */
-Pgno sqlite3pager_pagenumber(void *pData){
-  PgHdr *p = DATA_TO_PGHDR(pData);
+Pgno sqlite3PagerPagenumber(DbPage *p){
   return p->pgno;
 }
 
@@ -2169,8 +2247,7 @@ static void _page_ref(PgHdr *pPg){
 ** Increment the reference count for a page.  The input pointer is
 ** a reference to the page data.
 */
-int sqlite3pager_ref(void *pData){
-  PgHdr *pPg = DATA_TO_PGHDR(pData);
+int sqlite3PagerRef(DbPage *pPg){
   page_ref(pPg);
   return SQLITE_OK;
 }
@@ -2225,20 +2302,24 @@ static int syncJournal(Pager *pPager){
         ** it as a candidate for rollback. 
         */
         if( pPager->fullSync ){
-          TRACE2("SYNC journal of %d\n", PAGERID(pPager));
+          PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
+          IOTRACE(("JSYNC %p\n", pPager))
           rc = sqlite3OsSync(pPager->jfd, 0);
           if( rc!=0 ) return rc;
         }
         rc = sqlite3OsSeek(pPager->jfd,
                            pPager->journalHdr + sizeof(aJournalMagic));
         if( rc ) return rc;
+        IOTRACE(("JHDR %p %lld %d\n", pPager,
+                  pPager->journalHdr + sizeof(aJournalMagic), 4))
         rc = write32bits(pPager->jfd, pPager->nRec);
         if( rc ) return rc;
 
         rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff);
         if( rc ) return rc;
       }
-      TRACE2("SYNC journal of %d\n", PAGERID(pPager));
+      PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
+      IOTRACE(("JSYNC %d\n", pPager))
       rc = sqlite3OsSync(pPager->jfd, pPager->full_fsync);
       if( rc!=0 ) return rc;
       pPager->journalStarted = 1;
@@ -2302,9 +2383,16 @@ static PgHdr *merge_pagelist(PgHdr *pA, PgHdr *pB){
 ** connected by pDirty pointers.  The pPrevDirty pointers are
 ** corrupted by this sort.
 */
-#define N_SORT_BUCKET 25
+#define N_SORT_BUCKET_ALLOC 25
+#define N_SORT_BUCKET       25
+#ifdef SQLITE_TEST
+  int sqlite3_pager_n_sort_bucket = 0;
+  #undef N_SORT_BUCKET
+  #define N_SORT_BUCKET \
+   (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC)
+#endif
 static PgHdr *sort_pagelist(PgHdr *pIn){
-  PgHdr *a[N_SORT_BUCKET], *p;
+  PgHdr *a[N_SORT_BUCKET_ALLOC], *p;
   int i;
   memset(a, 0, sizeof(a));
   while( pIn ){
@@ -2321,6 +2409,11 @@ static PgHdr *sort_pagelist(PgHdr *pIn){
       }
     }
     if( i==N_SORT_BUCKET-1 ){
+      /* Coverage: To get here, there need to be 2^(N_SORT_BUCKET) 
+      ** elements in the input list. This is possible, but impractical.
+      ** Testing this line is the point of global variable
+      ** sqlite3_pager_n_sort_bucket.
+      */
       a[i] = merge_pagelist(a[i], p);
     }
   }
@@ -2370,19 +2463,20 @@ static int pager_write_pagelist(PgHdr *pList){
     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
+    ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to
     ** make the file smaller (presumably by auto-vacuum code). Do not write
     ** any such pages to the file.
     */
     if( pList->pgno<=pPager->dbSize ){
       char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
-      TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
+      PAGERTRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
+      IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno))
       rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize);
       TEST_INCR(pPager->nWrite);
     }
 #ifndef NDEBUG
     else{
-      TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
+      PAGERTRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
     }
 #endif
     if( rc ) return rc;
@@ -2414,9 +2508,13 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
 */
 static int hasHotJournal(Pager *pPager){
   if( !pPager->useJournal ) return 0;
-  if( !sqlite3OsFileExists(pPager->zJournal) ) return 0;
-  if( sqlite3OsCheckReservedLock(pPager->fd) ) return 0;
-  if( sqlite3pager_pagecount(pPager)==0 ){
+  if( !sqlite3OsFileExists(pPager->zJournal) ){
+    return 0;
+  }
+  if( sqlite3OsCheckReservedLock(pPager->fd) ){
+    return 0;
+  }
+  if( sqlite3PagerPagecount(pPager)==0 ){
     sqlite3OsDelete(pPager->zJournal);
     return 0;
   }else{
@@ -2434,6 +2532,8 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
   PgHdr *pPg;
   *ppPg = 0;
 
+  assert(!MEMDB);
+
   /* Find a page to recycle.  Try to locate a page that does not
   ** require us to do an fsync() on the journal.
   */
@@ -2458,6 +2558,7 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
       */
       pPager->nRec = 0;
       assert( pPager->journalOff > 0 );
+      assert( pPager->doNotSync==0 );
       rc = writeJournalHdr(pPager);
       if( rc!=0 ){
         return rc;
@@ -2488,20 +2589,21 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
 
   /* 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.
+  ** sqlite3PagerDontRollback() 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 ){
+    IOTRACE(("ALWAYS_ROLLBACK %p\n", pPager))
     pPager->alwaysRollback = 1;
   }
 
   /* Unlink the old page from the free list and the hash table
   */
   unlinkPage(pPg);
-  TEST_INCR(pPager->nOvfl);
+  assert( pPg->pgno==0 );
 
   *ppPg = pPg;
   return SQLITE_OK;
@@ -2518,9 +2620,8 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
 ** of bytes of memory released.
 */
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-int sqlite3pager_release_memory(int nReq){
+int sqlite3PagerReleaseMemory(int nReq){
   const ThreadData *pTsdro = sqlite3ThreadDataReadOnly();
-  Pager *p;
   int nReleased = 0;
   int i;
 
@@ -2542,15 +2643,20 @@ int sqlite3pager_release_memory(int nReq){
   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){
+    Pager *pPager = pTsdro->pPager;
+    for( ; pPager && (nReq<0 || nReleased<nReq); pPager=pPager->pNext){
       PgHdr *pPg;
       int rc;
 
+      if( MEMDB ){
+        continue;
+      }
+
       /* 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) {
+      while( SQLITE_OK==(rc = pager_recycle(pPager, 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. 
@@ -2561,11 +2667,10 @@ int sqlite3pager_release_memory(int nReq){
         */
         PgHdr *pTmp;
         assert( pPg );
-        page_remove_from_stmt_list(pPg);
-        if( pPg==p->pAll ){
-           p->pAll = pPg->pNextAll;
+        if( pPg==pPager->pAll ){
+           pPager->pAll = pPg->pNextAll;
         }else{
-          for( pTmp=p->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
+          for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
           pTmp->pNextAll = pPg->pNextAll;
         }
         nReleased += sqliteAllocSize(pPg);
@@ -2580,8 +2685,8 @@ int sqlite3pager_release_memory(int nReq){
         ** of a shared pager cache) of the pager for which the error occured.
         */
         assert( (rc&0xff)==SQLITE_IOERR || rc==SQLITE_FULL );
-        assert( p->state>=PAGER_RESERVED );
-        pager_error(p, rc);
+        assert( pPager->state>=PAGER_RESERVED );
+        pager_error(pPager, rc);
       }
     }
   }
@@ -2590,6 +2695,247 @@ int sqlite3pager_release_memory(int nReq){
 }
 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
 
+/*
+** Read the content of page pPg out of the database file.
+*/
+static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
+  int rc;
+  assert( MEMDB==0 );
+  rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg),
+                          pPager->pageSize);
+  }
+  IOTRACE(("PGIN %p %d\n", pPager, pgno))
+  PAGERTRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
+  CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
+  return rc;
+}
+
+
+/*
+** This function is called to obtain the shared lock required before
+** data may be read from the pager cache. If the shared lock has already
+** been obtained, this function is a no-op.
+**
+** Immediately after obtaining the shared lock (if required), this function
+** checks for a hot-journal file. If one is found, an emergency rollback
+** is performed immediately.
+*/
+static int pagerSharedLock(Pager *pPager){
+  int rc = SQLITE_OK;
+
+  if( pPager->state==PAGER_UNLOCK ){
+    if( !MEMDB ){
+      assert( pPager->nRef==0 );
+      if( !pPager->noReadlock ){
+        rc = pager_wait_on_lock(pPager, SHARED_LOCK);
+        if( rc!=SQLITE_OK ){
+          return pager_error(pPager, rc);
+        }
+        assert( pPager->state>=SHARED_LOCK );
+      }
+  
+      /* If a journal file exists, and there is no RESERVED lock on the
+      ** database file, then it either needs to be played back or deleted.
+      */
+      if( hasHotJournal(pPager) ){
+        /* 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
+        ** database file, detect the RESERVED lock, and conclude that the
+        ** database is safe to read while this process is still rolling it 
+        ** back.
+        ** 
+        ** Because the intermediate RESERVED lock is not requested, the
+        ** 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);
+        if( rc!=SQLITE_OK ){
+          pager_unlock(pPager);
+          return pager_error(pPager, rc);
+        }
+        pPager->state = PAGER_EXCLUSIVE;
+        /* Open the journal for reading only.  Return SQLITE_BUSY if
+        ** we are unable to open the journal file. 
+        **
+        ** The journal file does not need to be locked itself.  The
+        ** journal file is never open unless the main database file holds
+        ** a write lock, so there is never any chance of two or more
+        ** processes opening the journal at the same time.
+        **
+       ** Open the journal for read/write access. This is because in 
+       ** exclusive-access mode the file descriptor will be kept open and
+        ** possibly used for a transaction later on. On some systems, the
+        ** OsTruncate() call used in exclusive-access mode also requires
+        ** a read/write file handle.
+        */
+        rc = SQLITE_BUSY;
+        if( sqlite3OsFileExists(pPager->zJournal) ){
+          int ro;
+          assert( !pPager->tempFile );
+          rc = sqlite3OsOpenReadWrite(pPager->zJournal, &pPager->jfd, &ro);
+          assert( rc!=SQLITE_OK || pPager->jfd );
+          if( ro ){
+            rc = SQLITE_BUSY;
+            sqlite3OsClose(&pPager->jfd);
+          }
+        }
+        if( rc!=SQLITE_OK ){
+          pager_unlock(pPager);
+          return SQLITE_BUSY;
+        }
+        pPager->journalOpen = 1;
+        pPager->journalStarted = 0;
+        pPager->journalOff = 0;
+        pPager->setMaster = 0;
+        pPager->journalHdr = 0;
+        /* Playback and delete the journal.  Drop the database write
+        ** lock and reacquire the read lock.
+        */
+        rc = pager_playback(pPager, 1);
+        if( rc!=SQLITE_OK ){
+          return pager_error(pPager, rc);
+        }
+        assert(pPager->state==PAGER_SHARED || 
+            (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
+        );
+      }
+
+      if( pPager->pAll ){
+        /* The shared-lock has just been acquired on the database file
+        ** and there are already pages in the cache (from a previous
+        ** read or write transaction). If the value of the change-counter
+        ** stored in Pager.iChangeCount matches that found on page 1 of
+        ** the database file, then no database changes have occured since
+        ** the cache was last valid and it is safe to retain the cached
+        ** pages. Otherwise, if Pager.iChangeCount does not match the
+        ** change-counter on page 1 of the file, the current cache contents
+        ** must be discarded.
+        */
+        u8 zC[4];
+        u32 iChangeCounter = 0;
+        sqlite3PagerPagecount(pPager);
+
+        if( pPager->errCode ){
+          return pPager->errCode;
+        }
+
+        if( pPager->dbSize>0 ){
+          /* Read the 4-byte change counter directly from the file. */
+          rc = sqlite3OsSeek(pPager->fd, 24);
+          if( rc!=SQLITE_OK ){
+            return rc;
+          }
+          rc = sqlite3OsRead(pPager->fd, zC, 4);
+          if( rc!=SQLITE_OK ){
+            return rc;
+          }
+          iChangeCounter = (zC[0]<<24) + (zC[1]<<16) + (zC[2]<<8) + zC[3];
+        }
+
+        if( iChangeCounter!=pPager->iChangeCount ){
+          pager_reset(pPager);
+        }
+      }
+    }
+    assert( pPager->exclusiveMode || pPager->state<=PAGER_SHARED );
+    if( pPager->state==PAGER_UNLOCK ){
+      pPager->state = PAGER_SHARED;
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Allocate a PgHdr object.   Either create a new one or reuse
+** an existing one that is not otherwise in use.
+**
+** A new PgHdr structure is created if any of the following are
+** true:
+**
+**     (1)  We have not exceeded our maximum allocated cache size
+**          as set by the "PRAGMA cache_size" command.
+**
+**     (2)  There are no unused PgHdr objects available at this time.
+**
+**     (3)  This is an in-memory database.
+**
+**     (4)  There are no PgHdr objects that do not require a journal
+**          file sync and a sync of the journal file is currently
+**          prohibited.
+**
+** Otherwise, reuse an existing PgHdr.  In other words, reuse an
+** existing PgHdr if all of the following are true:
+**
+**     (1)  We have reached or exceeded the maximum cache size
+**          allowed by "PRAGMA cache_size".
+**
+**     (2)  There is a PgHdr available with PgHdr->nRef==0
+**
+**     (3)  We are not in an in-memory database
+**
+**     (4)  Either there is an available PgHdr that does not need
+**          to be synced to disk or else disk syncing is currently
+**          allowed.
+*/
+static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){
+  int rc = SQLITE_OK;
+  PgHdr *pPg;
+
+  /* Create a new PgHdr if any of the four conditions defined 
+  ** above is met: */
+  if( pPager->nPage<pPager->mxPage
+   || pPager->pFirst==0 
+   || MEMDB
+   || (pPager->pFirstSynced==0 && pPager->doNotSync)
+  ){
+    if( pPager->nPage>=pPager->nHash ){
+      pager_resize_hash_table(pPager,
+         pPager->nHash<256 ? 256 : pPager->nHash*2);
+      if( pPager->nHash==0 ){
+        rc = SQLITE_NOMEM;
+        goto pager_allocate_out;
+      }
+    }
+    pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
+                            + sizeof(u32) + pPager->nExtra
+                            + MEMDB*sizeof(PgHistory) );
+    if( pPg==0 ){
+      rc = SQLITE_NOMEM;
+      goto pager_allocate_out;
+    }
+    memset(pPg, 0, sizeof(*pPg));
+    if( MEMDB ){
+      memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
+    }
+    pPg->pPager = pPager;
+    pPg->pNextAll = pPager->pAll;
+    pPager->pAll = pPg;
+    pPager->nPage++;
+    if( pPager->nPage>pPager->nMaxPage ){
+      assert( pPager->nMaxPage==(pPager->nPage-1) );
+      pPager->nMaxPage++;
+    }
+  }else{
+    /* Recycle an existing page with a zero ref-count. */
+    rc = pager_recycle(pPager, 1, &pPg);
+    if( rc!=SQLITE_OK ){
+      goto pager_allocate_out;
+    }
+    assert( pPager->state>=SHARED_LOCK );
+    assert(pPg);
+  }
+  *ppPg = pPg;
+
+pager_allocate_out:
+  return rc;
+}
+
 /*
 ** Acquire a page.
 **
@@ -2605,18 +2951,25 @@ int sqlite3pager_release_memory(int nReq){
 ** The acquisition might fail for several reasons.  In all cases,
 ** an appropriate error code is returned and *ppPage is set to NULL.
 **
-** See also sqlite3pager_lookup().  Both this routine and _lookup() attempt
+** See also sqlite3PagerLookup().  Both this routine and _lookup() attempt
 ** to find a page in the in-memory cache first.  If the page is not already
 ** in memory, this routine goes to disk to read it in whereas _lookup()
 ** just returns 0.  This routine acquires a read-lock the first time it
 ** has to go to disk, and could also playback an old journal if necessary.
 ** Since _lookup() never goes to disk, it never has to deal with locks
 ** or journal files.
+**
+** If clrFlag is false, the page contents are actually read from disk.
+** If clfFlag is true, it means the page is about to be erased and
+** rewritten without first being read so there is no point it doing
+** the disk I/O.
 */
-int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
+int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag){
   PgHdr *pPg;
   int rc;
 
+  assert( pPager->state==PAGER_UNLOCK || pPager->nRef>0 || pgno==1 );
+
   /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
   ** number greater than this, or zero, is requested.
   */
@@ -2633,112 +2986,28 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
   }
 
   /* If this is the first page accessed, then get a SHARED lock
-  ** on the database file.
+  ** on the database file. pagerSharedLock() is a no-op if 
+  ** a database lock is already held.
   */
-  if( pPager->nRef==0 && !MEMDB ){
-    if( !pPager->noReadlock ){
-      rc = pager_wait_on_lock(pPager, SHARED_LOCK);
-      if( rc!=SQLITE_OK ){
-        return pager_error(pPager, rc);
-      }
-    }
-
-    /* If a journal file exists, and there is no RESERVED lock on the
-    ** database file, then it either needs to be played back or deleted.
-    */
-    if( hasHotJournal(pPager) ){
-       /* 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
-       ** database file, detect the RESERVED lock, and conclude that the
-       ** database is safe to read while this process is still rolling it 
-       ** back.
-       ** 
-       ** Because the intermediate RESERVED lock is not requested, the
-       ** 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);
-       if( rc!=SQLITE_OK ){
-         pager_unlock(pPager);
-         return pager_error(pPager, rc);
-       }
-       pPager->state = PAGER_EXCLUSIVE;
-
-       /* Open the journal for reading only.  Return SQLITE_BUSY if
-       ** we are unable to open the journal file. 
-       **
-       ** The journal file does not need to be locked itself.  The
-       ** journal file is never open unless the main database file holds
-       ** a write lock, so there is never any chance of two or more
-       ** processes opening the journal at the same time.
-       */
-       rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
-       if( rc!=SQLITE_OK ){
-         pager_unlock(pPager);
-         return SQLITE_BUSY;
-       }
-       pPager->journalOpen = 1;
-       pPager->journalStarted = 0;
-       pPager->journalOff = 0;
-       pPager->setMaster = 0;
-       pPager->journalHdr = 0;
-
-       /* Playback and delete the journal.  Drop the database write
-       ** lock and reacquire the read lock.
-       */
-       rc = pager_playback(pPager);
-       if( rc!=SQLITE_OK ){
-         return pager_error(pPager, rc);
-       }
-    }
-    pPg = 0;
-  }else{
-    /* Search for page in cache */
-    pPg = pager_lookup(pPager, pgno);
-    if( MEMDB && pPager->state==PAGER_UNLOCK ){
-      pPager->state = PAGER_SHARED;
-    }
+  rc = pagerSharedLock(pPager);
+  if( rc!=SQLITE_OK ){
+    return rc;
   }
+  assert( pPager->state!=PAGER_UNLOCK );
+
+  pPg = pager_lookup(pPager, pgno);
   if( pPg==0 ){
     /* The requested page is not in the page cache. */
+    int nMax;
     int h;
     TEST_INCR(pPager->nMiss);
-    if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ){
-      /* Create a new page */
-      if( pPager->nPage>=pPager->nHash ){
-        pager_resize_hash_table(pPager,
-           pPager->nHash<256 ? 256 : pPager->nHash*2);
-        if( pPager->nHash==0 ){
-          return SQLITE_NOMEM;
-        }
-      }
-      pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
-                              + sizeof(u32) + pPager->nExtra
-                              + MEMDB*sizeof(PgHistory) );
-      if( pPg==0 ){
-        return SQLITE_NOMEM;
-      }
-      memset(pPg, 0, sizeof(*pPg));
-      if( MEMDB ){
-        memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
-      }
-      pPg->pPager = pPager;
-      pPg->pNextAll = pPager->pAll;
-      pPager->pAll = pPg;
-      pPager->nPage++;
-      if( pPager->nPage>pPager->nMaxPage ){
-        assert( pPager->nMaxPage==(pPager->nPage-1) );
-        pPager->nMaxPage++;
-      }
-    }else{
-      rc = pager_recycle(pPager, 1, &pPg);
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
-      assert(pPg) ;
+    rc = pagerAllocatePage(pPager, &pPg);
+    if( rc!=SQLITE_OK ){
+      return rc;
     }
+
     pPg->pgno = pgno;
+    assert( !MEMDB || pgno>pPager->stmtSize );
     if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
       sqlite3CheckMemory(pPager->aInJournal, pgno/8);
       assert( pPager->journalOpen );
@@ -2748,12 +3017,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
       pPg->inJournal = 0;
       pPg->needSync = 0;
     }
-    if( pPager->aInStmt && (int)pgno<=pPager->stmtSize
-             && (pPager->aInStmt[pgno/8] & (1<<(pgno&7)))!=0 ){
-      page_add_to_stmt_list(pPg);
-    }else{
-      page_remove_from_stmt_list(pPg);
-    }
+
     makeClean(pPg);
     pPg->nRef = 1;
     REFINFO(pPg);
@@ -2762,8 +3026,9 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
     if( pPager->nExtra>0 ){
       memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
     }
+    nMax = sqlite3PagerPagecount(pPager);
     if( pPager->errCode ){
-      sqlite3pager_unref(PGHDR_TO_DATA(pPg));
+      sqlite3PagerUnref(pPg);
       rc = pPager->errCode;
       return rc;
     }
@@ -2771,20 +3036,13 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
     /* 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 ){
+    if( nMax<(int)pgno || MEMDB || (clrFlag && !pPager->alwaysRollback) ){
       memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
     }else{
-      assert( MEMDB==0 );
-      rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
-      if( rc==SQLITE_OK ){
-        rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg),
-                              pPager->pageSize);
-      }
-      TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
-      CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
+      rc = readDbPage(pPager, pPg, pgno);
       if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
         pPg->pgno = 0;
-        sqlite3pager_unref(PGHDR_TO_DATA(pPg));
+        sqlite3PagerUnref(pPg);
         return rc;
       }else{
         TEST_INCR(pPager->nRead);
@@ -2806,10 +3064,11 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
 #endif
   }else{
     /* The requested page is in the page cache. */
+    assert(pPager->nRef>0 || pgno==1);
     TEST_INCR(pPager->nHit);
     page_ref(pPg);
   }
-  *ppPage = PGHDR_TO_DATA(pPg);
+  *ppPage = pPg;
   return SQLITE_OK;
 }
 
@@ -2818,24 +3077,29 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
 ** not read the page from disk.  Return a pointer to the page,
 ** or 0 if the page is not in cache.
 **
-** See also sqlite3pager_get().  The difference between this routine
-** and sqlite3pager_get() is that _get() will go to the disk and read
+** See also sqlite3PagerGet().  The difference between this routine
+** and sqlite3PagerGet() is that _get() will go to the disk and read
 ** in the page if the page is not already in cache.  This routine
 ** returns NULL if the page is not in cache or if a disk I/O error 
 ** has ever happened.
 */
-void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){
+DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
   PgHdr *pPg;
 
   assert( pPager!=0 );
   assert( pgno!=0 );
+
+  if( pPager->state==PAGER_UNLOCK ){
+    assert( !pPager->pAll || pPager->exclusiveMode );
+    return 0;
+  }
   if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
     return 0;
   }
   pPg = pager_lookup(pPager, pgno);
   if( pPg==0 ) return 0;
   page_ref(pPg);
-  return PGHDR_TO_DATA(pPg);
+  return pPg;
 }
 
 /*
@@ -2846,12 +3110,10 @@ void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){
 ** are released, a rollback occurs and the lock on the database is
 ** removed.
 */
-int sqlite3pager_unref(void *pData){
-  PgHdr *pPg;
+int sqlite3PagerUnref(DbPage *pPg){
 
   /* Decrement the reference count for this page
   */
-  pPg = DATA_TO_PGHDR(pData);
   assert( pPg->nRef>0 );
   pPg->nRef--;
   REFINFO(pPg);
@@ -2876,7 +3138,7 @@ int sqlite3pager_unref(void *pData){
       pPager->pFirstSynced = pPg;
     }
     if( pPager->xDestructor ){
-      pPager->xDestructor(pData, pPager->pageSize);
+      pPager->xDestructor(pPg, pPager->pageSize);
     }
   
     /* When all pages reach the freelist, drop the read lock from
@@ -2884,8 +3146,8 @@ int sqlite3pager_unref(void *pData){
     */
     pPager->nRef--;
     assert( pPager->nRef>=0 );
-    if( pPager->nRef==0 && !MEMDB ){
-      pager_reset(pPager);
+    if( pPager->nRef==0 && (!pPager->exclusiveMode || pPager->journalOff>0) ){
+      pagerUnlockAndRollback(pPager);
     }
   }
   return SQLITE_OK;
@@ -2905,7 +3167,7 @@ static int pager_open_journal(Pager *pPager){
   assert( pPager->journalOpen==0 );
   assert( pPager->useJournal );
   assert( pPager->aInJournal==0 );
-  sqlite3pager_pagecount(pPager);
+  sqlite3PagerPagecount(pPager);
   pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
   if( pPager->aInJournal==0 ){
     rc = SQLITE_NOMEM;
@@ -2913,10 +3175,14 @@ static int pager_open_journal(Pager *pPager){
   }
   rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,
                                  pPager->tempFile);
+  assert( rc!=SQLITE_OK || pPager->jfd );
   pPager->journalOff = 0;
   pPager->setMaster = 0;
   pPager->journalHdr = 0;
   if( rc!=SQLITE_OK ){
+    if( rc==SQLITE_NOMEM ){
+      sqlite3OsDelete(pPager->zJournal);
+    }
     goto failed_to_open_journal;
   }
   sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync);
@@ -2936,10 +3202,10 @@ static int pager_open_journal(Pager *pPager){
   rc = writeJournalHdr(pPager);
 
   if( pPager->stmtAutoopen && rc==SQLITE_OK ){
-    rc = sqlite3pager_stmt_begin(pPager);
+    rc = sqlite3PagerStmtBegin(pPager);
   }
   if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
-    rc = pager_unwritelock(pPager);
+    rc = pager_end_transaction(pPager);
     if( rc==SQLITE_OK ){
       rc = SQLITE_FULL;
     }
@@ -2949,16 +3215,6 @@ static int pager_open_journal(Pager *pPager){
 failed_to_open_journal:
   sqliteFree(pPager->aInJournal);
   pPager->aInJournal = 0;
-  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{
-    pager_reset(pPager);
-  }
   return rc;
 }
 
@@ -2966,10 +3222,10 @@ failed_to_open_journal:
 ** Acquire a write-lock on the database.  The lock is removed when
 ** the any of the following happen:
 **
-**   *  sqlite3pager_commit() is called.
-**   *  sqlite3pager_rollback() is called.
-**   *  sqlite3pager_close() is called.
-**   *  sqlite3pager_unref() is called to on every outstanding page.
+**   *  sqlite3PagerCommitPhaseTwo() is called.
+**   *  sqlite3PagerRollback() is called.
+**   *  sqlite3PagerClose() is called.
+**   *  sqlite3PagerUnref() is called to on every outstanding page.
 **
 ** The first parameter to this routine is a pointer to any open page of the
 ** database file.  Nothing changes about the page - it is used merely to
@@ -2989,8 +3245,7 @@ failed_to_open_journal:
 ** immediately instead of waiting until we try to flush the cache.  The
 ** exFlag is ignored if a transaction is already active.
 */
-int sqlite3pager_begin(void *pData, int exFlag){
-  PgHdr *pPg = DATA_TO_PGHDR(pData);
+int sqlite3PagerBegin(DbPage *pPg, int exFlag){
   Pager *pPager = pPg->pPager;
   int rc = SQLITE_OK;
   assert( pPg->nRef>0 );
@@ -3012,12 +3267,30 @@ int sqlite3pager_begin(void *pData, int exFlag){
         return rc;
       }
       pPager->dirtyCache = 0;
-      TRACE2("TRANSACTION %d\n", PAGERID(pPager));
+      PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
       if( pPager->useJournal && !pPager->tempFile ){
         rc = pager_open_journal(pPager);
       }
     }
+  }else if( pPager->journalOpen && pPager->journalOff==0 ){
+    /* This happens when the pager was in exclusive-access mode last
+    ** time a (read or write) transaction was successfully concluded
+    ** by this connection. Instead of deleting the journal file it was 
+    ** kept open and truncated to 0 bytes.
+    */
+    assert( pPager->nRec==0 );
+    assert( pPager->origDbSize==0 );
+    assert( pPager->aInJournal==0 );
+    sqlite3PagerPagecount(pPager);
+    pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
+    if( !pPager->aInJournal ){
+      rc = SQLITE_NOMEM;
+    }else{
+      pPager->origDbSize = pPager->dbSize;
+      rc = writeJournalHdr(pPager);
+    }
   }
+  assert( !pPager->journalOpen || pPager->journalOff>0 || rc!=SQLITE_OK );
   return rc;
 }
 
@@ -3071,11 +3344,11 @@ static void makeClean(PgHdr *pPg){
 ** If the journal file could not be written because the disk is full,
 ** then this routine returns SQLITE_FULL and does an immediate rollback.
 ** All subsequent write attempts also return SQLITE_FULL until there
-** is a call to sqlite3pager_commit() or sqlite3pager_rollback() to
+** is a call to sqlite3PagerCommit() or sqlite3PagerRollback() to
 ** reset.
 */
-int sqlite3pager_write(void *pData){
-  PgHdr *pPg = DATA_TO_PGHDR(pData);
+static int pager_write(PgHdr *pPg){
+  void *pData = PGHDR_TO_DATA(pPg);
   Pager *pPager = pPg->pPager;
   int rc = SQLITE_OK;
 
@@ -3096,7 +3369,7 @@ int sqlite3pager_write(void *pData){
   ** to the journal then we can return right away.
   */
   makeDirty(pPg);
-  if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){
+  if( pPg->inJournal && (pageInStatement(pPg) || pPager->stmtInUse==0) ){
     pPager->dirtyCache = 1;
   }else{
 
@@ -3108,7 +3381,7 @@ int sqlite3pager_write(void *pData){
     ** create it if it does not.
     */
     assert( pPager->state!=PAGER_UNLOCK );
-    rc = sqlite3pager_begin(pData, 0);
+    rc = sqlite3PagerBegin(pPg, 0);
     if( rc!=SQLITE_OK ){
       return rc;
     }
@@ -3129,7 +3402,7 @@ int sqlite3pager_write(void *pData){
         int szPg;
         if( MEMDB ){
           PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
-          TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
+          PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
           assert( pHist->pOrig==0 );
           pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
           if( pHist->pOrig ){
@@ -3151,8 +3424,10 @@ int sqlite3pager_write(void *pData){
           szPg = pPager->pageSize+8;
           put32bits(pData2, pPg->pgno);
           rc = sqlite3OsWrite(pPager->jfd, pData2, szPg);
+          IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno,
+                   pPager->journalOff, szPg))
           pPager->journalOff += szPg;
-          TRACE4("JOURNAL %d page %d needSync=%d\n",
+          PAGERTRACE4("JOURNAL %d page %d needSync=%d\n",
                   PAGERID(pPager), pPg->pgno, pPg->needSync);
           *(u32*)pEnd = saved;
 
@@ -3169,12 +3444,11 @@ int sqlite3pager_write(void *pData){
           pPg->needSync = !pPager->noSync;
           if( pPager->stmtInUse ){
             pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-            page_add_to_stmt_list(pPg);
           }
         }
       }else{
         pPg->needSync = !pPager->journalStarted && !pPager->noSync;
-        TRACE4("APPEND %d page %d needSync=%d\n",
+        PAGERTRACE4("APPEND %d page %d needSync=%d\n",
                 PAGERID(pPager), pPg->pgno, pPg->needSync);
       }
       if( pPg->needSync ){
@@ -3188,7 +3462,10 @@ int sqlite3pager_write(void *pData){
     ** the statement journal format differs from the standard journal format
     ** in that it omits the checksums and the header.
     */
-    if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){
+    if( pPager->stmtInUse 
+     && !pageInStatement(pPg) 
+     && (int)pPg->pgno<=pPager->stmtSize 
+    ){
       assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
       if( MEMDB ){
         PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
@@ -3197,12 +3474,13 @@ int sqlite3pager_write(void *pData){
         if( pHist->pStmt ){
           memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
         }
-        TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
+        PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
+        page_add_to_stmt_list(pPg);
       }else{
         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);
+        PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
         if( rc!=SQLITE_OK ){
           return rc;
         }
@@ -3210,7 +3488,6 @@ int sqlite3pager_write(void *pData){
         assert( pPager->aInStmt!=0 );
         pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
       }
-      page_add_to_stmt_list(pPg);
     }
   }
 
@@ -3226,14 +3503,84 @@ int sqlite3pager_write(void *pData){
   return rc;
 }
 
+/*
+** This function is used to mark a data-page as writable. It uses 
+** pager_write() to open a journal file (if it is not already open)
+** and write the page *pData to the journal.
+**
+** The difference between this function and pager_write() is that this
+** function also deals with the special case where 2 or more pages
+** fit on a single disk sector. In this case all co-resident pages
+** must have been written to the journal file before returning.
+*/
+int sqlite3PagerWrite(DbPage *pDbPage){
+  int rc = SQLITE_OK;
+
+  PgHdr *pPg = pDbPage;
+  Pager *pPager = pPg->pPager;
+  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
+
+  if( !MEMDB && nPagePerSector>1 ){
+    Pgno nPageCount;          /* Total number of pages in database file */
+    Pgno pg1;                 /* First page of the sector pPg is located on. */
+    int nPage;                /* Number of pages starting at pg1 to journal */
+    int ii;
+
+    /* Set the doNotSync flag to 1. This is because we cannot allow a journal
+    ** header to be written between the pages journaled by this function.
+    */
+    assert( pPager->doNotSync==0 );
+    pPager->doNotSync = 1;
+
+    /* This trick assumes that both the page-size and sector-size are
+    ** an integer power of 2. It sets variable pg1 to the identifier
+    ** of the first page of the sector pPg is located on.
+    */
+    pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
+
+    nPageCount = sqlite3PagerPagecount(pPager);
+    if( pPg->pgno>nPageCount ){
+      nPage = (pPg->pgno - pg1)+1;
+    }else if( (pg1+nPagePerSector-1)>nPageCount ){
+      nPage = nPageCount+1-pg1;
+    }else{
+      nPage = nPagePerSector;
+    }
+    assert(nPage>0);
+    assert(pg1<=pPg->pgno);
+    assert((pg1+nPage)>pPg->pgno);
+
+    for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
+      Pgno pg = pg1+ii;
+      if( !pPager->aInJournal || pg==pPg->pgno || 
+          pg>pPager->origDbSize || !(pPager->aInJournal[pg/8]&(1<<(pg&7)))
+      ) {
+        if( pg!=PAGER_MJ_PGNO(pPager) ){
+          PgHdr *pPage;
+          rc = sqlite3PagerGet(pPager, pg, &pPage);
+          if( rc==SQLITE_OK ){
+            rc = pager_write(pPage);
+            sqlite3PagerUnref(pPage);
+          }
+        }
+      }
+    }
+
+    assert( pPager->doNotSync==1 );
+    pPager->doNotSync = 0;
+  }else{
+    rc = pager_write(pDbPage);
+  }
+  return rc;
+}
+
 /*
 ** Return TRUE if the page given in the argument was previously passed
-** to sqlite3pager_write().  In other words, return TRUE if it is ok
+** to sqlite3PagerWrite().  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);
+int sqlite3PagerIswriteable(DbPage *pPg){
   return pPg->dirty;
 }
 #endif
@@ -3243,17 +3590,17 @@ int sqlite3pager_iswriteable(void *pData){
 ** Replace the content of a single page with the information in the third
 ** argument.
 */
-int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){
-  void *pPage;
+int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void *pData){
+  PgHdr *pPg;
   int rc;
 
-  rc = sqlite3pager_get(pPager, pgno, &pPage);
+  rc = sqlite3PagerGet(pPager, pgno, &pPg);
   if( rc==SQLITE_OK ){
-    rc = sqlite3pager_write(pPage);
+    rc = sqlite3PagerWrite(pPg);
     if( rc==SQLITE_OK ){
-      memcpy(pPage, pData, pPager->pageSize);
+      memcpy(sqlite3PagerGetData(pPg), pData, pPager->pageSize);
     }
-    sqlite3pager_unref(pPage);
+    sqlite3PagerUnref(pPg);
   }
   return rc;
 }
@@ -3269,21 +3616,21 @@ int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){
 ** that it does not get written to disk.
 **
 ** Tests show that this optimization, together with the
-** sqlite3pager_dont_rollback() below, more than double the speed
+** sqlite3PagerDontRollback() below, more than double the speed
 ** of large INSERT operations and quadruple the speed of large DELETEs.
 **
 ** When this routine is called, set the alwaysRollback flag to true.
-** Subsequent calls to sqlite3pager_dont_rollback() for the same page
+** Subsequent calls to sqlite3PagerDontRollback() for the same page
 ** will thereafter be ignored.  This is necessary to avoid a problem
 ** where a page with data is added to the freelist during one part of
 ** a transaction then removed from the freelist during a later part
 ** of the same transaction and reused for some other purpose.  When it
 ** is first added to the freelist, this routine is called.  When reused,
-** the dont_rollback() routine is called.  But because the page contains
-** critical data, we still need to be sure it gets rolled back in spite
-** of the dont_rollback() call.
+** the sqlite3PagerDontRollback() routine is called.  But because the
+** page contains critical data, we still need to be sure it gets
+** rolled back in spite of the sqlite3PagerDontRollback() call.
 */
-void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
+void sqlite3PagerDontWrite(Pager *pPager, Pgno pgno){
   PgHdr *pPg;
 
   if( MEMDB ) return;
@@ -3303,7 +3650,8 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
       ** corruption during the next transaction.
       */
     }else{
-      TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager));
+      PAGERTRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager));
+      IOTRACE(("CLEAN %p %d\n", pPager, pgno))
       makeClean(pPg);
 #ifdef SQLITE_CHECK_PAGES
       pPg->pageHash = pager_pagehash(pPg);
@@ -3318,8 +3666,7 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
 ** means that the pager does not have to record the given page in the
 ** rollback journal.
 */
-void sqlite3pager_dont_rollback(void *pData){
-  PgHdr *pPg = DATA_TO_PGHDR(pData);
+void sqlite3PagerDontRollback(DbPage *pPg){
   Pager *pPager = pPg->pPager;
 
   assert( pPager->state>=PAGER_RESERVED );
@@ -3331,19 +3678,145 @@ void sqlite3pager_dont_rollback(void *pData){
     pPg->inJournal = 1;
     if( pPager->stmtInUse ){
       pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-      page_add_to_stmt_list(pPg);
     }
-    TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager));
+    PAGERTRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager));
+    IOTRACE(("GARBAGE %p %d\n", pPager, pPg->pgno))
   }
-  if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){
+  if( pPager->stmtInUse 
+   && !pageInStatement(pPg) 
+   && (int)pPg->pgno<=pPager->stmtSize 
+  ){
     assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
     assert( pPager->aInStmt!=0 );
     pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-    page_add_to_stmt_list(pPg);
   }
 }
 
 
+/*
+** This routine is called to increment the database file change-counter,
+** stored at byte 24 of the pager file.
+*/
+static int pager_incr_changecounter(Pager *pPager){
+  PgHdr *pPgHdr;
+  u32 change_counter;
+  int rc;
+
+  if( !pPager->changeCountDone ){
+    /* Open page 1 of the file for writing. */
+    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
+    if( rc!=SQLITE_OK ) return rc;
+    rc = sqlite3PagerWrite(pPgHdr);
+    if( rc!=SQLITE_OK ) return rc;
+  
+    /* Read the current value at byte 24. */
+    change_counter = retrieve32bits(pPgHdr, 24);
+  
+    /* Increment the value just read and write it back to byte 24. */
+    change_counter++;
+    put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
+    pPager->iChangeCount = change_counter;
+  
+    /* Release the page reference. */
+    sqlite3PagerUnref(pPgHdr);
+    pPager->changeCountDone = 1;
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Sync the database file for the pager pPager. zMaster points to the name
+** of a master journal file that should be written into the individual
+** journal file. zMaster may be NULL, which is interpreted as no master
+** journal (a single database transaction).
+**
+** This routine ensures that the journal is synced, all dirty pages written
+** to the database file and the database file synced. The only thing that
+** remains to commit the transaction is to delete the journal file (or
+** master journal file if specified).
+**
+** Note that if zMaster==NULL, this does not overwrite a previous value
+** passed to an sqlite3PagerCommitPhaseOne() call.
+**
+** If parameter nTrunc is non-zero, then the pager file is truncated to
+** nTrunc pages (this is used by auto-vacuum databases).
+*/
+int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster, Pgno nTrunc){
+  int rc = SQLITE_OK;
+
+  PAGERTRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", 
+      pPager->zFilename, zMaster, nTrunc);
+
+  /* If this is an in-memory db, or no pages have been written to, or this
+  ** function has already been called, it is a no-op.
+  */
+  if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
+    PgHdr *pPg;
+    assert( pPager->journalOpen );
+
+    /* If a master journal file name has already been written to the
+    ** journal file, then no sync is required. This happens when it is
+    ** written, then the process fails to upgrade from a RESERVED to an
+    ** EXCLUSIVE lock. The next time the process tries to commit the
+    ** transaction the m-j name will have already been written.
+    */
+    if( !pPager->setMaster ){
+      rc = pager_incr_changecounter(pPager);
+      if( rc!=SQLITE_OK ) goto sync_exit;
+#ifndef SQLITE_OMIT_AUTOVACUUM
+      if( nTrunc!=0 ){
+        /* If this transaction has made the database smaller, then all pages
+        ** being discarded by the truncation must be written to the journal
+        ** file.
+        */
+        Pgno i;
+        int iSkip = PAGER_MJ_PGNO(pPager);
+        for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
+          if( !(pPager->aInJournal[i/8] & (1<<(i&7))) && i!=iSkip ){
+            rc = sqlite3PagerGet(pPager, i, &pPg);
+            if( rc!=SQLITE_OK ) goto sync_exit;
+            rc = sqlite3PagerWrite(pPg);
+            sqlite3PagerUnref(pPg);
+            if( rc!=SQLITE_OK ) goto sync_exit;
+          }
+        } 
+      }
+#endif
+      rc = writeMasterJournal(pPager, zMaster);
+      if( rc!=SQLITE_OK ) goto sync_exit;
+      rc = syncJournal(pPager);
+      if( rc!=SQLITE_OK ) goto sync_exit;
+    }
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+    if( nTrunc!=0 ){
+      rc = sqlite3PagerTruncate(pPager, nTrunc);
+      if( rc!=SQLITE_OK ) goto sync_exit;
+    }
+#endif
+
+    /* Write all dirty pages to the database file */
+    pPg = pager_get_all_dirty_pages(pPager);
+    rc = pager_write_pagelist(pPg);
+    if( rc!=SQLITE_OK ) goto sync_exit;
+    pPager->pDirty = 0;
+
+    /* Sync the database file. */
+    if( !pPager->noSync ){
+      rc = sqlite3OsSync(pPager->fd, 0);
+    }
+    IOTRACE(("DBSYNC %p\n", pPager))
+
+    pPager->state = PAGER_SYNCED;
+  }else if( MEMDB && nTrunc!=0 ){
+    rc = sqlite3PagerTruncate(pPager, nTrunc);
+  }
+
+sync_exit:
+  return rc;
+}
+
+
 /*
 ** Commit all changes to the database and release the write lock.
 **
@@ -3351,7 +3824,7 @@ void sqlite3pager_dont_rollback(void *pData){
 ** and an error code is returned.  If the commit worked, SQLITE_OK
 ** is returned.
 */
-int sqlite3pager_commit(Pager *pPager){
+int sqlite3PagerCommitPhaseTwo(Pager *pPager){
   int rc;
   PgHdr *pPg;
 
@@ -3361,16 +3834,17 @@ int sqlite3pager_commit(Pager *pPager){
   if( pPager->state<PAGER_RESERVED ){
     return SQLITE_ERROR;
   }
-  TRACE2("COMMIT %d\n", PAGERID(pPager));
+  PAGERTRACE2("COMMIT %d\n", PAGERID(pPager));
   if( MEMDB ){
     pPg = pager_get_all_dirty_pages(pPager);
     while( pPg ){
-      clearHistory(PGHDR_TO_HIST(pPg, pPager));
+      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+      clearHistory(pHist);
       pPg->dirty = 0;
       pPg->inJournal = 0;
-      pPg->inStmt = 0;
+      pHist->inStmt = 0;
       pPg->needSync = 0;
-      pPg->pPrevStmt = pPg->pNextStmt = 0;
+      pHist->pPrevStmt = pHist->pNextStmt = 0;
       pPg = pPg->pDirty;
     }
     pPager->pDirty = 0;
@@ -3386,19 +3860,10 @@ int sqlite3pager_commit(Pager *pPager){
     pPager->state = PAGER_SHARED;
     return SQLITE_OK;
   }
-  if( pPager->dirtyCache==0 ){
-    /* Exit early (without doing the time-consuming sqlite3OsSync() calls)
-    ** if there have been no changes to the database file. */
-    assert( pPager->needSync==0 );
-    rc = pager_unwritelock(pPager);
-    return rc;
-  }
-  assert( pPager->journalOpen );
-  rc = sqlite3pager_sync(pPager, 0, 0);
-  if( rc==SQLITE_OK ){
-    rc = pager_unwritelock(pPager);
-  }
-  return rc;
+  assert( pPager->journalOpen || !pPager->dirtyCache );
+  assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache );
+  rc = pager_end_transaction(pPager);
+  return pager_error(pPager, rc);
 }
 
 /*
@@ -3407,15 +3872,15 @@ int sqlite3pager_commit(Pager *pPager){
 ** The journal is deleted.
 **
 ** This routine cannot fail unless some other process is not following
-** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
+** the correct locking protocol or unless some other
 ** process is writing trash into the journal file (SQLITE_CORRUPT) or
 ** unless a prior malloc() failed (SQLITE_NOMEM).  Appropriate error
 ** codes are returned for all these occasions.  Otherwise,
 ** SQLITE_OK is returned.
 */
-int sqlite3pager_rollback(Pager *pPager){
+int sqlite3PagerRollback(Pager *pPager){
   int rc;
-  TRACE2("ROLLBACK %d\n", PAGERID(pPager));
+  PAGERTRACE2("ROLLBACK %d\n", PAGERID(pPager));
   if( MEMDB ){
     PgHdr *p;
     for(p=pPager->pAll; p; p=p->pNextAll){
@@ -3430,49 +3895,50 @@ int sqlite3pager_rollback(Pager *pPager){
       pHist = PGHDR_TO_HIST(p, pPager);
       if( pHist->pOrig ){
         memcpy(PGHDR_TO_DATA(p), pHist->pOrig, pPager->pageSize);
-        TRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager));
+        PAGERTRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager));
       }else{
-        TRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager));
+        PAGERTRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager));
       }
       clearHistory(pHist);
       p->dirty = 0;
       p->inJournal = 0;
-      p->inStmt = 0;
-      p->pPrevStmt = p->pNextStmt = 0;
+      pHist->inStmt = 0;
+      pHist->pPrevStmt = pHist->pNextStmt = 0;
       if( pPager->xReiniter ){
-        pPager->xReiniter(PGHDR_TO_DATA(p), pPager->pageSize);
+        pPager->xReiniter(p, pPager->pageSize);
       }
     }
     pPager->pDirty = 0;
     pPager->pStmt = 0;
     pPager->dbSize = pPager->origDbSize;
-    memoryTruncate(pPager);
+    pager_truncate_cache(pPager);
     pPager->stmtInUse = 0;
     pPager->state = PAGER_SHARED;
     return SQLITE_OK;
   }
 
   if( !pPager->dirtyCache || !pPager->journalOpen ){
-    rc = pager_unwritelock(pPager);
+    rc = pager_end_transaction(pPager);
     return rc;
   }
 
   if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
     if( pPager->state>=PAGER_EXCLUSIVE ){
-      pager_playback(pPager);
+      pager_playback(pPager, 0);
     }
     return pPager->errCode;
   }
   if( pPager->state==PAGER_RESERVED ){
     int rc2;
-    rc = pager_reload_cache(pPager);
-    rc2 = pager_unwritelock(pPager);
+    rc = pager_playback(pPager, 0);
+    rc2 = pager_end_transaction(pPager);
     if( rc==SQLITE_OK ){
       rc = rc2;
     }
   }else{
-    rc = pager_playback(pPager);
+    rc = pager_playback(pPager, 0);
   }
+  /* pager_reset(pPager); */
   pPager->dbSize = -1;
 
   /* If an error occurs during a ROLLBACK, we can no longer trust the pager
@@ -3486,14 +3952,14 @@ int sqlite3pager_rollback(Pager *pPager){
 ** Return TRUE if the database file is opened read-only.  Return FALSE
 ** if the database is (in theory) writable.
 */
-int sqlite3pager_isreadonly(Pager *pPager){
+int sqlite3PagerIsreadonly(Pager *pPager){
   return pPager->readOnly;
 }
 
 /*
 ** Return the number of references to the pager.
 */
-int sqlite3pager_refcount(Pager *pPager){
+int sqlite3PagerRefcount(Pager *pPager){
   return pPager->nRef;
 }
 
@@ -3501,7 +3967,7 @@ int sqlite3pager_refcount(Pager *pPager){
 /*
 ** This routine is used for testing and analysis only.
 */
-int *sqlite3pager_stats(Pager *pPager){
+int *sqlite3PagerStats(Pager *pPager){
   static int a[11];
   a[0] = pPager->nRef;
   a[1] = pPager->nPage;
@@ -3511,7 +3977,7 @@ int *sqlite3pager_stats(Pager *pPager){
   a[5] = pPager->errCode;
   a[6] = pPager->nHit;
   a[7] = pPager->nMiss;
-  a[8] = pPager->nOvfl;
+  a[8] = 0;  /* Used to be pPager->nOvfl */
   a[9] = pPager->nRead;
   a[10] = pPager->nWrite;
   return a;
@@ -3525,13 +3991,12 @@ int *sqlite3pager_stats(Pager *pPager){
 ** open.  A new statement journal is created that can be used to rollback
 ** changes of a single SQL command within a larger transaction.
 */
-int sqlite3pager_stmt_begin(Pager *pPager){
+int sqlite3PagerStmtBegin(Pager *pPager){
   int rc;
-  char zTemp[SQLITE_TEMPNAME_SIZE];
   assert( !pPager->stmtInUse );
   assert( pPager->state>=PAGER_SHARED );
   assert( pPager->dbSize>=0 );
-  TRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
+  PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
   if( MEMDB ){
     pPager->stmtInUse = 1;
     pPager->stmtSize = pPager->dbSize;
@@ -3557,7 +4022,7 @@ int sqlite3pager_stmt_begin(Pager *pPager){
   pPager->stmtHdrOff = 0;
   pPager->stmtCksum = pPager->cksumInit;
   if( !pPager->stmtOpen ){
-    rc = sqlite3pager_opentemp(zTemp, &pPager->stfd);
+    rc = sqlite3PagerOpentemp(&pPager->stfd);
     if( rc ) goto stmt_begin_failed;
     pPager->stmtOpen = 1;
     pPager->stmtNRec = 0;
@@ -3576,23 +4041,22 @@ stmt_begin_failed:
 /*
 ** Commit a statement.
 */
-int sqlite3pager_stmt_commit(Pager *pPager){
+int sqlite3PagerStmtCommit(Pager *pPager){
   if( pPager->stmtInUse ){
     PgHdr *pPg, *pNext;
-    TRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
+    PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
     if( !MEMDB ){
       sqlite3OsSeek(pPager->stfd, 0);
       /* sqlite3OsTruncate(pPager->stfd, 0); */
       sqliteFree( pPager->aInStmt );
       pPager->aInStmt = 0;
-    }
-    for(pPg=pPager->pStmt; pPg; pPg=pNext){
-      pNext = pPg->pNextStmt;
-      assert( pPg->inStmt );
-      pPg->inStmt = 0;
-      pPg->pPrevStmt = pPg->pNextStmt = 0;
-      if( MEMDB ){
+    }else{
+      for(pPg=pPager->pStmt; pPg; pPg=pNext){
         PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+        pNext = pHist->pNextStmt;
+        assert( pHist->inStmt );
+        pHist->inStmt = 0;
+        pHist->pPrevStmt = pHist->pNextStmt = 0;
         sqliteFree(pHist->pStmt);
         pHist->pStmt = 0;
       }
@@ -3608,14 +4072,15 @@ int sqlite3pager_stmt_commit(Pager *pPager){
 /*
 ** Rollback a statement.
 */
-int sqlite3pager_stmt_rollback(Pager *pPager){
+int sqlite3PagerStmtRollback(Pager *pPager){
   int rc;
   if( pPager->stmtInUse ){
-    TRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
+    PAGERTRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
     if( MEMDB ){
       PgHdr *pPg;
-      for(pPg=pPager->pStmt; pPg; pPg=pPg->pNextStmt){
-        PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+      PgHistory *pHist;
+      for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){
+        pHist = PGHDR_TO_HIST(pPg, pPager);
         if( pHist->pStmt ){
           memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize);
           sqliteFree(pHist->pStmt);
@@ -3623,12 +4088,12 @@ int sqlite3pager_stmt_rollback(Pager *pPager){
         }
       }
       pPager->dbSize = pPager->stmtSize;
-      memoryTruncate(pPager);
+      pager_truncate_cache(pPager);
       rc = SQLITE_OK;
     }else{
       rc = pager_stmt_playback(pPager);
     }
-    sqlite3pager_stmt_commit(pPager);
+    sqlite3PagerStmtCommit(pPager);
   }else{
     rc = SQLITE_OK;
   }
@@ -3639,21 +4104,21 @@ int sqlite3pager_stmt_rollback(Pager *pPager){
 /*
 ** Return the full pathname of the database file.
 */
-const char *sqlite3pager_filename(Pager *pPager){
+const char *sqlite3PagerFilename(Pager *pPager){
   return pPager->zFilename;
 }
 
 /*
 ** Return the directory of the database file.
 */
-const char *sqlite3pager_dirname(Pager *pPager){
+const char *sqlite3PagerDirname(Pager *pPager){
   return pPager->zDirectory;
 }
 
 /*
 ** Return the full pathname of the journal file.
 */
-const char *sqlite3pager_journalname(Pager *pPager){
+const char *sqlite3PagerJournalname(Pager *pPager){
   return pPager->zJournal;
 }
 
@@ -3661,14 +4126,15 @@ const char *sqlite3pager_journalname(Pager *pPager){
 ** Return true if fsync() calls are disabled for this pager.  Return FALSE
 ** if fsync()s are executed normally.
 */
-int sqlite3pager_nosync(Pager *pPager){
+int sqlite3PagerNosync(Pager *pPager){
   return pPager->noSync;
 }
 
+#ifdef SQLITE_HAS_CODEC
 /*
 ** Set the codec for this pager
 */
-void sqlite3pager_set_codec(
+void sqlite3PagerSetCodec(
   Pager *pPager,
   void *(*xCodec)(void*,void*,Pgno,int),
   void *pCodecArg
@@ -3676,126 +4142,7 @@ void sqlite3pager_set_codec(
   pPager->xCodec = xCodec;
   pPager->pCodecArg = pCodecArg;
 }
-
-/*
-** This routine is called to increment the database file change-counter,
-** stored at byte 24 of the pager file.
-*/
-static int pager_incr_changecounter(Pager *pPager){
-  void *pPage;
-  PgHdr *pPgHdr;
-  u32 change_counter;
-  int rc;
-
-  /* Open page 1 of the file for writing. */
-  rc = sqlite3pager_get(pPager, 1, &pPage);
-  if( rc!=SQLITE_OK ) return rc;
-  rc = sqlite3pager_write(pPage);
-  if( rc!=SQLITE_OK ) return rc;
-
-  /* Read the current value at byte 24. */
-  pPgHdr = DATA_TO_PGHDR(pPage);
-  change_counter = retrieve32bits(pPgHdr, 24);
-
-  /* Increment the value just read and write it back to byte 24. */
-  change_counter++;
-  put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
-
-  /* Release the page reference. */
-  sqlite3pager_unref(pPage);
-  return SQLITE_OK;
-}
-
-/*
-** Sync the database file for the pager pPager. zMaster points to the name
-** of a master journal file that should be written into the individual
-** journal file. zMaster may be NULL, which is interpreted as no master
-** journal (a single database transaction).
-**
-** This routine ensures that the journal is synced, all dirty pages written
-** to the database file and the database file synced. The only thing that
-** remains to commit the transaction is to delete the journal file (or
-** master journal file if specified).
-**
-** Note that if zMaster==NULL, this does not overwrite a previous value
-** passed to an sqlite3pager_sync() call.
-**
-** If parameter nTrunc is non-zero, then the pager file is truncated to
-** nTrunc pages (this is used by auto-vacuum databases).
-*/
-int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){
-  int rc = SQLITE_OK;
-
-  TRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", 
-      pPager->zFilename, zMaster, nTrunc);
-
-  /* If this is an in-memory db, or no pages have been written to, or this
-  ** function has already been called, it is a no-op.
-  */
-  if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
-    PgHdr *pPg;
-    assert( pPager->journalOpen );
-
-    /* If a master journal file name has already been written to the
-    ** journal file, then no sync is required. This happens when it is
-    ** written, then the process fails to upgrade from a RESERVED to an
-    ** EXCLUSIVE lock. The next time the process tries to commit the
-    ** transaction the m-j name will have already been written.
-    */
-    if( !pPager->setMaster ){
-      rc = pager_incr_changecounter(pPager);
-      if( rc!=SQLITE_OK ) goto sync_exit;
-#ifndef SQLITE_OMIT_AUTOVACUUM
-      if( nTrunc!=0 ){
-        /* If this transaction has made the database smaller, then all pages
-        ** being discarded by the truncation must be written to the journal
-        ** file.
-        */
-        Pgno i;
-        void *pPage;
-        int iSkip = PAGER_MJ_PGNO(pPager);
-        for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
-          if( !(pPager->aInJournal[i/8] & (1<<(i&7))) && i!=iSkip ){
-            rc = sqlite3pager_get(pPager, i, &pPage);
-            if( rc!=SQLITE_OK ) goto sync_exit;
-            rc = sqlite3pager_write(pPage);
-            sqlite3pager_unref(pPage);
-            if( rc!=SQLITE_OK ) goto sync_exit;
-          }
-        } 
-      }
 #endif
-      rc = writeMasterJournal(pPager, zMaster);
-      if( rc!=SQLITE_OK ) goto sync_exit;
-      rc = syncJournal(pPager);
-      if( rc!=SQLITE_OK ) goto sync_exit;
-    }
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-    if( nTrunc!=0 ){
-      rc = sqlite3pager_truncate(pPager, nTrunc);
-      if( rc!=SQLITE_OK ) goto sync_exit;
-    }
-#endif
-
-    /* Write all dirty pages to the database file */
-    pPg = pager_get_all_dirty_pages(pPager);
-    rc = pager_write_pagelist(pPg);
-    if( rc!=SQLITE_OK ) goto sync_exit;
-
-    /* Sync the database file. */
-    if( !pPager->noSync ){
-      rc = sqlite3OsSync(pPager->fd, 0);
-    }
-
-    pPager->state = PAGER_SYNCED;
-  }else if( MEMDB && nTrunc!=0 ){
-    rc = sqlite3pager_truncate(pPager, nTrunc);
-  }
-
-sync_exit:
-  return rc;
-}
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
@@ -3815,16 +4162,16 @@ sync_exit:
 ** has been removed (CREATE INDEX needs to move a page when a statement
 ** transaction is active).
 */
-int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
-  PgHdr *pPg = DATA_TO_PGHDR(pData);
+int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
   PgHdr *pPgOld; 
   int h;
   Pgno needSyncPgno = 0;
 
   assert( pPg->nRef>0 );
 
-  TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
+  PAGERTRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
       PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);
+  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
 
   if( pPg->needSync ){
     needSyncPgno = pPg->pgno;
@@ -3876,32 +4223,70 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
     ** Pager.aInJournal bit has been set. This needs to be remedied by loading
     ** the page into the pager-cache and setting the PgHdr.needSync flag.
     **
-    ** The sqlite3pager_get() call may cause the journal to sync. So make
+    ** The sqlite3PagerGet() call may cause the journal to sync. So make
     ** sure the Pager.needSync flag is set too.
     */
     int rc;
-    void *pNeedSync;
+    PgHdr *pPgHdr;
     assert( pPager->needSync );
-    rc = sqlite3pager_get(pPager, needSyncPgno, &pNeedSync);
+    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
     if( rc!=SQLITE_OK ) return rc;
     pPager->needSync = 1;
-    DATA_TO_PGHDR(pNeedSync)->needSync = 1;
-    DATA_TO_PGHDR(pNeedSync)->inJournal = 1;
-    makeDirty(DATA_TO_PGHDR(pNeedSync));
-    sqlite3pager_unref(pNeedSync);
+    pPgHdr->needSync = 1;
+    pPgHdr->inJournal = 1;
+    makeDirty(pPgHdr);
+    sqlite3PagerUnref(pPgHdr);
   }
 
   return SQLITE_OK;
 }
 #endif
 
+/*
+** Return a pointer to the data for the specified page.
+*/
+void *sqlite3PagerGetData(DbPage *pPg){
+  return PGHDR_TO_DATA(pPg);
+}
+
+/*
+** Return a pointer to the Pager.nExtra bytes of "extra" space 
+** allocated along with the specified page.
+*/
+void *sqlite3PagerGetExtra(DbPage *pPg){
+  Pager *pPager = pPg->pPager;
+  return (pPager?PGHDR_TO_EXTRA(pPg, pPager):0);
+}
+
+/*
+** Get/set the locking-mode for this pager. Parameter eMode must be one
+** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or 
+** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
+** the locking-mode is set to the value specified.
+**
+** The returned value is either PAGER_LOCKINGMODE_NORMAL or
+** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
+** locking-mode.
+*/
+int sqlite3PagerLockingMode(Pager *pPager, int eMode){
+  assert( eMode==PAGER_LOCKINGMODE_QUERY
+            || eMode==PAGER_LOCKINGMODE_NORMAL
+            || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
+  assert( PAGER_LOCKINGMODE_QUERY<0 );
+  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
+  if( eMode>=0 && !pPager->tempFile ){
+    pPager->exclusiveMode = eMode;
+  }
+  return (int)pPager->exclusiveMode;
+}
+
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
 /*
 ** Return the current state of the file lock for the given pager.
 ** The return value is one of NO_LOCK, SHARED_LOCK, RESERVED_LOCK,
 ** PENDING_LOCK, or EXCLUSIVE_LOCK.
 */
-int sqlite3pager_lockstate(Pager *pPager){
+int sqlite3PagerLockstate(Pager *pPager){
   return sqlite3OsLockState(pPager->fd);
 }
 #endif
@@ -3910,7 +4295,7 @@ int sqlite3pager_lockstate(Pager *pPager){
 /*
 ** Print a listing of all referenced pages and their ref count.
 */
-void sqlite3pager_refdump(Pager *pPager){
+void sqlite3PagerRefdump(Pager *pPager){
   PgHdr *pPg;
   for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
     if( pPg->nRef<=0 ) continue;
index 7626ff6bbd73be16851113b1b9283698c036f779..104a795982b014e7806bac5b3e280a9be6e7f944 100644 (file)
@@ -57,67 +57,91 @@ typedef unsigned int Pgno;
 typedef struct Pager Pager;
 
 /*
-** Allowed values for the flags parameter to sqlite3pager_open().
+** Handle type for pages.
+*/
+typedef struct PgHdr DbPage;
+
+/*
+** Allowed values for the flags parameter to sqlite3PagerOpen().
 **
 ** NOTE: This values must match the corresponding BTREE_ values in btree.h.
 */
 #define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
 #define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */
 
+/*
+** Valid values for the second argument to sqlite3PagerLockingMode().
+*/
+#define PAGER_LOCKINGMODE_QUERY      -1
+#define PAGER_LOCKINGMODE_NORMAL      0
+#define PAGER_LOCKINGMODE_EXCLUSIVE   1
 
 /*
 ** See source code comments for a detailed description of the following
 ** routines:
 */
-int sqlite3pager_open(Pager **ppPager, const char *zFilename,
+int sqlite3PagerOpen(Pager **ppPager, const char *zFilename,
                      int nExtra, int flags);
-void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
-void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
-void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
-int sqlite3pager_set_pagesize(Pager*, int);
-int sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
-void sqlite3pager_set_cachesize(Pager*, int);
-int sqlite3pager_close(Pager *pPager);
-int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
-void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
-int sqlite3pager_ref(void*);
-int sqlite3pager_unref(void*);
-Pgno sqlite3pager_pagenumber(void*);
-int sqlite3pager_write(void*);
-int sqlite3pager_iswriteable(void*);
-int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*);
-int sqlite3pager_pagecount(Pager*);
-int sqlite3pager_truncate(Pager*,Pgno);
-int sqlite3pager_begin(void*, int exFlag);
-int sqlite3pager_commit(Pager*);
-int sqlite3pager_sync(Pager*,const char *zMaster, Pgno);
-int sqlite3pager_rollback(Pager*);
-int sqlite3pager_isreadonly(Pager*);
-int sqlite3pager_stmt_begin(Pager*);
-int sqlite3pager_stmt_commit(Pager*);
-int sqlite3pager_stmt_rollback(Pager*);
-void sqlite3pager_dont_rollback(void*);
-void sqlite3pager_dont_write(Pager*, Pgno);
-int sqlite3pager_refcount(Pager*);
-int *sqlite3pager_stats(Pager*);
-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*);
-int sqlite3pager_movepage(Pager*,void*,Pgno);
-int sqlite3pager_reset(Pager*);
-int sqlite3pager_release_memory(int);
+void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler);
+void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int));
+void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int));
+int sqlite3PagerSetPagesize(Pager*, int);
+int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
+void sqlite3PagerSetCachesize(Pager*, int);
+int sqlite3PagerClose(Pager *pPager);
+int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
+#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
+DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
+int sqlite3PagerRef(DbPage*);
+int sqlite3PagerUnref(DbPage*);
+Pgno sqlite3PagerPagenumber(DbPage*);
+int sqlite3PagerWrite(DbPage*);
+int sqlite3PagerIswriteable(DbPage*);
+int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void*);
+int sqlite3PagerPagecount(Pager*);
+int sqlite3PagerTruncate(Pager*,Pgno);
+int sqlite3PagerBegin(DbPage*, int exFlag);
+int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, Pgno);
+int sqlite3PagerCommitPhaseTwo(Pager*);
+int sqlite3PagerRollback(Pager*);
+int sqlite3PagerIsreadonly(Pager*);
+int sqlite3PagerStmtBegin(Pager*);
+int sqlite3PagerStmtCommit(Pager*);
+int sqlite3PagerStmtRollback(Pager*);
+void sqlite3PagerDontRollback(DbPage*);
+void sqlite3PagerDontWrite(Pager*, Pgno);
+int sqlite3PagerRefcount(Pager*);
+int *sqlite3PagerStats(Pager*);
+void sqlite3PagerSetSafetyLevel(Pager*,int,int);
+const char *sqlite3PagerFilename(Pager*);
+const char *sqlite3PagerDirname(Pager*);
+const char *sqlite3PagerJournalname(Pager*);
+int sqlite3PagerNosync(Pager*);
+int sqlite3PagerRename(Pager*, const char *zNewName);
+void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
+int sqlite3PagerMovepage(Pager*,DbPage*,Pgno);
+int sqlite3PagerReset(Pager*);
+int sqlite3PagerReleaseMemory(int);
+
+void *sqlite3PagerGetData(DbPage *); 
+void *sqlite3PagerGetExtra(DbPage *); 
+int sqlite3PagerLockingMode(Pager *, int);
 
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
-int sqlite3pager_lockstate(Pager*);
+int sqlite3PagerLockstate(Pager*);
 #endif
 
 #ifdef SQLITE_TEST
-void sqlite3pager_refdump(Pager*);
+void sqlite3PagerRefdump(Pager*);
 int pager3_refinfo_enable;
 #endif
 
+#ifdef SQLITE_TEST
+void disable_simulated_io_errors(void);
+void enable_simulated_io_errors(void);
+#else
+# define disable_simulated_io_errors()
+# define enable_simulated_io_errors()
+#endif
+
 #endif /* _PAGER_H_ */
index 64672402ddf401628efa03233adb576db504614e..f074c578f3ea66d583afb06809f587c2616e9fc6 100644 (file)
@@ -4,7 +4,7 @@
 /* First off, code is include which follows the "include" declaration
 ** in the input file. */
 #include <stdio.h>
-#line 56 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 56 "parse.y"
 
 #include "sqliteInt.h"
 #include "parse.h"
@@ -43,7 +43,7 @@ struct TrigEvent { int a; IdList * b; };
 */
 struct AttachKey { int type;  Token key; };
 
-#line 48 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 48 "parse.c"
 /* Next is all token values, in a form suitable for use by makeheaders.
 ** This section will be null unless lemon is run with the -m switch.
 */
@@ -82,7 +82,8 @@ struct AttachKey { int type;  Token key; };
 **                       This is typically a union of many types, one of
 **                       which is sqlite3ParserTOKENTYPE.  The entry in the union
 **                       for base tokens is called "yy0".
-**    YYSTACKDEPTH       is the maximum depth of the parser's stack.
+**    YYSTACKDEPTH       is the maximum depth of the parser's stack.  If
+**                       zero the stack is dynamically sized using realloc()
 **    sqlite3ParserARG_SDECL     A static variable declaration for the %extra_argument
 **    sqlite3ParserARG_PDECL     A parameter declaration for the %extra_argument
 **    sqlite3ParserARG_STORE     Code to store %extra_argument into yypParser
@@ -93,36 +94,38 @@ struct AttachKey { int type;  Token key; };
 **                       defined, then do no error processing.
 */
 #define YYCODETYPE unsigned char
-#define YYNOCODE 249
+#define YYNOCODE 248
 #define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 60
+#define YYWILDCARD 59
 #define sqlite3ParserTOKENTYPE Token
 typedef union {
   sqlite3ParserTOKENTYPE yy0;
-  Select* yy43;
-  TriggerStep* yy75;
-  struct LimitVal yy84;
-  struct LikeOp yy86;
-  Expr * yy158;
-  Token yy178;
-  struct {int value; int mask;} yy207;
-  ExprList* yy242;
-  int yy316;
-  IdList* yy352;
-  struct TrigEvent yy354;
-  SrcList* yy419;
-  Expr* yy450;
-  int yy497;
+  int yy46;
+  struct LikeOp yy72;
+  Expr* yy172;
+  ExprList* yy174;
+  Select* yy219;
+  struct LimitVal yy234;
+  TriggerStep* yy243;
+  struct TrigEvent yy370;
+  SrcList* yy373;
+  Expr * yy386;
+  struct {int value; int mask;} yy405;
+  Token yy410;
+  IdList* yy432;
+  int yy495;
 } YYMINORTYPE;
+#ifndef YYSTACKDEPTH
 #define YYSTACKDEPTH 100
+#endif
 #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 587
-#define YYNRULE 312
-#define YYERRORSYMBOL 139
-#define YYERRSYMDT yy497
+#define YYNSTATE 586
+#define YYNRULE 311
+#define YYERRORSYMBOL 138
+#define YYERRSYMDT yy495
 #define YYFALLBACK 1
 #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
 #define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
@@ -176,415 +179,415 @@ typedef union {
 **  yy_default[]       Default action for each state.
 */
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   289,  900,  121,  586,  205,  169,    2,  435,   61,   61,
- /*    10 */    61,   61,  435,   63,   63,   63,   63,   64,   64,   65,
- /*    20 */    65,   65,   66,  230,  198,  299,  420,  426,   68,   63,
+ /*     0 */   289,  898,  121,  585,  405,  169,    2,  435,   61,   61,
+ /*    10 */    61,   61,  517,   63,   63,   63,   63,   64,   64,   65,
+ /*    20 */    65,   65,   66,  230,  387,  384,  420,  426,   68,   63,
  /*    30 */    63,   63,   63,   64,   64,   65,   65,   65,   66,  230,
- /*    40 */    67,  447,   69,  151,  230,   60,   59,  294,  430,  431,
- /*    50 */   427,  427,   62,   62,   61,   61,   61,   61,  411,   63,
- /*    60 */    63,   63,   63,   64,   64,   65,   65,   65,   66,  230,
- /*    70 */   289,  487,  515,  435,  570,  415,   80,   67,  435,   69,
- /*    80 */   151,   63,   63,   63,   63,   64,   64,   65,   65,   65,
- /*    90 */    66,  230,  569,  568,  248,  386,  420,  426,    2,  572,
- /*   100 */    58,  115,  238,  340,  243,  341,  173,  417,  417,  417,
- /*   110 */   570,  387,  384,  249,  289,   60,   59,  294,  430,  431,
- /*   120 */   427,  427,   62,   62,   61,   61,   61,   61,  569,   63,
- /*   130 */    63,   63,   63,   64,   64,   65,   65,   65,   66,  230,
- /*   140 */   420,  426,   92,   64,   64,   65,   65,   65,   66,  230,
- /*   150 */   245,  392,   56,  171,  566,  207,  406,  443,  208,   60,
- /*   160 */    59,  294,  430,  431,  427,  427,   62,   62,   61,   61,
- /*   170 */    61,   61,  205,   63,   63,   63,   63,   64,   64,   65,
- /*   180 */    65,   65,   66,  230,  289,  368,  522,  411,  522,  111,
- /*   190 */   378,  207,  447,  467,  223,  403,   21,  532,   21,  172,
- /*   200 */   157,  317,   66,  230,  336,  404,  520,  443,  208,  486,
- /*   210 */   420,  426,  146,  147,  517,  488,  489,  393,  394,  148,
- /*   220 */   531,  224,  487,  410,   41,  407,  415,  567,  289,   60,
- /*   230 */    59,  294,  430,  431,  427,  427,   62,   62,   61,   61,
- /*   240 */    61,   61,  476,   63,   63,   63,   63,   64,   64,   65,
- /*   250 */    65,   65,   66,  230,  420,  426,  491,  492,  417,  417,
- /*   260 */   417,  155,  549,  331,  211,   65,   65,   65,   66,  230,
- /*   270 */   546,  492,  289,   60,   59,  294,  430,  431,  427,  427,
- /*   280 */    62,   62,   61,   61,   61,   61,  467,   63,   63,   63,
- /*   290 */    63,   64,   64,   65,   65,   65,   66,  230,  420,  426,
- /*   300 */   548,  299,  178,  297,  522,  342,  345,  346,  472,   67,
- /*   310 */   460,   69,  151,  577,   21,  338,  347,   60,   59,  294,
- /*   320 */   430,  431,  427,  427,   62,   62,   61,   61,   61,   61,
- /*   330 */   530,   63,   63,   63,   63,   64,   64,   65,   65,   65,
- /*   340 */    66,  230,  409,  523,   76,  289,  408,  478,  452,  482,
- /*   350 */   392,  369,  266,  265,  283,  149,  405,  445,  521,  165,
- /*   360 */   453,  317,  205,   67,  517,   69,  151,  529,  503,  152,
- /*   370 */   248,  420,  426,  454,  528,  493,  161,  115,  238,  340,
- /*   380 */   243,  341,  173,  410,   35,  494,  580,  288,   79,  249,
- /*   390 */    60,   59,  294,  430,  431,  427,  427,   62,   62,   61,
- /*   400 */    61,   61,   61,  411,   63,   63,   63,   63,   64,   64,
- /*   410 */    65,   65,   65,   66,  230,  289,  393,  394,  178,  485,
- /*   420 */   508,  342,  345,  346,  178,  296,  317,  342,  345,  346,
- /*   430 */   366,  317,  347,   20,  317,  141,  317,  457,  347,  150,
- /*   440 */   509,  420,  426,   22,  295,  438,  439,  435,  410,   35,
- /*   450 */   328,  260,  472,  410,   28,  232,  410,   35,  410,   36,
- /*   460 */    60,   59,  294,  430,  431,  427,  427,   62,   62,   61,
- /*   470 */    61,   61,   61,  411,   63,   63,   63,   63,   64,   64,
- /*   480 */    65,   65,   65,   66,  230,  289,  436,  481,   23,  502,
- /*   490 */   298,  234,  380,  301,  317,  217,  317,  476,  333,  317,
- /*   500 */   392,  317,  457,  337,  168,  157,  421,  422,  207,  231,
- /*   510 */   457,  420,  426,  435,  313,  388,  410,   35,  410,   49,
- /*   520 */   204,  410,   41,  410,   49,  410,    3,  197,  424,  425,
- /*   530 */    60,   59,  294,  430,  431,  427,  427,   62,   62,   61,
- /*   540 */    61,   61,   61,  382,   63,   63,   63,   63,   64,   64,
- /*   550 */    65,   65,   65,   66,  230,  289,  443,  423,  357,  252,
- /*   560 */   434,  411,  210,  292,  308,  350,  393,  394,  448,  309,
- /*   570 */   456,  322,  438,  439,  320,    1,  433,  433,   19,  392,
- /*   580 */   541,  420,  426,  191,  540,  375,  584,  891,  543,  891,
- /*   590 */   584,  890,  174,  890,  472,  392,  358,  445,  323,  165,
- /*   600 */    60,   59,  294,  430,  431,  427,  427,   62,   62,   61,
- /*   610 */    61,   61,   61,  383,   63,   63,   63,   63,   64,   64,
- /*   620 */    65,   65,   65,   66,  230,  289,  370,  581,    9,  452,
- /*   630 */    91,  581,   10,  236,  409,  207,  392,  359,  408,  392,
- /*   640 */   156,  453,  169,  362,  435,  393,  394,  320,  291,  433,
- /*   650 */   433,  420,  426,  249,  454,  320,  327,  433,  433,  260,
- /*   660 */   462,  393,  394,  515,  515,  545,  515,  463,  270,  289,
- /*   670 */    60,   59,  294,  430,  431,  427,  427,   62,   62,   61,
- /*   680 */    61,   61,   61,   82,   63,   63,   63,   63,   64,   64,
- /*   690 */    65,   65,   65,   66,  230,  420,  426,  480,  302,  216,
- /*   700 */   261,  303,  393,  394,  822,  393,  394,  273,  515,  271,
- /*   710 */   435,  515,  334,  289,   60,   59,  294,  430,  431,  427,
- /*   720 */   427,   62,   62,   61,   61,   61,   61,  233,   63,   63,
- /*   730 */    63,   63,   64,   64,   65,   65,   65,   66,  230,  420,
- /*   740 */   426,  247,  247,  304,  247,  318,  306,  587,  387,  384,
- /*   750 */   395,  396,  397,  320,  219,  433,  433,  289,   60,   70,
- /*   760 */   294,  430,  431,  427,  427,   62,   62,   61,   61,   61,
- /*   770 */    61,  317,   63,   63,   63,   63,   64,   64,   65,   65,
- /*   780 */    65,   66,  230,  420,  426,  476,  247,  391,  272,  247,
- /*   790 */   539,  356,  539,  410,   29,  175,  176,  177,  162,  260,
- /*   800 */   260,  289,    5,   59,  294,  430,  431,  427,  427,   62,
- /*   810 */    62,   61,   61,   61,   61,  377,   63,   63,   63,   63,
- /*   820 */    64,   64,   65,   65,   65,   66,  230,  420,  426,  392,
- /*   830 */   311,  120,  392,  319,  205,  260,  366,  465,  254,  189,
- /*   840 */   556,  558,  260,   75,  260,   77,  307,  376,  294,  430,
- /*   850 */   431,  427,  427,   62,   62,   61,   61,   61,   61,  260,
- /*   860 */    63,   63,   63,   63,   64,   64,   65,   65,   65,   66,
- /*   870 */   230,   72,  324,  411,    4,  260,  559,  258,  293,  256,
- /*   880 */   174,  125,  317,  560,  317,  274,  321,   72,  324,  193,
- /*   890 */     4,  153,  621,  180,  293,  393,  394,  367,  393,  394,
- /*   900 */   374,  218,  321,  326,  410,   24,  410,   33,  183,  317,
- /*   910 */   428,  206,  441,  441,  447,  317,  276,  317,   55,  326,
- /*   920 */   363,  468,  239,  411,  469,  411,  455,  411,   13,  144,
- /*   930 */   447,  410,   53,  240,   74,   73,  291,  410,   52,  410,
- /*   940 */    96,  116,  411,   72,  315,  316,  582,  474,  415,  170,
- /*   950 */    74,   73,  479,  317,  507,  506,  317,  500,  416,   72,
- /*   960 */   315,  316,   72,  324,  415,    4,  205,  317,  329,  293,
- /*   970 */   317,  458,  483,  444,   13,  410,   94,  321,  410,   99,
- /*   980 */   417,  417,  417,  418,  419,   12,  583,  466,  317,  410,
- /*   990 */   100,  471,  410,  110,  326,  475,  417,  417,  417,  418,
- /*  1000 */   419,   12,  497,  498,  512,  447,  125,  159,  244,  317,
- /*  1010 */   410,  112,  220,  221,  222,  102,  537,  538,  317,  251,
- /*  1020 */   317,  125,  317,  504,  505,   74,   73,  349,  202,  125,
- /*  1030 */   278,  410,   17,  510,   72,  315,  316,  279,  524,  415,
- /*  1040 */   410,   97,  410,   34,  410,   95,  317,  511,  544,  200,
- /*  1050 */   125,  548,  552,  253,  170,  317,  199,  255,  317,  201,
- /*  1060 */   553,  257,   89,  317,  259,  563,  317,   89,  410,   25,
- /*  1070 */   317,  417,  417,  417,  418,  419,   12,  410,   54,  186,
- /*  1080 */   410,  113,  354,  317,  264,  410,  114,  317,  410,   26,
- /*  1090 */   361,  364,  410,   37,  579,  365,  287,  317,  267,  317,
- /*  1100 */   143,  317,  373,  275,  265,  410,   38,  268,  290,  410,
- /*  1110 */    27,  317,  269,  205,  555,  565,  317,  277,  317,  410,
- /*  1120 */    39,  410,   40,  410,   42,  317,  280,  317,  281,  317,
- /*  1130 */   576,  317,  225,  410,   43,  401,  503,  379,  410,   44,
- /*  1140 */   410,   30,  317,  325,  440,  317,  461,  410,   31,  410,
- /*  1150 */    45,  410,   46,  410,   47,  442,  317,  551,  317,  464,
- /*  1160 */   317,  241,  513,  516,  410,   48,  344,  410,   32,  562,
- /*  1170 */   160,  390,  398,  399,  400,    8,  314,  412,  410,   11,
- /*  1180 */   410,   50,  410,   51,   82,  332,  226,   81,  330,  227,
- /*  1190 */    57,  406,  414,  228,   78,  167,  229,  209,   83,  413,
- /*  1200 */   459,  122,  335,  339,  500,  490,  235,  495,  242,  473,
- /*  1210 */   237,  300,  477,  499,  496,  501,  103,  284,  246,  514,
- /*  1220 */   518,  519,  525,  526,  527,  351,  533,  181,  285,  182,
- /*  1230 */   184,  214,  353,  185,  535,  187,  215,  355,   86,  118,
- /*  1240 */   360,  547,  190,  129,  139,  371,  262,  372,  130,  536,
- /*  1250 */   554,  310,  131,  132,  573,   90,  133,  135,   93,  138,
- /*  1260 */   578,  574,  575,  109,  213,  561,  101,  119,  389,   18,
- /*  1270 */    98,  402,  622,  623,  163,  164,  429,  312,  432,   71,
- /*  1280 */   449,  437,  446,  140,  154,  166,  450,    6,  451,  470,
- /*  1290 */     7,  123,   14,   13,  124,  158,  484,  212,   84,  343,
- /*  1300 */   104,  348,  250,  105,   85,  117,  106,  240,  179,  352,
- /*  1310 */   142,  534,  126,  305,  170,  263,  188,  107,  286,  550,
- /*  1320 */   127,  128,   15,  542,  192,   87,  194,   88,  195,  557,
- /*  1330 */   196,  136,  137,  134,   16,  108,  571,  282,  381,  564,
- /*  1340 */   203,  145,  385,  901,  585,
+ /*    40 */   443,  208,  392,  447,   60,   59,  294,  430,  431,  427,
+ /*    50 */   427,   62,   62,   61,   61,   61,   61,  205,   63,   63,
+ /*    60 */    63,   63,   64,   64,   65,   65,   65,   66,  230,  289,
+ /*    70 */   368,  316,  435,  487,  205,   80,   67,  415,   69,  151,
+ /*    80 */    63,   63,   63,   63,   64,   64,   65,   65,   65,   66,
+ /*    90 */   230,  515,  162,  410,   35,  420,  426,  443,  571,   58,
+ /*   100 */    64,   64,   65,   65,   65,   66,  230,  393,  394,  417,
+ /*   110 */   417,  417,  289,   60,   59,  294,  430,  431,  427,  427,
+ /*   120 */    62,   62,   61,   61,   61,   61,  302,   63,   63,   63,
+ /*   130 */    63,   64,   64,   65,   65,   65,   66,  230,  420,  426,
+ /*   140 */    92,   65,   65,   65,   66,  230,  392,  456,  472,   67,
+ /*   150 */    56,   69,  151,  169,  406,  435,   60,   59,  294,  430,
+ /*   160 */   431,  427,  427,   62,   62,   61,   61,   61,   61,  247,
+ /*   170 */    63,   63,   63,   63,   64,   64,   65,   65,   65,   66,
+ /*   180 */   230,  289,  569,  522,  292,  620,  111,  478,  515,  447,
+ /*   190 */   230,  316,  403,   21,   67,  460,   69,  151,   66,  230,
+ /*   200 */   568,  443,  208,   67,  224,   69,  151,  420,  426,  146,
+ /*   210 */   147,  393,  394,  410,   41,  386,  148,  531,    2,  487,
+ /*   220 */   435,  566,  232,  415,  289,   60,   59,  294,  430,  431,
+ /*   230 */   427,  427,   62,   62,   61,   61,   61,   61,  316,   63,
+ /*   240 */    63,   63,   63,   64,   64,   65,   65,   65,   66,  230,
+ /*   250 */   420,  426,  486,  330,  211,  417,  417,  417,  359,  270,
+ /*   260 */   410,   41,  378,  207,  362,  542,  245,  289,   60,   59,
+ /*   270 */   294,  430,  431,  427,  427,   62,   62,   61,   61,   61,
+ /*   280 */    61,  392,   63,   63,   63,   63,   64,   64,   65,   65,
+ /*   290 */    65,   66,  230,  420,  426,  260,  299,  273,  522,  271,
+ /*   300 */   522,  210,  370,  319,  223,  433,  433,  532,   21,  576,
+ /*   310 */    21,   60,   59,  294,  430,  431,  427,  427,   62,   62,
+ /*   320 */    61,   61,   61,   61,  191,   63,   63,   63,   63,   64,
+ /*   330 */    64,   65,   65,   65,   66,  230,  261,  316,  239,   76,
+ /*   340 */   289,  544,  299,  149,  482,  150,  393,  394,  178,  240,
+ /*   350 */   569,  341,  344,  345,  404,  520,  445,  322,  165,  410,
+ /*   360 */    28,  540,  346,  517,  248,  539,  420,  426,  568,  567,
+ /*   370 */   161,  115,  238,  339,  243,  340,  173,  358,  272,  411,
+ /*   380 */   821,  488,   79,  249,   60,   59,  294,  430,  431,  427,
+ /*   390 */   427,   62,   62,   61,   61,   61,   61,  530,   63,   63,
+ /*   400 */    63,   63,   64,   64,   65,   65,   65,   66,  230,  289,
+ /*   410 */   248,  178,  465,  485,  341,  344,  345,  115,  238,  339,
+ /*   420 */   243,  340,  173,   82,  316,  346,  316,  491,  492,  249,
+ /*   430 */   565,  207,  152,  523,  489,  420,  426,  178,  529,  503,
+ /*   440 */   341,  344,  345,  407,  472,  528,  410,   35,  410,   35,
+ /*   450 */   171,  346,  198,   60,   59,  294,  430,  431,  427,  427,
+ /*   460 */    62,   62,   61,   61,   61,   61,  411,   63,   63,   63,
+ /*   470 */    63,   64,   64,   65,   65,   65,   66,  230,  289,  548,
+ /*   480 */   579,  288,  502,  234,  411,  316,  411,  316,  296,  283,
+ /*   490 */   298,  316,  445,  521,  165,  476,  172,  157,  421,  422,
+ /*   500 */   457,  335,  457,  144,  420,  426,  366,  410,   35,  410,
+ /*   510 */    36,  435,    1,  410,   49,  327,  392,  547,  193,  424,
+ /*   520 */   425,  156,   60,   59,  294,  430,  431,  427,  427,   62,
+ /*   530 */    62,   61,   61,   61,   61,  333,   63,   63,   63,   63,
+ /*   540 */    64,   64,   65,   65,   65,   66,  230,  289,  423,  332,
+ /*   550 */   452,  252,  411,  295,  438,  439,  297,  316,  349,  307,
+ /*   560 */   231,  457,  453,  321,  438,  439,  392,  369,  266,  265,
+ /*   570 */   189,  217,  392,  420,  426,  454,  435,  493,  205,  410,
+ /*   580 */    49,  393,  394,  583,  889,  174,  889,  494,  545,  492,
+ /*   590 */   392,   60,   59,  294,  430,  431,  427,  427,   62,   62,
+ /*   600 */    61,   61,   61,   61,  411,   63,   63,   63,   63,   64,
+ /*   610 */    64,   65,   65,   65,   66,  230,  289,  207,  586,  387,
+ /*   620 */   384,   91,   10,  580,  336,  308,  392,  207,  367,  480,
+ /*   630 */   316,  393,  394,  583,  888,  219,  888,  393,  394,  476,
+ /*   640 */   291,  233,  420,  426,  481,  249,  410,    3,  434,  260,
+ /*   650 */   317,  363,  410,   29,  448,  393,  394,  468,  260,  289,
+ /*   660 */    60,   59,  294,  430,  431,  427,  427,   62,   62,   61,
+ /*   670 */    61,   61,   61,  580,   63,   63,   63,   63,   64,   64,
+ /*   680 */    65,   65,   65,   66,  230,  420,  426,  391,  312,  388,
+ /*   690 */   555,  393,  394,   75,  204,   77,  395,  396,  397,  557,
+ /*   700 */   357,  197,  289,   60,   59,  294,  430,  431,  427,  427,
+ /*   710 */    62,   62,   61,   61,   61,   61,  316,   63,   63,   63,
+ /*   720 */    63,   64,   64,   65,   65,   65,   66,  230,  420,  426,
+ /*   730 */   319,  116,  433,  433,  319,  411,  433,  433,  410,   24,
+ /*   740 */   319,  515,  433,  433,  515,  289,   60,   70,  294,  430,
+ /*   750 */   431,  427,  427,   62,   62,   61,   61,   61,   61,  375,
+ /*   760 */    63,   63,   63,   63,   64,   64,   65,   65,   65,   66,
+ /*   770 */   230,  420,  426,  538,  356,  538,  216,  260,  472,  303,
+ /*   780 */   175,  176,  177,  254,  476,  515,  260,  383,  289,    5,
+ /*   790 */    59,  294,  430,  431,  427,  427,   62,   62,   61,   61,
+ /*   800 */    61,   61,  316,   63,   63,   63,   63,   64,   64,   65,
+ /*   810 */    65,   65,   66,  230,  420,  426,  392,  236,  380,  247,
+ /*   820 */   304,  258,  247,  256,  410,   33,  260,  558,  125,  467,
+ /*   830 */   515,  416,  168,  157,  294,  430,  431,  427,  427,   62,
+ /*   840 */    62,   61,   61,   61,   61,  306,   63,   63,   63,   63,
+ /*   850 */    64,   64,   65,   65,   65,   66,  230,   72,  323,  452,
+ /*   860 */     4,  153,   22,  247,  293,  305,  435,  559,  316,  382,
+ /*   870 */   316,  453,  320,   72,  323,  316,    4,  366,  316,  180,
+ /*   880 */   293,  393,  394,   20,  454,  141,  326,  316,  320,  325,
+ /*   890 */   410,   53,  410,   52,  316,  411,  155,  410,   96,  447,
+ /*   900 */   410,   94,  316,  500,  316,  325,  328,  469,  247,  410,
+ /*   910 */    99,  444,  260,  411,  318,  447,  410,  100,  316,   74,
+ /*   920 */    73,  467,  183,  260,  410,  110,  410,  112,   72,  314,
+ /*   930 */   315,  435,  337,  415,  458,   74,   73,  479,  316,  377,
+ /*   940 */   410,   17,  218,   19,   72,  314,  315,   72,  323,  415,
+ /*   950 */     4,  205,  316,  274,  293,  316,  411,  466,  205,  409,
+ /*   960 */   410,   97,  320,  408,  374,  417,  417,  417,  418,  419,
+ /*   970 */    12,  376,  316,  206,  410,   34,  174,  410,   95,  325,
+ /*   980 */    55,  417,  417,  417,  418,  419,   12,  310,  120,  447,
+ /*   990 */   428,  159,    9,  260,  410,   25,  220,  221,  222,  102,
+ /*  1000 */   441,  441,  316,  471,  409,  316,  475,  316,  408,   74,
+ /*  1010 */    73,  436,  202,   23,  278,  455,  244,   13,   72,  314,
+ /*  1020 */   315,  279,  316,  415,  410,   54,  316,  410,  113,  410,
+ /*  1030 */   114,  291,  581,  200,  276,  547,  462,  497,  498,  199,
+ /*  1040 */   316,  504,  201,  463,  410,   26,  316,  524,  410,   37,
+ /*  1050 */   316,  474,  316,  170,  253,  417,  417,  417,  418,  419,
+ /*  1060 */    12,  505,  410,   38,  510,  483,  316,   13,  410,   27,
+ /*  1070 */   508,  582,  410,   39,  410,   40,  316,  255,  507,  506,
+ /*  1080 */   512,  316,  125,  316,  511,  373,  275,  265,  410,   42,
+ /*  1090 */   509,  290,  316,  251,  316,  125,  205,  257,  410,   43,
+ /*  1100 */   316,  259,  316,  410,   44,  410,   30,  348,  316,  125,
+ /*  1110 */   316,  353,  186,  316,  410,   31,  410,   45,  316,  543,
+ /*  1120 */   379,  125,  410,   46,  410,   47,  316,  551,  264,  170,
+ /*  1130 */   410,   48,  410,   32,  401,  410,   11,  552,  440,   89,
+ /*  1140 */   410,   50,  301,  562,  578,   89,  287,  361,  410,   51,
+ /*  1150 */   364,  365,  267,  268,  269,  554,  143,  564,  277,  324,
+ /*  1160 */   280,  281,  575,  225,  442,  461,  464,  503,  241,  513,
+ /*  1170 */   516,  550,  343,  160,  561,  390,    8,  313,  398,  399,
+ /*  1180 */   400,  412,   82,  226,  331,  329,   81,  406,   57,   78,
+ /*  1190 */   209,  167,   83,  459,  122,  414,  227,  334,  228,  338,
+ /*  1200 */   300,  500,  103,  496,  246,  519,  514,  490,  495,  242,
+ /*  1210 */   214,  518,  499,  229,  501,  413,  350,  533,  284,  525,
+ /*  1220 */   526,  527,  235,  181,  473,  237,  285,  477,  182,  354,
+ /*  1230 */   352,  184,   86,  185,  118,  535,  187,  546,  360,  190,
+ /*  1240 */   129,  553,  139,  371,  372,  130,  215,  309,  560,  131,
+ /*  1250 */   132,  133,  572,  577,  135,  573,   98,  574,  389,  262,
+ /*  1260 */   402,  621,  536,  213,  101,  622,  432,  163,  164,  429,
+ /*  1270 */   138,   71,  449,  437,  446,  140,  470,  154,    6,  450,
+ /*  1280 */     7,  158,  166,  451,   14,  123,   13,  124,  484,  212,
+ /*  1290 */    84,  342,  104,  105,   90,  250,   85,  117,  106,  347,
+ /*  1300 */   179,  240,  351,  142,  534,  126,   18,  170,   93,  263,
+ /*  1310 */   188,  107,  355,  286,  109,  127,  549,  541,  128,  119,
+ /*  1320 */   537,  192,   15,  194,  195,  136,  196,  134,  556,  563,
+ /*  1330 */   311,  137,   16,  108,  570,  203,  145,  385,  381,  282,
+ /*  1340 */   584,  899,  899,  899,  899,  899,   87,  899,   88,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     0 */    16,  140,  141,  142,  111,   21,  145,   23,   70,   71,
- /*    10 */    72,   73,   23,   75,   76,   77,   78,   79,   80,   81,
- /*    20 */    82,   83,   84,   85,  156,   16,   42,   43,   74,   75,
- /*    30 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   85,
- /*    40 */   217,   59,  219,  220,   85,   61,   62,   63,   64,   65,
- /*    50 */    66,   67,   68,   69,   70,   71,   72,   73,  190,   75,
- /*    60 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   85,
- /*    70 */    16,   89,  148,   89,  148,   93,   22,  217,   89,  219,
- /*    80 */   220,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*    90 */    84,   85,  166,  167,   85,  142,   42,   43,  145,  239,
- /*   100 */    46,   92,   93,   94,   95,   96,   97,  125,  126,  127,
- /*   110 */   148,    1,    2,  104,   16,   61,   62,   63,   64,   65,
- /*   120 */    66,   67,   68,   69,   70,   71,   72,   73,  166,   75,
- /*   130 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   85,
- /*   140 */    42,   43,   44,   79,   80,   81,   82,   83,   84,   85,
- /*   150 */   226,   23,   19,  156,  228,  229,   23,   79,   80,   61,
- /*   160 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
- /*   170 */    72,   73,  111,   75,   76,   77,   78,   79,   80,   81,
- /*   180 */    82,   83,   84,   85,   16,  124,  148,  190,  148,   21,
- /*   190 */   228,  229,   59,   22,  154,  157,  158,  157,  158,  202,
- /*   200 */   203,  148,   84,   85,  207,  168,  169,   79,   80,  170,
- /*   210 */    42,   43,   79,   80,  177,  170,  161,   89,   90,  181,
- /*   220 */   182,  191,   89,  170,  171,  170,   93,   99,   16,   61,
- /*   230 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
- /*   240 */    72,   73,  148,   75,   76,   77,   78,   79,   80,   81,
- /*   250 */    82,   83,   84,   85,   42,   43,  186,  187,  125,  126,
- /*   260 */   127,   90,   11,  210,  211,   81,   82,   83,   84,   85,
- /*   270 */   186,  187,   16,   61,   62,   63,   64,   65,   66,   67,
- /*   280 */    68,   69,   70,   71,   72,   73,  115,   75,   76,   77,
- /*   290 */    78,   79,   80,   81,   82,   83,   84,   85,   42,   43,
- /*   300 */    49,   16,   91,  209,  148,   94,   95,   96,  162,  217,
- /*   310 */   218,  219,  220,  157,  158,   81,  105,   61,   62,   63,
- /*   320 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
- /*   330 */   182,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*   340 */    84,   85,  108,  182,  132,   16,  112,  201,   12,   20,
- /*   350 */    23,  100,  101,  102,  159,   22,  169,  162,  163,  164,
- /*   360 */    24,  148,  111,  217,  177,  219,  220,  177,  178,  156,
- /*   370 */    85,   42,   43,   37,  184,   39,   91,   92,   93,   94,
- /*   380 */    95,   96,   97,  170,  171,   49,  245,  246,  132,  104,
- /*   390 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
- /*   400 */    71,   72,   73,  190,   75,   76,   77,   78,   79,   80,
- /*   410 */    81,   82,   83,   84,   85,   16,   89,   90,   91,   20,
- /*   420 */    30,   94,   95,   96,   91,  212,  148,   94,   95,   96,
- /*   430 */   148,  148,  105,   19,  148,   21,  148,  224,  105,  156,
- /*   440 */    50,   42,   43,   19,  165,  166,  167,   23,  170,  171,
- /*   450 */   187,  148,  162,  170,  171,  148,  170,  171,  170,  171,
- /*   460 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
- /*   470 */    71,   72,   73,  190,   75,   76,   77,   78,   79,   80,
- /*   480 */    81,   82,   83,   84,   85,   16,   20,   20,   22,   20,
- /*   490 */   212,  201,  189,  103,  148,  213,  148,  148,  212,  148,
- /*   500 */    23,  148,  224,  148,  202,  203,   42,   43,  229,  221,
- /*   510 */   224,   42,   43,   89,  143,  144,  170,  171,  170,  171,
- /*   520 */   149,  170,  171,  170,  171,  170,  171,  156,   64,   65,
- /*   530 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
- /*   540 */    71,   72,   73,  240,   75,   76,   77,   78,   79,   80,
- /*   550 */    81,   82,   83,   84,   85,   16,   79,   93,  209,   20,
- /*   560 */    20,  190,  211,  151,  216,   16,   89,   90,   20,  216,
- /*   570 */   224,  165,  166,  167,  107,   19,  109,  110,   19,   23,
- /*   580 */    25,   42,   43,   22,   29,  214,   19,   20,   18,   22,
- /*   590 */    19,   20,   43,   22,  162,   23,   41,  162,  163,  164,
- /*   600 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
- /*   610 */    71,   72,   73,  242,   75,   76,   77,   78,   79,   80,
- /*   620 */    81,   82,   83,   84,   85,   16,   56,   60,   69,   12,
- /*   630 */    21,   60,   19,  201,  108,  229,   23,  225,  112,   23,
- /*   640 */   148,   24,   21,  231,   23,   89,   90,  107,   99,  109,
- /*   650 */   110,   42,   43,  104,   37,  107,   39,  109,  110,  148,
- /*   660 */    27,   89,   90,  148,  148,   95,  148,   34,   14,   16,
- /*   670 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
- /*   680 */    71,   72,   73,  122,   75,   76,   77,   78,   79,   80,
- /*   690 */    81,   82,   83,   84,   85,   42,   43,   81,  183,  183,
- /*   700 */   189,  183,   89,   90,  134,   89,   90,   53,  148,   55,
- /*   710 */    89,  148,  148,   16,   61,   62,   63,   64,   65,   66,
- /*   720 */    67,   68,   69,   70,   71,   72,   73,  148,   75,   76,
- /*   730 */    77,   78,   79,   80,   81,   82,   83,   84,   85,   42,
- /*   740 */    43,  226,  226,  183,  226,  148,  183,    0,    1,    2,
- /*   750 */     7,    8,    9,  107,  146,  109,  110,   16,   61,   62,
- /*   760 */    63,   64,   65,   66,   67,   68,   69,   70,   71,   72,
- /*   770 */    73,  148,   75,   76,   77,   78,   79,   80,   81,   82,
- /*   780 */    83,   84,   85,   42,   43,  148,  226,  148,  134,  226,
- /*   790 */   100,  101,  102,  170,  171,  100,  101,  102,   19,  148,
- /*   800 */   148,   16,  192,   62,   63,   64,   65,   66,   67,   68,
- /*   810 */    69,   70,   71,   72,   73,   92,   75,   76,   77,   78,
- /*   820 */    79,   80,   81,   82,   83,   84,   85,   42,   43,   23,
- /*   830 */   243,  244,   23,   16,  111,  148,  148,   22,   14,  156,
- /*   840 */   189,  189,  148,  131,  148,  133,  209,  124,   63,   64,
- /*   850 */    65,   66,   67,   68,   69,   70,   71,   72,   73,  148,
- /*   860 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
- /*   870 */    85,   16,   17,  190,   19,  148,  189,   53,   23,   55,
- /*   880 */    43,   22,  148,  189,  148,  189,   31,   16,   17,  156,
- /*   890 */    19,  156,  113,  156,   23,   89,   90,  214,   89,   90,
- /*   900 */   189,  213,   31,   48,  170,  171,  170,  171,  156,  148,
- /*   910 */    93,  193,  125,  126,   59,  148,  189,  148,  200,   48,
- /*   920 */   237,  115,   93,  190,  115,  190,   20,  190,   22,  114,
- /*   930 */    59,  170,  171,  104,   79,   80,   99,  170,  171,  170,
- /*   940 */   171,  148,  190,   88,   89,   90,   20,   20,   93,   22,
- /*   950 */    79,   80,   81,  148,   92,   93,  148,   98,  148,   88,
- /*   960 */    89,   90,   16,   17,   93,   19,  111,  148,  148,   23,
- /*   970 */   148,  148,   20,  162,   22,  170,  171,   31,  170,  171,
- /*   980 */   125,  126,  127,  128,  129,  130,   60,  204,  148,  170,
- /*   990 */   171,  148,  170,  171,   48,  148,  125,  126,  127,  128,
- /*  1000 */   129,  130,    7,    8,   20,   59,   22,    5,  148,  148,
- /*  1010 */   170,  171,   10,   11,   12,   13,   51,   52,  148,   20,
- /*  1020 */   148,   22,  148,  148,  179,   79,   80,   20,   26,   22,
- /*  1030 */    28,  170,  171,  179,   88,   89,   90,   35,  148,   93,
- /*  1040 */   170,  171,  170,  171,  170,  171,  148,  179,   20,   47,
- /*  1050 */    22,   49,   20,  148,   22,  148,   54,  148,  148,   57,
- /*  1060 */    20,  148,   22,  148,  148,   20,  148,   22,  170,  171,
- /*  1070 */   148,  125,  126,  127,  128,  129,  130,  170,  171,  233,
- /*  1080 */   170,  171,  234,  148,  148,  170,  171,  148,  170,  171,
- /*  1090 */   148,  148,  170,  171,   20,  148,   22,  148,  148,  148,
- /*  1100 */   192,  148,  100,  101,  102,  170,  171,  148,  106,  170,
- /*  1110 */   171,  148,  148,  111,  148,  148,  148,  148,  148,  170,
- /*  1120 */   171,  170,  171,  170,  171,  148,  148,  148,  148,  148,
- /*  1130 */   148,  148,  194,  170,  171,  150,  178,  135,  170,  171,
- /*  1140 */   170,  171,  148,  223,  230,  148,  173,  170,  171,  170,
- /*  1150 */   171,  170,  171,  170,  171,  230,  148,  195,  148,  173,
- /*  1160 */   148,  173,  173,  173,  170,  171,  174,  170,  171,  195,
- /*  1170 */     6,  147,  147,  147,  147,   22,  155,  190,  170,  171,
- /*  1180 */   170,  171,  170,  171,  122,  119,  195,  120,  117,  196,
- /*  1190 */   121,   23,  161,  197,  131,  113,  198,  222,   99,  199,
- /*  1200 */   153,  153,  116,   99,   98,  172,  205,  172,  172,  206,
- /*  1210 */   205,   40,  206,  174,  180,  172,   19,  175,   85,  161,
- /*  1220 */   161,  180,  172,  172,  172,   15,  153,  152,  175,  152,
- /*  1230 */   152,  227,  153,  153,  153,  152,  227,   38,  131,   61,
- /*  1240 */   153,  185,  185,   19,  215,  153,  235,   15,  188,  236,
- /*  1250 */   195,  153,  188,  188,   33,  238,  188,  185,  238,  215,
- /*  1260 */   138,  153,  153,  241,  176,  195,  176,  244,    1,  232,
- /*  1270 */   160,   20,  113,  113,  113,  113,   93,  247,  108,   19,
- /*  1280 */    11,   20,   20,   19,   19,   22,   20,  118,   20,  115,
- /*  1290 */   118,   19,   22,   22,   20,  113,   20,   44,   19,   44,
- /*  1300 */    19,   44,   20,   19,   19,   32,   19,  104,   97,   16,
- /*  1310 */    21,   17,   99,   36,   22,  134,   99,   19,    5,    1,
- /*  1320 */    45,  103,   19,   45,  123,   69,  114,   69,   14,   17,
- /*  1330 */   116,  103,  123,  114,   19,   14,   20,  137,   58,  124,
- /*  1340 */   136,   19,    3,  248,    4,
+ /*     0 */    16,  139,  140,  141,  168,   21,  144,   23,   69,   70,
+ /*    10 */    71,   72,  176,   74,   75,   76,   77,   78,   79,   80,
+ /*    20 */    81,   82,   83,   84,    1,    2,   42,   43,   73,   74,
+ /*    30 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
+ /*    40 */    78,   79,   23,   58,   60,   61,   62,   63,   64,   65,
+ /*    50 */    66,   67,   68,   69,   70,   71,   72,  110,   74,   75,
+ /*    60 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   16,
+ /*    70 */   123,  147,   88,   88,  110,   22,  216,   92,  218,  219,
+ /*    80 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
+ /*    90 */    84,  147,   19,  169,  170,   42,   43,   78,  238,   46,
+ /*   100 */    78,   79,   80,   81,   82,   83,   84,   88,   89,  124,
+ /*   110 */   125,  126,   16,   60,   61,   62,   63,   64,   65,   66,
+ /*   120 */    67,   68,   69,   70,   71,   72,  182,   74,   75,   76,
+ /*   130 */    77,   78,   79,   80,   81,   82,   83,   84,   42,   43,
+ /*   140 */    44,   80,   81,   82,   83,   84,   23,  223,  161,  216,
+ /*   150 */    19,  218,  219,   21,   23,   23,   60,   61,   62,   63,
+ /*   160 */    64,   65,   66,   67,   68,   69,   70,   71,   72,  225,
+ /*   170 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
+ /*   180 */    84,   16,  147,  147,  150,  112,   21,  200,  147,   58,
+ /*   190 */    84,  147,  156,  157,  216,  217,  218,  219,   83,   84,
+ /*   200 */   165,   78,   79,  216,  190,  218,  219,   42,   43,   78,
+ /*   210 */    79,   88,   89,  169,  170,  141,  180,  181,  144,   88,
+ /*   220 */    88,   98,  147,   92,   16,   60,   61,   62,   63,   64,
+ /*   230 */    65,   66,   67,   68,   69,   70,   71,   72,  147,   74,
+ /*   240 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
+ /*   250 */    42,   43,  169,  209,  210,  124,  125,  126,  224,   14,
+ /*   260 */   169,  170,  227,  228,  230,   18,  225,   16,   60,   61,
+ /*   270 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
+ /*   280 */    72,   23,   74,   75,   76,   77,   78,   79,   80,   81,
+ /*   290 */    82,   83,   84,   42,   43,  147,   16,   52,  147,   54,
+ /*   300 */   147,  210,   55,  106,  153,  108,  109,  156,  157,  156,
+ /*   310 */   157,   60,   61,   62,   63,   64,   65,   66,   67,   68,
+ /*   320 */    69,   70,   71,   72,   22,   74,   75,   76,   77,   78,
+ /*   330 */    79,   80,   81,   82,   83,   84,  188,  147,   92,  131,
+ /*   340 */    16,   94,   16,   22,   20,  155,   88,   89,   90,  103,
+ /*   350 */   147,   93,   94,   95,  167,  168,  161,  162,  163,  169,
+ /*   360 */   170,   25,  104,  176,   84,   29,   42,   43,  165,  166,
+ /*   370 */    90,   91,   92,   93,   94,   95,   96,   41,  133,  189,
+ /*   380 */   133,  169,  131,  103,   60,   61,   62,   63,   64,   65,
+ /*   390 */    66,   67,   68,   69,   70,   71,   72,  181,   74,   75,
+ /*   400 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   16,
+ /*   410 */    84,   90,   22,   20,   93,   94,   95,   91,   92,   93,
+ /*   420 */    94,   95,   96,  121,  147,  104,  147,  185,  186,  103,
+ /*   430 */   227,  228,  155,  181,  160,   42,   43,   90,  176,  177,
+ /*   440 */    93,   94,   95,  169,  161,  183,  169,  170,  169,  170,
+ /*   450 */   155,  104,  155,   60,   61,   62,   63,   64,   65,   66,
+ /*   460 */    67,   68,   69,   70,   71,   72,  189,   74,   75,   76,
+ /*   470 */    77,   78,   79,   80,   81,   82,   83,   84,   16,   11,
+ /*   480 */   244,  245,   20,  200,  189,  147,  189,  147,  211,  158,
+ /*   490 */   211,  147,  161,  162,  163,  147,  201,  202,   42,   43,
+ /*   500 */   223,  206,  223,  113,   42,   43,  147,  169,  170,  169,
+ /*   510 */   170,   23,   19,  169,  170,  186,   23,   49,  155,   63,
+ /*   520 */    64,  147,   60,   61,   62,   63,   64,   65,   66,   67,
+ /*   530 */    68,   69,   70,   71,   72,  147,   74,   75,   76,   77,
+ /*   540 */    78,   79,   80,   81,   82,   83,   84,   16,   92,  211,
+ /*   550 */    12,   20,  189,  164,  165,  166,  208,  147,   16,  215,
+ /*   560 */   220,  223,   24,  164,  165,  166,   23,   99,  100,  101,
+ /*   570 */   155,  212,   23,   42,   43,   37,   88,   39,  110,  169,
+ /*   580 */   170,   88,   89,   19,   20,   43,   22,   49,  185,  186,
+ /*   590 */    23,   60,   61,   62,   63,   64,   65,   66,   67,   68,
+ /*   600 */    69,   70,   71,   72,  189,   74,   75,   76,   77,   78,
+ /*   610 */    79,   80,   81,   82,   83,   84,   16,  228,    0,    1,
+ /*   620 */     2,   21,   19,   59,  147,  215,   23,  228,  213,   80,
+ /*   630 */   147,   88,   89,   19,   20,  145,   22,   88,   89,  147,
+ /*   640 */    98,  147,   42,   43,   20,  103,  169,  170,   20,  147,
+ /*   650 */   147,  236,  169,  170,   20,   88,   89,  114,  147,   16,
+ /*   660 */    60,   61,   62,   63,   64,   65,   66,   67,   68,   69,
+ /*   670 */    70,   71,   72,   59,   74,   75,   76,   77,   78,   79,
+ /*   680 */    80,   81,   82,   83,   84,   42,   43,  147,  142,  143,
+ /*   690 */   188,   88,   89,  130,  148,  132,    7,    8,    9,  188,
+ /*   700 */   208,  155,   16,   60,   61,   62,   63,   64,   65,   66,
+ /*   710 */    67,   68,   69,   70,   71,   72,  147,   74,   75,   76,
+ /*   720 */    77,   78,   79,   80,   81,   82,   83,   84,   42,   43,
+ /*   730 */   106,  147,  108,  109,  106,  189,  108,  109,  169,  170,
+ /*   740 */   106,  147,  108,  109,  147,   16,   60,   61,   62,   63,
+ /*   750 */    64,   65,   66,   67,   68,   69,   70,   71,   72,  213,
+ /*   760 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
+ /*   770 */    84,   42,   43,   99,  100,  101,  182,  147,  161,  182,
+ /*   780 */    99,  100,  101,   14,  147,  147,  147,  241,   16,  191,
+ /*   790 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
+ /*   800 */    71,   72,  147,   74,   75,   76,   77,   78,   79,   80,
+ /*   810 */    81,   82,   83,   84,   42,   43,   23,  200,  188,  225,
+ /*   820 */   182,   52,  225,   54,  169,  170,  147,  188,   22,   22,
+ /*   830 */   147,  147,  201,  202,   62,   63,   64,   65,   66,   67,
+ /*   840 */    68,   69,   70,   71,   72,  208,   74,   75,   76,   77,
+ /*   850 */    78,   79,   80,   81,   82,   83,   84,   16,   17,   12,
+ /*   860 */    19,  155,   19,  225,   23,  182,   23,  188,  147,  239,
+ /*   870 */   147,   24,   31,   16,   17,  147,   19,  147,  147,  155,
+ /*   880 */    23,   88,   89,   19,   37,   21,   39,  147,   31,   48,
+ /*   890 */   169,  170,  169,  170,  147,  189,   89,  169,  170,   58,
+ /*   900 */   169,  170,  147,   97,  147,   48,  147,  114,  225,  169,
+ /*   910 */   170,  161,  147,  189,   16,   58,  169,  170,  147,   78,
+ /*   920 */    79,  114,  155,  147,  169,  170,  169,  170,   87,   88,
+ /*   930 */    89,   88,   80,   92,  147,   78,   79,   80,  147,   91,
+ /*   940 */   169,  170,  212,   19,   87,   88,   89,   16,   17,   92,
+ /*   950 */    19,  110,  147,  188,   23,  147,  189,  203,  110,  107,
+ /*   960 */   169,  170,   31,  111,  188,  124,  125,  126,  127,  128,
+ /*   970 */   129,  123,  147,  192,  169,  170,   43,  169,  170,   48,
+ /*   980 */   199,  124,  125,  126,  127,  128,  129,  242,  243,   58,
+ /*   990 */    92,    5,   68,  147,  169,  170,   10,   11,   12,   13,
+ /*  1000 */   124,  125,  147,  147,  107,  147,  147,  147,  111,   78,
+ /*  1010 */    79,   20,   26,   22,   28,   20,  147,   22,   87,   88,
+ /*  1020 */    89,   35,  147,   92,  169,  170,  147,  169,  170,  169,
+ /*  1030 */   170,   98,   20,   47,  188,   49,   27,    7,    8,   53,
+ /*  1040 */   147,  147,   56,   34,  169,  170,  147,  147,  169,  170,
+ /*  1050 */   147,   20,  147,   22,  147,  124,  125,  126,  127,  128,
+ /*  1060 */   129,  178,  169,  170,  178,   20,  147,   22,  169,  170,
+ /*  1070 */    30,   59,  169,  170,  169,  170,  147,  147,   91,   92,
+ /*  1080 */    20,  147,   22,  147,  178,   99,  100,  101,  169,  170,
+ /*  1090 */    50,  105,  147,   20,  147,   22,  110,  147,  169,  170,
+ /*  1100 */   147,  147,  147,  169,  170,  169,  170,   20,  147,   22,
+ /*  1110 */   147,  233,  232,  147,  169,  170,  169,  170,  147,   20,
+ /*  1120 */   134,   22,  169,  170,  169,  170,  147,   20,  147,   22,
+ /*  1130 */   169,  170,  169,  170,  149,  169,  170,   20,  229,   22,
+ /*  1140 */   169,  170,  102,   20,   20,   22,   22,  147,  169,  170,
+ /*  1150 */   147,  147,  147,  147,  147,  147,  191,  147,  147,  222,
+ /*  1160 */   147,  147,  147,  193,  229,  172,  172,  177,  172,  172,
+ /*  1170 */   172,  194,  173,    6,  194,  146,   22,  154,  146,  146,
+ /*  1180 */   146,  189,  121,  194,  118,  116,  119,   23,  120,  130,
+ /*  1190 */   221,  112,   98,  152,  152,  160,  195,  115,  196,   98,
+ /*  1200 */    40,   97,   19,  179,   84,  179,  160,  171,  171,  171,
+ /*  1210 */   226,  160,  173,  197,  171,  198,   15,  152,  174,  171,
+ /*  1220 */   171,  171,  204,  151,  205,  204,  174,  205,  151,   38,
+ /*  1230 */   152,  151,  130,  152,   60,  152,  151,  184,  152,  184,
+ /*  1240 */    19,  194,  214,  152,   15,  187,  226,  152,  194,  187,
+ /*  1250 */   187,  187,   33,  137,  184,  152,  159,  152,    1,  234,
+ /*  1260 */    20,  112,  235,  175,  175,  112,  107,  112,  112,   92,
+ /*  1270 */   214,   19,   11,   20,   20,   19,  114,   19,  117,   20,
+ /*  1280 */   117,  112,   22,   20,   22,   19,   22,   20,   20,   44,
+ /*  1290 */    19,   44,   19,   19,  237,   20,   19,   32,   19,   44,
+ /*  1300 */    96,  103,   16,   21,   17,   98,  231,   22,  237,  133,
+ /*  1310 */    98,   19,   36,    5,  240,   45,    1,   45,  102,  243,
+ /*  1320 */    51,  122,   19,  113,   14,  102,  115,  113,   17,  123,
+ /*  1330 */   246,  122,   19,   14,   20,  135,   19,    3,   57,  136,
+ /*  1340 */     4,  247,  247,  247,  247,  247,   68,  247,   68,
 };
-#define YY_SHIFT_USE_DFLT (-108)
+#define YY_SHIFT_USE_DFLT (-62)
 #define YY_SHIFT_MAX 385
 static const short yy_shift_ofst[] = {
- /*     0 */   110,  855, 1002,  -16,  855,  946,  946,  946,  327,  128,
- /*    10 */  -107,   98,  946,  946,  946,  946,  946,  -46,  251,  477,
- /*    20 */   572,  -11,   78,   78,   54,  168,  212,  256,  329,  399,
- /*    30 */   469,  539,  609,  653,  697,  653,  653,  653,  653,  653,
- /*    40 */   653,  653,  653,  653,  653,  653,  653,  653,  653,  653,
- /*    50 */   653,  653,  741,  785,  785,  871,  946,  946,  946,  946,
- /*    60 */   946,  946,  946,  946,  946,  946,  946,  946,  946,  946,
- /*    70 */   946,  946,  946,  946,  946,  946,  946,  946,  946,  946,
- /*    80 */   946,  946,  946,  946,  946,  946,  946,  946,  946,  946,
- /*    90 */   946,  946,  946,  946,  -62,  -62,    6,    6,  285,   64,
- /*   100 */   184,  549,  570,  572,  572,  572,  572,  572,  572,  572,
- /*   110 */   118,  -11,  -41, -108, -108,  133,    9,  336,  336,  567,
- /*   120 */   571,  747,  621,  572,  621,  572,  572,  572,  572,  572,
- /*   130 */   572,  572,  572,  572,  572,  572,  572,  572,  723,   61,
- /*   140 */  -107, -107, -107, -108, -108, -108,  -18,  -18,  333,  211,
- /*   150 */   467,  556,  540,  548,  617,  806,  809,  613,  616,  743,
- /*   160 */   572,  572,  234,  572,  572,  424,  572,  572,  171,  572,
- /*   170 */   572,  646,  171,  572,  572,  390,  390,  390,  572,  572,
- /*   180 */   646,  572,  572,  646,  572,  555,  690,  572,  572,  646,
- /*   190 */   572,  572,  572,  646,  572,  572,  572,  646,  646,  572,
- /*   200 */   572,  572,  572,  572,  414,  526,  815,  787,  787,  712,
- /*   210 */   633,  633,  633,  837,  633,  633,  859,  561,  561, 1164,
- /*   220 */  1164, 1164, 1164, 1153, -107, 1062, 1066, 1067, 1071, 1069,
- /*   230 */  1168, 1063, 1082, 1082, 1099, 1086, 1099, 1086, 1104, 1104,
- /*   240 */  1171, 1104, 1106, 1104, 1197, 1133, 1168, 1133, 1168, 1171,
- /*   250 */  1104, 1104, 1104, 1197, 1210, 1082, 1210, 1082, 1210, 1082,
- /*   260 */  1082, 1199, 1107, 1210, 1082, 1178, 1178, 1224, 1062, 1082,
- /*   270 */  1232, 1232, 1232, 1232, 1062, 1178, 1224, 1082, 1221, 1221,
- /*   280 */  1082, 1082, 1122, -108, -108, -108, -108, -108, -108,  464,
- /*   290 */   654,  695,  824,  779,  817,  466,  906,  927,  952,  829,
- /*   300 */   995,  862,  984,  999, 1007,  965, 1028, 1032, 1040, 1045,
- /*   310 */   559, 1074,  926, 1267, 1251, 1159, 1160, 1161, 1162, 1183,
- /*   320 */  1170, 1260, 1261, 1262, 1264, 1269, 1265, 1266, 1263, 1268,
- /*   330 */  1169, 1270, 1172, 1271, 1174, 1272, 1274, 1182, 1276, 1273,
- /*   340 */  1253, 1279, 1255, 1281, 1282, 1284, 1285, 1257, 1287, 1211,
- /*   350 */  1203, 1293, 1294, 1289, 1213, 1277, 1275, 1292, 1278, 1181,
- /*   360 */  1217, 1298, 1313, 1318, 1218, 1256, 1258, 1201, 1303, 1212,
- /*   370 */  1314, 1214, 1312, 1219, 1228, 1209, 1315, 1215, 1316, 1321,
- /*   380 */  1280, 1204, 1200, 1322, 1339, 1340,
+ /*     0 */    23,  841,  986,  -16,  841,  931,  931,  931,  258,  123,
+ /*    10 */   -36,   96,  931,  931,  931,  931,  931,  -45,  468,   19,
+ /*    20 */   567,  488,  -38,  -38,   53,  165,  208,  251,  324,  393,
+ /*    30 */   462,  531,  600,  643,  686,  643,  643,  643,  643,  643,
+ /*    40 */   643,  643,  643,  643,  643,  643,  643,  643,  643,  643,
+ /*    50 */   643,  643,  729,  772,  772,  857,  931,  931,  931,  931,
+ /*    60 */   931,  931,  931,  931,  931,  931,  931,  931,  931,  931,
+ /*    70 */   931,  931,  931,  931,  931,  931,  931,  931,  931,  931,
+ /*    80 */   931,  931,  931,  931,  931,  931,  931,  931,  931,  931,
+ /*    90 */   931,  931,  931,  931,  -61,  -61,    6,    6,  280,   22,
+ /*   100 */    61,  542,  247,  567,  567,  567,  567,  567,  567,  567,
+ /*   110 */   115,  488,  106,  -62,  -62,  131,  326,  538,  538,  564,
+ /*   120 */   614,  618,  132,  567,  132,  567,  567,  567,  567,  567,
+ /*   130 */   567,  567,  567,  567,  567,  567,  567,  567,  848,  -53,
+ /*   140 */   -36,  -36,  -36,  -62,  -62,  -62,  -15,  -15,  321,  347,
+ /*   150 */   624,  493,  628,  634,  847,  543,  793,  603,  549,  689,
+ /*   160 */   567,  567,  852,  567,  567,  843,  567,  567,  807,  567,
+ /*   170 */   567,  197,  807,  567,  567, 1040, 1040, 1040,  567,  567,
+ /*   180 */   197,  567,  567,  197,  567,  336,  674,  567,  567,  197,
+ /*   190 */   567,  567,  567,  197,  567,  567,  567,  197,  197,  567,
+ /*   200 */   567,  567,  567,  567,  864,  897,  390,  876,  876,  563,
+ /*   210 */  1009, 1009, 1009,  933, 1009, 1009,  806,  302,  302, 1167,
+ /*   220 */  1167, 1167, 1167, 1154,  -36, 1061, 1066, 1067, 1069, 1068,
+ /*   230 */  1164, 1059, 1079, 1079, 1094, 1082, 1094, 1082, 1101, 1101,
+ /*   240 */  1160, 1101, 1104, 1101, 1183, 1120, 1164, 1120, 1164, 1160,
+ /*   250 */  1101, 1101, 1101, 1183, 1201, 1079, 1201, 1079, 1201, 1079,
+ /*   260 */  1079, 1191, 1102, 1201, 1079, 1174, 1174, 1221, 1061, 1079,
+ /*   270 */  1229, 1229, 1229, 1229, 1061, 1174, 1221, 1079, 1219, 1219,
+ /*   280 */  1079, 1079, 1116,  -62,  -62,  -62,  -62,  -62,  -62,  456,
+ /*   290 */   245,  681,  769,   73,  898,  991,  995, 1031, 1045,  246,
+ /*   300 */  1030,  987, 1060, 1073, 1087, 1099, 1107, 1117, 1123,  924,
+ /*   310 */  1124, 1012, 1257, 1240, 1149, 1153, 1155, 1156, 1177, 1159,
+ /*   320 */  1252, 1253, 1254, 1256, 1261, 1258, 1259, 1260, 1263, 1161,
+ /*   330 */  1262, 1163, 1264, 1162, 1266, 1267, 1169, 1268, 1265, 1245,
+ /*   340 */  1271, 1247, 1273, 1275, 1274, 1277, 1255, 1279, 1204, 1198,
+ /*   350 */  1286, 1287, 1282, 1207, 1276, 1269, 1270, 1285, 1272, 1176,
+ /*   360 */  1212, 1292, 1308, 1315, 1216, 1278, 1280, 1199, 1303, 1210,
+ /*   370 */  1310, 1211, 1311, 1214, 1223, 1209, 1313, 1206, 1314, 1319,
+ /*   380 */  1281, 1200, 1203, 1317, 1334, 1336,
 };
-#define YY_REDUCE_USE_DFLT (-178)
+#define YY_REDUCE_USE_DFLT (-165)
 #define YY_REDUCE_MAX 288
 static const short yy_reduce_ofst[] = {
- /*     0 */  -139,  213,  371,  146,  283,  278,   53,  286,   38,  -74,
- /*    10 */    -3, -140,  288,  346,  351,  348,  353,   92,  683,  -38,
- /*    20 */    40,  195,  279,  406, -177, -177, -177, -177, -177, -177,
- /*    30 */  -177, -177, -177, -177, -177, -177, -177, -177, -177, -177,
- /*    40 */  -177, -177, -177, -177, -177, -177, -177, -177, -177, -177,
- /*    50 */  -177, -177, -177, -177, -177,  355,  623,  734,  736,  761,
- /*    60 */   767,  769,  805,  808,  819,  822,  840,  861,  870,  872,
- /*    70 */   874,  898,  907,  910,  915,  918,  922,  935,  939,  949,
- /*    80 */   951,  953,  963,  968,  970,  977,  979,  981,  983,  994,
- /*    90 */   997, 1008, 1010, 1012, -177, -177, -177, -177,   37, -177,
- /*   100 */  -177,  190,  412,  515,  516,  518,  560,  563,  303,  156,
- /*   110 */  -177,  435, -177, -177, -177,   55,  187,   70,   84,  141,
- /*   120 */   141,  -47,  290,   94,  432,  -76,  511,  349,  282,  637,
- /*   130 */   651,  652,  687,  694,  696,  711,  688,  727, -132,  733,
- /*   140 */   735,  737,  752,  718,  302,  587,   39,   45,  148,  161,
- /*   150 */    30,  307,   30,   30,  263,  492,  564,  579,  597,  608,
- /*   160 */   639,  793,  610,  597,  810,  811,  820,  823,  783,  843,
- /*   170 */   847,   30,  783,  860,  875,  845,  854,  868,  890,  905,
- /*   180 */    30,  909,  913,   30,  916,  846,  848,  936,  942,   30,
- /*   190 */   943,  947,  950,   30,  959,  964,  966,   30,   30,  967,
- /*   200 */   969,  978,  980,  982,  985,  908,  938,  914,  925,  920,
- /*   210 */   973,  986,  988,  958,  989,  990,  992,  962,  974, 1024,
- /*   220 */  1025, 1026, 1027, 1021,  987,  991,  993,  996,  998, 1000,
- /*   230 */  1031,  975, 1047, 1048, 1001, 1003, 1005, 1006, 1033, 1035,
- /*   240 */  1034, 1036, 1039, 1043, 1042, 1004, 1058, 1009, 1059, 1041,
- /*   250 */  1050, 1051, 1052, 1053, 1075, 1073, 1077, 1079, 1078, 1080,
- /*   260 */  1081, 1011, 1013, 1083, 1087, 1056, 1057, 1029, 1055, 1092,
- /*   270 */  1060, 1064, 1065, 1068, 1070, 1072, 1044, 1098, 1017, 1020,
- /*   280 */  1108, 1109, 1022, 1110, 1088, 1090, 1037, 1023, 1030,
+ /*     0 */  -138,  277,  546,  -13,  190,  279,   44,  338,   36,  203,
+ /*    10 */   295, -140,  340,  -76,   91,  344,  410,  -22,  415,   35,
+ /*    20 */   151,  331,  389,  399,  -67,  -67,  -67,  -67,  -67,  -67,
+ /*    30 */   -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,
+ /*    40 */   -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,
+ /*    50 */   -67,  -67,  -67,  -67,  -67,  477,  483,  569,  655,  721,
+ /*    60 */   723,  728,  731,  740,  747,  755,  757,  771,  791,  805,
+ /*    70 */   808,  825,  855,  858,  860,  875,  879,  893,  899,  903,
+ /*    80 */   905,  919,  929,  934,  936,  945,  947,  953,  955,  961,
+ /*    90 */   963,  966,  971,  979,  -67,  -67,  -67,  -67,  187,  -67,
+ /*   100 */   -67,  262,   34,  -56,  594,  597,  638,  683,  630,  153,
+ /*   110 */   -67,  195,  -67,  -67,  -67,  274, -164,  242,  403,  236,
+ /*   120 */   236,   74,  283,  348,  617,   41,  148,  492,  359,  637,
+ /*   130 */   502,  511,  639,  679,  765,  776,  730,  846,  297,  363,
+ /*   140 */   706,  724,  767,  781,  631,  745,   83,  212,  216,  252,
+ /*   150 */    14,   75,   14,   14,  329,  374,  388,  494,  503,  490,
+ /*   160 */   540,  584,  598,  503,  684,  750,  759,  787,  754,  856,
+ /*   170 */   859,   14,  754,  869,  894,  883,  886,  906,  900,  907,
+ /*   180 */    14,  930,  950,   14,  954,  880,  878,  981, 1000,   14,
+ /*   190 */  1003, 1004, 1005,   14, 1006, 1007, 1008,   14,   14, 1010,
+ /*   200 */  1011, 1013, 1014, 1015,  985,  965,  970,  909,  935,  937,
+ /*   210 */   993,  994,  996,  990,  997,  998,  999,  977,  980, 1029,
+ /*   220 */  1032, 1033, 1034, 1023,  992,  989, 1001, 1002, 1016, 1017,
+ /*   230 */  1035,  969, 1041, 1042, 1018, 1019, 1021, 1022, 1036, 1037,
+ /*   240 */  1024, 1038, 1039, 1043, 1044,  984, 1046, 1020, 1051, 1026,
+ /*   250 */  1048, 1049, 1050, 1052, 1072, 1065, 1077, 1078, 1080, 1081,
+ /*   260 */  1083, 1025, 1027, 1085, 1086, 1053, 1055, 1028, 1047, 1091,
+ /*   270 */  1058, 1062, 1063, 1064, 1054, 1070, 1056, 1095, 1057, 1071,
+ /*   280 */  1103, 1105, 1074, 1097, 1088, 1089, 1075, 1076, 1084,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   593,  819,  899,  708,  899,  819,  899,  819,  899,  844,
- /*    10 */   712,  873,  815,  819,  899,  899,  899,  790,  899,  844,
- /*    20 */   899,  624,  844,  844,  741,  899,  899,  899,  899,  899,
- /*    30 */   899,  899,  899,  742,  899,  818,  814,  810,  812,  811,
- /*    40 */   743,  732,  739,  746,  724,  858,  748,  749,  755,  756,
- /*    50 */   874,  877,  778,  777,  796,  899,  899,  899,  899,  899,
- /*    60 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*    70 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*    80 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*    90 */   899,  899,  899,  899,  780,  801,  779,  789,  617,  781,
- /*   100 */   782,  677,  612,  899,  899,  899,  899,  899,  899,  899,
- /*   110 */   783,  899,  784,  797,  798,  899,  899,  899,  899,  899,
- /*   120 */   899,  593,  708,  899,  708,  899,  899,  899,  899,  899,
- /*   130 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*   140 */   899,  899,  899,  702,  712,  892,  899,  899,  668,  899,
- /*   150 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  600,
- /*   160 */   598,  899,  700,  899,  899,  626,  899,  899,  710,  899,
- /*   170 */   899,  715,  716,  899,  899,  899,  899,  899,  899,  899,
- /*   180 */   614,  899,  899,  689,  899,  850,  899,  899,  899,  865,
- /*   190 */   899,  899,  899,  863,  899,  899,  899,  691,  751,  831,
- /*   200 */   899,  878,  880,  899,  899,  700,  709,  899,  899,  813,
- /*   210 */   735,  735,  735,  647,  735,  735,  650,  745,  745,  597,
- /*   220 */   597,  597,  597,  667,  899,  745,  736,  738,  728,  740,
- /*   230 */   899,  899,  717,  717,  725,  727,  725,  727,  679,  679,
- /*   240 */   664,  679,  650,  679,  823,  828,  899,  828,  899,  664,
- /*   250 */   679,  679,  679,  823,  609,  717,  609,  717,  609,  717,
- /*   260 */   717,  854,  857,  609,  717,  681,  681,  757,  745,  717,
- /*   270 */   688,  688,  688,  688,  745,  681,  757,  717,  876,  876,
- /*   280 */   717,  717,  885,  634,  652,  652,  860,  892,  897,  899,
- /*   290 */   899,  899,  899,  764,  899,  899,  899,  899,  899,  899,
- /*   300 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*   310 */   837,  899,  899,  899,  899,  769,  765,  899,  766,  899,
- /*   320 */   694,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*   330 */   899,  729,  899,  737,  899,  899,  899,  899,  899,  899,
- /*   340 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*   350 */   899,  899,  899,  899,  899,  899,  852,  853,  899,  899,
- /*   360 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*   370 */   899,  899,  899,  899,  899,  899,  899,  899,  899,  899,
- /*   380 */   884,  899,  899,  887,  594,  899,  588,  591,  590,  592,
- /*   390 */   596,  599,  621,  622,  623,  601,  602,  603,  604,  605,
- /*   400 */   606,  607,  613,  615,  633,  635,  619,  637,  698,  699,
- /*   410 */   761,  692,  693,  697,  772,  763,  767,  768,  770,  771,
- /*   420 */   785,  786,  788,  794,  800,  803,  787,  792,  793,  795,
- /*   430 */   799,  802,  695,  696,  806,  620,  627,  628,  631,  632,
- /*   440 */   840,  842,  841,  843,  630,  629,  773,  776,  808,  809,
- /*   450 */   866,  867,  868,  869,  870,  804,  816,  817,  718,  807,
- /*   460 */   791,  730,  733,  734,  731,  701,  711,  720,  721,  722,
- /*   470 */   723,  706,  707,  713,  726,  759,  760,  714,  703,  704,
- /*   480 */   705,  805,  762,  774,  775,  638,  639,  769,  640,  641,
- /*   490 */   642,  680,  683,  684,  685,  643,  662,  665,  666,  644,
- /*   500 */   651,  645,  646,  653,  654,  655,  658,  659,  660,  661,
- /*   510 */   656,  657,  824,  825,  829,  827,  826,  648,  649,  663,
- /*   520 */   636,  625,  618,  669,  672,  673,  674,  675,  676,  678,
- /*   530 */   670,  671,  616,  608,  610,  719,  846,  855,  856,  851,
- /*   540 */   847,  848,  849,  611,  820,  821,  682,  753,  754,  845,
- /*   550 */   859,  861,  758,  862,  864,  889,  686,  687,  690,  830,
- /*   560 */   871,  744,  747,  750,  752,  832,  833,  834,  835,  838,
- /*   570 */   839,  836,  872,  875,  879,  881,  882,  883,  886,  888,
- /*   580 */   893,  894,  895,  898,  896,  595,  589,
+ /*     0 */   592,  818,  897,  707,  897,  818,  897,  818,  897,  843,
+ /*    10 */   711,  872,  814,  818,  897,  897,  897,  789,  897,  843,
+ /*    20 */   897,  623,  843,  843,  740,  897,  897,  897,  897,  897,
+ /*    30 */   897,  897,  897,  741,  897,  817,  813,  809,  811,  810,
+ /*    40 */   742,  731,  738,  745,  723,  856,  747,  748,  754,  755,
+ /*    50 */   873,  871,  777,  776,  795,  897,  897,  897,  897,  897,
+ /*    60 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*    70 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*    80 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*    90 */   897,  897,  897,  897,  779,  800,  778,  788,  616,  780,
+ /*   100 */   781,  676,  611,  897,  897,  897,  897,  897,  897,  897,
+ /*   110 */   782,  897,  783,  796,  797,  897,  897,  897,  897,  897,
+ /*   120 */   897,  592,  707,  897,  707,  897,  897,  897,  897,  897,
+ /*   130 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*   140 */   897,  897,  897,  701,  711,  890,  897,  897,  667,  897,
+ /*   150 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  599,
+ /*   160 */   597,  897,  699,  897,  897,  625,  897,  897,  709,  897,
+ /*   170 */   897,  714,  715,  897,  897,  897,  897,  897,  897,  897,
+ /*   180 */   613,  897,  897,  688,  897,  849,  897,  897,  897,  863,
+ /*   190 */   897,  897,  897,  861,  897,  897,  897,  690,  750,  830,
+ /*   200 */   897,  876,  878,  897,  897,  699,  708,  897,  897,  812,
+ /*   210 */   734,  734,  734,  646,  734,  734,  649,  744,  744,  596,
+ /*   220 */   596,  596,  596,  666,  897,  744,  735,  737,  727,  739,
+ /*   230 */   897,  897,  716,  716,  724,  726,  724,  726,  678,  678,
+ /*   240 */   663,  678,  649,  678,  822,  827,  897,  827,  897,  663,
+ /*   250 */   678,  678,  678,  822,  608,  716,  608,  716,  608,  716,
+ /*   260 */   716,  853,  855,  608,  716,  680,  680,  756,  744,  716,
+ /*   270 */   687,  687,  687,  687,  744,  680,  756,  716,  875,  875,
+ /*   280 */   716,  716,  883,  633,  651,  651,  858,  890,  895,  897,
+ /*   290 */   897,  897,  897,  763,  897,  897,  897,  897,  897,  897,
+ /*   300 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  836,
+ /*   310 */   897,  897,  897,  897,  768,  764,  897,  765,  897,  693,
+ /*   320 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*   330 */   728,  897,  736,  897,  897,  897,  897,  897,  897,  897,
+ /*   340 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*   350 */   897,  897,  897,  897,  897,  897,  851,  852,  897,  897,
+ /*   360 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*   370 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
+ /*   380 */   882,  897,  897,  885,  593,  897,  587,  590,  589,  591,
+ /*   390 */   595,  598,  620,  621,  622,  600,  601,  602,  603,  604,
+ /*   400 */   605,  606,  612,  614,  632,  634,  618,  636,  697,  698,
+ /*   410 */   760,  691,  692,  696,  771,  762,  766,  767,  769,  770,
+ /*   420 */   784,  785,  787,  793,  799,  802,  786,  791,  792,  794,
+ /*   430 */   798,  801,  694,  695,  805,  619,  626,  627,  630,  631,
+ /*   440 */   839,  841,  840,  842,  629,  628,  772,  775,  807,  808,
+ /*   450 */   864,  865,  866,  867,  868,  803,  815,  816,  717,  806,
+ /*   460 */   790,  729,  732,  733,  730,  700,  710,  719,  720,  721,
+ /*   470 */   722,  705,  706,  712,  725,  758,  759,  713,  702,  703,
+ /*   480 */   704,  804,  761,  773,  774,  637,  638,  768,  639,  640,
+ /*   490 */   641,  679,  682,  683,  684,  642,  661,  664,  665,  643,
+ /*   500 */   650,  644,  645,  652,  653,  654,  657,  658,  659,  660,
+ /*   510 */   655,  656,  823,  824,  828,  826,  825,  647,  648,  662,
+ /*   520 */   635,  624,  617,  668,  671,  672,  673,  674,  675,  677,
+ /*   530 */   669,  670,  615,  607,  609,  718,  845,  854,  850,  846,
+ /*   540 */   847,  848,  610,  819,  820,  681,  752,  753,  844,  857,
+ /*   550 */   859,  757,  860,  862,  887,  685,  686,  689,  829,  869,
+ /*   560 */   743,  746,  749,  751,  831,  832,  833,  834,  837,  838,
+ /*   570 */   835,  870,  874,  877,  879,  880,  881,  884,  886,  891,
+ /*   580 */   892,  893,  896,  894,  594,  588,
 };
 #define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
 
@@ -652,7 +655,6 @@ static const YYCODETYPE yyFallback[] = {
    23,  /*    REPLACE => ID */
    23,  /*   RESTRICT => ID */
    23,  /*        ROW => ID */
-   23,  /*  STATEMENT => ID */
    23,  /*    TRIGGER => ID */
    23,  /*     VACUUM => ID */
    23,  /*       VIEW => ID */
@@ -769,7 +771,12 @@ struct yyParser {
   int yyidx;                    /* Index of top element in stack */
   int yyerrcnt;                 /* Shifts left before out of the error */
   sqlite3ParserARG_SDECL                /* A place to hold %extra_argument */
+#if YYSTACKDEPTH<=0
+  int yystksz;                  /* Current side of the stack */
+  yyStackEntry *yystack;        /* The parser's stack */
+#else
   yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
+#endif
 };
 typedef struct yyParser yyParser;
 
@@ -822,55 +829,55 @@ static const char *const yyTokenName[] = {
   "INITIALLY",     "INSTEAD",       "LIKE_KW",       "MATCH",       
   "KEY",           "OF",            "OFFSET",        "PRAGMA",      
   "RAISE",         "REPLACE",       "RESTRICT",      "ROW",         
-  "STATEMENT",     "TRIGGER",       "VACUUM",        "VIEW",        
-  "VIRTUAL",       "REINDEX",       "RENAME",        "CTIME_KW",    
-  "ANY",           "OR",            "AND",           "IS",          
-  "BETWEEN",       "IN",            "ISNULL",        "NOTNULL",     
-  "NE",            "EQ",            "GT",            "LE",          
-  "LT",            "GE",            "ESCAPE",        "BITAND",      
-  "BITOR",         "LSHIFT",        "RSHIFT",        "PLUS",        
-  "MINUS",         "STAR",          "SLASH",         "REM",         
-  "CONCAT",        "COLLATE",       "UMINUS",        "UPLUS",       
-  "BITNOT",        "STRING",        "JOIN_KW",       "CONSTRAINT",  
-  "DEFAULT",       "NULL",          "PRIMARY",       "UNIQUE",      
-  "CHECK",         "REFERENCES",    "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",        "plus_num",      "minus_num",   
-  "carg",          "ccons",         "term",          "expr",        
-  "onconf",        "sortorder",     "autoinc",       "idxlist_opt", 
-  "refargs",       "defer_subclause",  "refarg",        "refact",      
-  "init_deferred_pred_opt",  "conslist",      "tcons",         "idxlist",     
-  "defer_subclause_opt",  "orconf",        "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",    
-  "exprlist",      "setlist",       "insert_cmd",    "inscollist_opt",
-  "itemlist",      "likeop",        "escape",        "between_op",  
-  "in_op",         "case_operand",  "case_exprlist",  "case_else",   
-  "expritem",      "uniqueflag",    "idxitem",       "collate",     
-  "nmnum",         "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",  "create_vtab",   "vtabarglist", 
-  "vtabarg",       "vtabargtoken",  "lp",            "anylist",     
+  "TRIGGER",       "VACUUM",        "VIEW",          "VIRTUAL",     
+  "REINDEX",       "RENAME",        "CTIME_KW",      "ANY",         
+  "OR",            "AND",           "IS",            "BETWEEN",     
+  "IN",            "ISNULL",        "NOTNULL",       "NE",          
+  "EQ",            "GT",            "LE",            "LT",          
+  "GE",            "ESCAPE",        "BITAND",        "BITOR",       
+  "LSHIFT",        "RSHIFT",        "PLUS",          "MINUS",       
+  "STAR",          "SLASH",         "REM",           "CONCAT",      
+  "COLLATE",       "UMINUS",        "UPLUS",         "BITNOT",      
+  "STRING",        "JOIN_KW",       "CONSTRAINT",    "DEFAULT",     
+  "NULL",          "PRIMARY",       "UNIQUE",        "CHECK",       
+  "REFERENCES",    "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",        "plus_num",      "minus_num",     "carg",        
+  "ccons",         "term",          "expr",          "onconf",      
+  "sortorder",     "autoinc",       "idxlist_opt",   "refargs",     
+  "defer_subclause",  "refarg",        "refact",        "init_deferred_pred_opt",
+  "conslist",      "tcons",         "idxlist",       "defer_subclause_opt",
+  "orconf",        "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",      "exprlist",    
+  "setlist",       "insert_cmd",    "inscollist_opt",  "itemlist",    
+  "likeop",        "escape",        "between_op",    "in_op",       
+  "case_operand",  "case_exprlist",  "case_else",     "expritem",    
+  "uniqueflag",    "idxitem",       "collate",       "nmnum",       
+  "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",  "create_vtab",   "vtabarglist",   "vtabarg",     
+  "vtabargtoken",  "lp",            "anylist",     
 };
 #endif /* NDEBUG */
 
@@ -1147,67 +1154,74 @@ static const char *const yyRuleName[] = {
  /* 266 */ "trigger_event ::= UPDATE OF inscollist",
  /* 267 */ "foreach_clause ::=",
  /* 268 */ "foreach_clause ::= FOR EACH ROW",
- /* 269 */ "foreach_clause ::= FOR EACH STATEMENT",
- /* 270 */ "when_clause ::=",
- /* 271 */ "when_clause ::= WHEN expr",
- /* 272 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 273 */ "trigger_cmd_list ::=",
- /* 274 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
- /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
- /* 276 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
- /* 277 */ "trigger_cmd ::= DELETE FROM nm where_opt",
- /* 278 */ "trigger_cmd ::= select",
- /* 279 */ "expr ::= RAISE LP IGNORE RP",
- /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 281 */ "raisetype ::= ROLLBACK",
- /* 282 */ "raisetype ::= ABORT",
- /* 283 */ "raisetype ::= FAIL",
- /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 269 */ "when_clause ::=",
+ /* 270 */ "when_clause ::= WHEN expr",
+ /* 271 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 272 */ "trigger_cmd_list ::=",
+ /* 273 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
+ /* 274 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
+ /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
+ /* 276 */ "trigger_cmd ::= DELETE FROM nm where_opt",
+ /* 277 */ "trigger_cmd ::= select",
+ /* 278 */ "expr ::= RAISE LP IGNORE RP",
+ /* 279 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 280 */ "raisetype ::= ROLLBACK",
+ /* 281 */ "raisetype ::= ABORT",
+ /* 282 */ "raisetype ::= FAIL",
+ /* 283 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 284 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 285 */ "cmd ::= DETACH database_kw_opt expr",
  /* 286 */ "key_opt ::=",
  /* 287 */ "key_opt ::= KEY expr",
  /* 288 */ "database_kw_opt ::= DATABASE",
  /* 289 */ "database_kw_opt ::=",
- /* 290 */ "cmd ::= DETACH database_kw_opt expr",
- /* 291 */ "cmd ::= REINDEX",
- /* 292 */ "cmd ::= REINDEX nm dbnm",
- /* 293 */ "cmd ::= ANALYZE",
- /* 294 */ "cmd ::= ANALYZE nm dbnm",
- /* 295 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 296 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 297 */ "add_column_fullname ::= fullname",
- /* 298 */ "kwcolumn_opt ::=",
- /* 299 */ "kwcolumn_opt ::= COLUMNKW",
- /* 300 */ "cmd ::= create_vtab",
- /* 301 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 302 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
- /* 303 */ "vtabarglist ::= vtabarg",
- /* 304 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 305 */ "vtabarg ::=",
- /* 306 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 307 */ "vtabargtoken ::= ANY",
- /* 308 */ "vtabargtoken ::= lp anylist RP",
- /* 309 */ "lp ::= LP",
- /* 310 */ "anylist ::=",
- /* 311 */ "anylist ::= anylist ANY",
+ /* 290 */ "cmd ::= REINDEX",
+ /* 291 */ "cmd ::= REINDEX nm dbnm",
+ /* 292 */ "cmd ::= ANALYZE",
+ /* 293 */ "cmd ::= ANALYZE nm dbnm",
+ /* 294 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 295 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 296 */ "add_column_fullname ::= fullname",
+ /* 297 */ "kwcolumn_opt ::=",
+ /* 298 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 299 */ "cmd ::= create_vtab",
+ /* 300 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 301 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
+ /* 302 */ "vtabarglist ::= vtabarg",
+ /* 303 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 304 */ "vtabarg ::=",
+ /* 305 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 306 */ "vtabargtoken ::= ANY",
+ /* 307 */ "vtabargtoken ::= lp anylist RP",
+ /* 308 */ "lp ::= LP",
+ /* 309 */ "anylist ::=",
+ /* 310 */ "anylist ::= anylist ANY",
 };
 #endif /* NDEBUG */
 
+
+#if YYSTACKDEPTH<=0
 /*
-** This function returns the symbolic name associated with a token
-** value.
+** Try to increase the size of the parser stack.
 */
-const char *sqlite3ParserTokenName(int tokenType){
+static void yyGrowStack(yyParser *p){
+  int newSize;
+  yyStackEntry *pNew;
+
+  newSize = p->yystksz*2 + 100;
+  pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
+  if( pNew ){
+    p->yystack = pNew;
+    p->yystksz = newSize;
 #ifndef NDEBUG
-  if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
-    return yyTokenName[tokenType];
-  }else{
-    return "Unknown";
-  }
-#else
-  return "";
+    if( yyTraceFILE ){
+      fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
+              yyTracePrompt, p->yystksz);
+    }
 #endif
+  }
 }
+#endif
 
 /* 
 ** This function allocates a new parser.
@@ -1226,6 +1240,9 @@ void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
   pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
   if( pParser ){
     pParser->yyidx = -1;
+#if YYSTACKDEPTH<=0
+    yyGrowStack(pParser);
+#endif
   }
   return pParser;
 }
@@ -1247,81 +1264,73 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
     ** which appear on the RHS of the rule, but which are not used
     ** inside the C code.
     */
-    case 156:
-    case 190:
-    case 207:
-#line 375 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3SelectDelete((yypminor->yy43));}
-#line 1257 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 155:
+    case 189:
+    case 206:
+#line 374 "parse.y"
+{sqlite3SelectDelete((yypminor->yy219));}
+#line 1274 "parse.c"
       break;
+    case 169:
     case 170:
-    case 171:
+    case 194:
+    case 196:
+    case 204:
+    case 210:
+    case 217:
+    case 220:
+    case 222:
+    case 223:
+    case 235:
+#line 623 "parse.y"
+{sqlite3ExprDelete((yypminor->yy172));}
+#line 1289 "parse.c"
+      break;
+    case 174:
+    case 182:
+    case 192:
     case 195:
     case 197:
-    case 205:
+    case 199:
+    case 209:
     case 211:
-    case 218:
+    case 212:
+    case 215:
     case 221:
-    case 223:
-    case 224:
-    case 236:
-#line 616 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3ExprDelete((yypminor->yy450));}
-#line 1272 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 863 "parse.y"
+{sqlite3ExprListDelete((yypminor->yy174));}
+#line 1304 "parse.c"
       break;
-    case 175:
-    case 183:
+    case 188:
     case 193:
-    case 196:
-    case 198:
-    case 200:
-    case 210:
-    case 212:
-    case 213:
-    case 216:
-    case 222:
-#line 856 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3ExprListDelete((yypminor->yy242));}
-#line 1287 "ext/pdo_sqlite/sqlite/src/parse.c"
-      break;
-    case 189:
-    case 194:
+    case 201:
     case 202:
-    case 203:
-#line 488 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3SrcListDelete((yypminor->yy419));}
-#line 1295 "ext/pdo_sqlite/sqlite/src/parse.c"
-      break;
-    case 199:
-#line 546 "ext/pdo_sqlite/sqlite/src/parse.y"
-{
-  sqlite3ExprDelete((yypminor->yy84).pLimit);
-  sqlite3ExprDelete((yypminor->yy84).pOffset);
-}
-#line 1303 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 487 "parse.y"
+{sqlite3SrcListDelete((yypminor->yy373));}
+#line 1312 "parse.c"
       break;
-    case 206:
-    case 209:
-    case 215:
-#line 505 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3IdListDelete((yypminor->yy352));}
-#line 1310 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 205:
+    case 208:
+    case 214:
+#line 504 "parse.y"
+{sqlite3IdListDelete((yypminor->yy432));}
+#line 1319 "parse.c"
       break;
-    case 232:
-    case 237:
-#line 957 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DeleteTriggerStep((yypminor->yy75));}
-#line 1316 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 231:
+    case 236:
+#line 964 "parse.y"
+{sqlite3DeleteTriggerStep((yypminor->yy243));}
+#line 1325 "parse.c"
       break;
-    case 234:
-#line 941 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3IdListDelete((yypminor->yy354).b);}
-#line 1321 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 233:
+#line 950 "parse.y"
+{sqlite3IdListDelete((yypminor->yy370).b);}
+#line 1330 "parse.c"
       break;
-    case 239:
-#line 1025 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3ExprDelete((yypminor->yy158));}
-#line 1326 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 238:
+#line 1037 "parse.y"
+{sqlite3ExprDelete((yypminor->yy386));}
+#line 1335 "parse.c"
       break;
     default:  break;   /* If no destructor action specified: do nothing */
   }
@@ -1372,6 +1381,9 @@ void sqlite3ParserFree(
   yyParser *pParser = (yyParser*)p;
   if( pParser==0 ) return;
   while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
+#if YYSTACKDEPTH<=0
+  free(pParser->yystack);
+#endif
   (*freeProc)((void*)pParser);
 }
 
@@ -1463,6 +1475,28 @@ static int yy_find_reduce_action(
   }
 }
 
+/*
+** The following routine is called if the stack overflows.
+*/
+static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
+   sqlite3ParserARG_FETCH;
+   yypParser->yyidx--;
+#ifndef NDEBUG
+   if( yyTraceFILE ){
+     fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+   }
+#endif
+   while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+   /* Here code is inserted which will execute if the parser
+   ** stack every overflows */
+#line 44 "parse.y"
+
+  sqlite3ErrorMsg(pParse, "parser stack overflow");
+  pParse->parseError = 1;
+#line 1499 "parse.c"
+   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
+}
+
 /*
 ** Perform a shift action.
 */
@@ -1474,25 +1508,20 @@ static void yy_shift(
 ){
   yyStackEntry *yytos;
   yypParser->yyidx++;
+#if YYSTACKDEPTH>0 
   if( yypParser->yyidx>=YYSTACKDEPTH ){
-     sqlite3ParserARG_FETCH;
-     yypParser->yyidx--;
-#ifndef NDEBUG
-     if( yyTraceFILE ){
-       fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
-     }
-#endif
-     while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-     /* Here code is inserted which will execute if the parser
-     ** stack every overflows */
-#line 44 "ext/pdo_sqlite/sqlite/src/parse.y"
-
-  sqlite3ErrorMsg(pParse, "parser stack overflow");
-  pParse->parseError = 1;
-#line 1495 "ext/pdo_sqlite/sqlite/src/parse.c"
-     sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
-     return;
+    yyStackOverflow(yypParser, yypMinor);
+    return;
   }
+#else
+  if( yypParser->yyidx>=yypParser->yystksz ){
+    yyGrowStack(yypParser);
+    if( yypParser->yyidx>=yypParser->yystksz ){
+      yyStackOverflow(yypParser, yypMinor);
+      return;
+    }
+  }
+#endif
   yytos = &yypParser->yystack[yypParser->yyidx];
   yytos->stateno = yyNewState;
   yytos->major = yyMajor;
@@ -1516,318 +1545,317 @@ static const struct {
   YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
   unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
 } yyRuleInfo[] = {
+  { 139, 1 },
+  { 140, 2 },
   { 140, 1 },
-  { 141, 2 },
-  { 141, 1 },
-  { 143, 1 },
   { 142, 1 },
-  { 142, 3 },
-  { 145, 0 },
-  { 145, 1 },
-  { 145, 3 },
+  { 141, 1 },
+  { 141, 3 },
+  { 144, 0 },
+  { 144, 1 },
   { 144, 3 },
-  { 147, 0 },
-  { 147, 1 },
-  { 147, 2 },
+  { 143, 3 },
   { 146, 0 },
   { 146, 1 },
-  { 146, 1 },
-  { 146, 1 },
-  { 144, 2 },
-  { 144, 2 },
-  { 144, 2 },
-  { 144, 2 },
-  { 149, 6 },
-  { 152, 0 },
-  { 152, 3 },
-  { 151, 1 },
+  { 146, 2 },
+  { 145, 0 },
+  { 145, 1 },
+  { 145, 1 },
+  { 145, 1 },
+  { 143, 2 },
+  { 143, 2 },
+  { 143, 2 },
+  { 143, 2 },
+  { 148, 6 },
   { 151, 0 },
-  { 150, 4 },
-  { 150, 2 },
-  { 154, 3 },
-  { 154, 1 },
-  { 157, 3 },
-  { 158, 1 },
+  { 151, 3 },
+  { 150, 1 },
+  { 150, 0 },
+  { 149, 4 },
+  { 149, 2 },
+  { 153, 3 },
+  { 153, 1 },
+  { 156, 3 },
+  { 157, 1 },
+  { 160, 1 },
   { 161, 1 },
+  { 147, 1 },
+  { 147, 1 },
+  { 147, 1 },
+  { 158, 0 },
+  { 158, 1 },
   { 162, 1 },
-  { 148, 1 },
-  { 148, 1 },
-  { 148, 1 },
-  { 159, 0 },
-  { 159, 1 },
+  { 162, 4 },
+  { 162, 6 },
   { 163, 1 },
-  { 163, 4 },
-  { 163, 6 },
+  { 163, 2 },
   { 164, 1 },
-  { 164, 2 },
-  { 165, 1 },
-  { 165, 1 },
-  { 160, 2 },
-  { 160, 0 },
+  { 164, 1 },
+  { 159, 2 },
+  { 159, 0 },
+  { 167, 3 },
+  { 167, 1 },
+  { 168, 2 },
+  { 168, 4 },
+  { 168, 3 },
+  { 168, 3 },
+  { 168, 2 },
+  { 168, 2 },
   { 168, 3 },
+  { 168, 5 },
+  { 168, 2 },
+  { 168, 4 },
+  { 168, 4 },
   { 168, 1 },
-  { 169, 2 },
-  { 169, 4 },
-  { 169, 3 },
-  { 169, 3 },
-  { 169, 2 },
-  { 169, 2 },
-  { 169, 3 },
-  { 169, 5 },
-  { 169, 2 },
-  { 169, 4 },
-  { 169, 4 },
-  { 169, 1 },
-  { 169, 2 },
-  { 174, 0 },
-  { 174, 1 },
-  { 176, 0 },
-  { 176, 2 },
+  { 168, 2 },
+  { 173, 0 },
+  { 173, 1 },
+  { 175, 0 },
+  { 175, 2 },
+  { 177, 2 },
+  { 177, 3 },
+  { 177, 3 },
+  { 177, 3 },
+  { 178, 2 },
   { 178, 2 },
-  { 178, 3 },
-  { 178, 3 },
-  { 178, 3 },
+  { 178, 1 },
+  { 178, 1 },
+  { 176, 3 },
+  { 176, 2 },
+  { 179, 0 },
   { 179, 2 },
   { 179, 2 },
-  { 179, 1 },
-  { 179, 1 },
-  { 177, 3 },
-  { 177, 2 },
-  { 180, 0 },
-  { 180, 2 },
+  { 154, 0 },
+  { 154, 2 },
+  { 180, 3 },
   { 180, 2 },
-  { 155, 0 },
-  { 155, 2 },
-  { 181, 3 },
+  { 180, 1 },
   { 181, 2 },
-  { 181, 1 },
-  { 182, 2 },
-  { 182, 7 },
-  { 182, 5 },
-  { 182, 5 },
-  { 182, 10 },
+  { 181, 7 },
+  { 181, 5 },
+  { 181, 5 },
+  { 181, 10 },
+  { 183, 0 },
+  { 183, 1 },
+  { 171, 0 },
+  { 171, 3 },
   { 184, 0 },
-  { 184, 1 },
-  { 172, 0 },
-  { 172, 3 },
-  { 185, 0 },
-  { 185, 2 },
-  { 186, 1 },
-  { 186, 1 },
-  { 186, 1 },
-  { 144, 4 },
-  { 188, 2 },
-  { 188, 0 },
-  { 144, 8 },
-  { 144, 4 },
-  { 144, 1 },
-  { 156, 1 },
-  { 156, 3 },
+  { 184, 2 },
+  { 185, 1 },
+  { 185, 1 },
+  { 185, 1 },
+  { 143, 4 },
+  { 187, 2 },
+  { 187, 0 },
+  { 143, 8 },
+  { 143, 4 },
+  { 143, 1 },
+  { 155, 1 },
+  { 155, 3 },
+  { 190, 1 },
+  { 190, 2 },
+  { 190, 1 },
+  { 189, 9 },
   { 191, 1 },
-  { 191, 2 },
   { 191, 1 },
-  { 190, 9 },
-  { 192, 1 },
-  { 192, 1 },
-  { 192, 0 },
+  { 191, 0 },
+  { 199, 2 },
+  { 199, 0 },
+  { 192, 3 },
+  { 192, 2 },
+  { 192, 4 },
   { 200, 2 },
+  { 200, 1 },
   { 200, 0 },
-  { 193, 3 },
+  { 193, 0 },
   { 193, 2 },
-  { 193, 4 },
-  { 201, 2 },
-  { 201, 1 },
-  { 201, 0 },
-  { 194, 0 },
-  { 194, 2 },
+  { 202, 2 },
+  { 202, 0 },
+  { 201, 6 },
+  { 201, 7 },
+  { 206, 1 },
+  { 206, 1 },
+  { 152, 0 },
+  { 152, 2 },
+  { 188, 2 },
+  { 203, 1 },
   { 203, 2 },
-  { 203, 0 },
-  { 202, 6 },
-  { 202, 7 },
-  { 207, 1 },
-  { 207, 1 },
-  { 153, 0 },
-  { 153, 2 },
-  { 189, 2 },
-  { 204, 1 },
+  { 203, 3 },
+  { 203, 4 },
   { 204, 2 },
-  { 204, 3 },
-  { 204, 4 },
-  { 205, 2 },
+  { 204, 0 },
+  { 205, 4 },
   { 205, 0 },
-  { 206, 4 },
-  { 206, 0 },
-  { 198, 0 },
-  { 198, 3 },
-  { 210, 4 },
-  { 210, 2 },
-  { 211, 1 },
-  { 173, 1 },
-  { 173, 1 },
-  { 173, 0 },
-  { 196, 0 },
-  { 196, 3 },
   { 197, 0 },
-  { 197, 2 },
-  { 199, 0 },
-  { 199, 2 },
-  { 199, 4 },
-  { 199, 4 },
-  { 144, 4 },
+  { 197, 3 },
+  { 209, 4 },
+  { 209, 2 },
+  { 210, 1 },
+  { 172, 1 },
+  { 172, 1 },
+  { 172, 0 },
   { 195, 0 },
-  { 195, 2 },
-  { 144, 6 },
-  { 213, 5 },
-  { 213, 3 },
-  { 144, 8 },
-  { 144, 5 },
-  { 144, 6 },
-  { 214, 2 },
-  { 214, 1 },
-  { 216, 3 },
-  { 216, 1 },
-  { 215, 0 },
+  { 195, 3 },
+  { 196, 0 },
+  { 196, 2 },
+  { 198, 0 },
+  { 198, 2 },
+  { 198, 4 },
+  { 198, 4 },
+  { 143, 4 },
+  { 194, 0 },
+  { 194, 2 },
+  { 143, 6 },
+  { 212, 5 },
+  { 212, 3 },
+  { 143, 8 },
+  { 143, 5 },
+  { 143, 6 },
+  { 213, 2 },
+  { 213, 1 },
   { 215, 3 },
-  { 209, 3 },
-  { 209, 1 },
-  { 171, 1 },
-  { 171, 3 },
+  { 215, 1 },
+  { 214, 0 },
+  { 214, 3 },
+  { 208, 3 },
+  { 208, 1 },
   { 170, 1 },
-  { 171, 1 },
-  { 171, 1 },
-  { 171, 3 },
-  { 171, 5 },
+  { 170, 3 },
+  { 169, 1 },
   { 170, 1 },
   { 170, 1 },
-  { 171, 1 },
-  { 171, 1 },
-  { 171, 3 },
-  { 171, 6 },
-  { 171, 5 },
-  { 171, 4 },
+  { 170, 3 },
+  { 170, 5 },
+  { 169, 1 },
+  { 169, 1 },
   { 170, 1 },
-  { 171, 3 },
-  { 171, 3 },
-  { 171, 3 },
-  { 171, 3 },
-  { 171, 3 },
-  { 171, 3 },
-  { 171, 3 },
-  { 171, 3 },
-  { 217, 1 },
-  { 217, 2 },
-  { 217, 1 },
+  { 170, 1 },
+  { 170, 3 },
+  { 170, 6 },
+  { 170, 5 },
+  { 170, 4 },
+  { 169, 1 },
+  { 170, 3 },
+  { 170, 3 },
+  { 170, 3 },
+  { 170, 3 },
+  { 170, 3 },
+  { 170, 3 },
+  { 170, 3 },
+  { 170, 3 },
+  { 216, 1 },
+  { 216, 2 },
+  { 216, 1 },
+  { 216, 2 },
   { 217, 2 },
+  { 217, 0 },
+  { 170, 4 },
+  { 170, 2 },
+  { 170, 3 },
+  { 170, 3 },
+  { 170, 4 },
+  { 170, 2 },
+  { 170, 2 },
+  { 170, 2 },
+  { 218, 1 },
   { 218, 2 },
-  { 218, 0 },
-  { 171, 4 },
-  { 171, 2 },
-  { 171, 3 },
-  { 171, 3 },
-  { 171, 4 },
-  { 171, 2 },
-  { 171, 2 },
-  { 171, 2 },
+  { 170, 5 },
   { 219, 1 },
   { 219, 2 },
-  { 171, 5 },
+  { 170, 5 },
+  { 170, 3 },
+  { 170, 5 },
+  { 170, 4 },
+  { 170, 4 },
+  { 170, 5 },
+  { 221, 5 },
+  { 221, 4 },
+  { 222, 2 },
+  { 222, 0 },
   { 220, 1 },
-  { 220, 2 },
-  { 171, 5 },
-  { 171, 3 },
-  { 171, 5 },
-  { 171, 4 },
-  { 171, 4 },
-  { 171, 5 },
-  { 222, 5 },
-  { 222, 4 },
-  { 223, 2 },
+  { 220, 0 },
+  { 211, 3 },
+  { 211, 1 },
+  { 223, 1 },
   { 223, 0 },
-  { 221, 1 },
-  { 221, 0 },
-  { 212, 3 },
-  { 212, 1 },
+  { 143, 11 },
   { 224, 1 },
   { 224, 0 },
-  { 144, 11 },
+  { 174, 0 },
+  { 174, 3 },
+  { 182, 5 },
+  { 182, 3 },
   { 225, 1 },
-  { 225, 0 },
-  { 175, 0 },
-  { 175, 3 },
-  { 183, 5 },
-  { 183, 3 },
-  { 226, 1 },
-  { 227, 0 },
-  { 227, 2 },
-  { 144, 4 },
-  { 144, 1 },
-  { 144, 2 },
-  { 144, 5 },
-  { 144, 5 },
-  { 144, 5 },
-  { 144, 6 },
-  { 144, 3 },
-  { 228, 1 },
-  { 228, 1 },
+  { 226, 0 },
+  { 226, 2 },
+  { 143, 4 },
+  { 143, 1 },
+  { 143, 2 },
+  { 143, 5 },
+  { 143, 5 },
+  { 143, 5 },
+  { 143, 6 },
+  { 143, 3 },
+  { 227, 1 },
+  { 227, 1 },
+  { 165, 2 },
   { 166, 2 },
-  { 167, 2 },
-  { 230, 1 },
   { 229, 1 },
-  { 229, 0 },
-  { 144, 5 },
-  { 231, 11 },
+  { 228, 1 },
+  { 228, 0 },
+  { 143, 5 },
+  { 230, 11 },
+  { 232, 1 },
+  { 232, 1 },
+  { 232, 2 },
+  { 232, 0 },
   { 233, 1 },
   { 233, 1 },
-  { 233, 2 },
-  { 233, 0 },
-  { 234, 1 },
-  { 234, 1 },
+  { 233, 3 },
+  { 234, 0 },
   { 234, 3 },
   { 235, 0 },
-  { 235, 3 },
-  { 235, 3 },
-  { 236, 0 },
-  { 236, 2 },
-  { 232, 3 },
-  { 232, 0 },
-  { 237, 6 },
-  { 237, 8 },
-  { 237, 5 },
-  { 237, 4 },
-  { 237, 1 },
-  { 171, 4 },
-  { 171, 6 },
-  { 187, 1 },
-  { 187, 1 },
-  { 187, 1 },
-  { 144, 4 },
-  { 144, 6 },
-  { 239, 0 },
-  { 239, 2 },
-  { 238, 1 },
+  { 235, 2 },
+  { 231, 3 },
+  { 231, 0 },
+  { 236, 6 },
+  { 236, 8 },
+  { 236, 5 },
+  { 236, 4 },
+  { 236, 1 },
+  { 170, 4 },
+  { 170, 6 },
+  { 186, 1 },
+  { 186, 1 },
+  { 186, 1 },
+  { 143, 4 },
+  { 143, 6 },
+  { 143, 3 },
   { 238, 0 },
-  { 144, 3 },
-  { 144, 1 },
-  { 144, 3 },
-  { 144, 1 },
-  { 144, 3 },
-  { 144, 6 },
-  { 144, 6 },
+  { 238, 2 },
+  { 237, 1 },
+  { 237, 0 },
+  { 143, 1 },
+  { 143, 3 },
+  { 143, 1 },
+  { 143, 3 },
+  { 143, 6 },
+  { 143, 6 },
+  { 239, 1 },
+  { 240, 0 },
   { 240, 1 },
-  { 241, 0 },
-  { 241, 1 },
-  { 144, 1 },
-  { 144, 4 },
-  { 242, 7 },
-  { 243, 1 },
-  { 243, 3 },
-  { 244, 0 },
-  { 244, 2 },
+  { 143, 1 },
+  { 143, 4 },
+  { 241, 7 },
+  { 242, 1 },
+  { 242, 3 },
+  { 243, 0 },
+  { 243, 2 },
+  { 244, 1 },
+  { 244, 3 },
   { 245, 1 },
-  { 245, 3 },
-  { 246, 1 },
-  { 247, 0 },
-  { 247, 2 },
+  { 246, 0 },
+  { 246, 2 },
 };
 
 static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -1881,62 +1909,102 @@ static void yy_reduce(
   **  #line <lineno> <thisfile>
   **     break;
   */
+      case 0:
+      case 1:
+      case 2:
+      case 4:
+      case 5:
+      case 10:
+      case 11:
+      case 12:
+      case 20:
+      case 28:
+      case 29:
+      case 37:
+      case 44:
+      case 45:
+      case 46:
+      case 47:
+      case 48:
+      case 49:
+      case 55:
+      case 82:
+      case 83:
+      case 84:
+      case 85:
+      case 256:
+      case 257:
+      case 267:
+      case 268:
+      case 288:
+      case 289:
+      case 297:
+      case 298:
+      case 302:
+      case 303:
+      case 305:
+      case 309:
+#line 97 "parse.y"
+{
+}
+#line 1953 "parse.c"
+        break;
       case 3:
-#line 100 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 100 "parse.y"
 { sqlite3FinishCoding(pParse); }
-#line 1890 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1958 "parse.c"
         break;
       case 6:
-#line 103 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 103 "parse.y"
 { sqlite3BeginParse(pParse, 0); }
-#line 1895 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1963 "parse.c"
         break;
       case 7:
-#line 105 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 105 "parse.y"
 { sqlite3BeginParse(pParse, 1); }
-#line 1900 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1968 "parse.c"
         break;
       case 8:
-#line 106 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 106 "parse.y"
 { sqlite3BeginParse(pParse, 2); }
-#line 1905 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1973 "parse.c"
         break;
       case 9:
-#line 112 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy316);}
-#line 1910 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 112 "parse.y"
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy46);}
+#line 1978 "parse.c"
         break;
       case 13:
-#line 117 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = TK_DEFERRED;}
-#line 1915 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 117 "parse.y"
+{yygotominor.yy46 = TK_DEFERRED;}
+#line 1983 "parse.c"
         break;
       case 14:
       case 15:
       case 16:
       case 107:
       case 109:
-#line 118 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = yymsp[0].major;}
-#line 1924 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 118 "parse.y"
+{yygotominor.yy46 = yymsp[0].major;}
+#line 1992 "parse.c"
         break;
       case 17:
       case 18:
-#line 121 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 121 "parse.y"
 {sqlite3CommitTransaction(pParse);}
-#line 1930 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1998 "parse.c"
         break;
       case 19:
-#line 123 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 123 "parse.y"
 {sqlite3RollbackTransaction(pParse);}
-#line 1935 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2003 "parse.c"
         break;
       case 21:
-#line 128 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 128 "parse.y"
 {
-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178,yymsp[-4].minor.yy316,0,0,yymsp[-2].minor.yy316);
+   sqlite3StartTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,yymsp[-4].minor.yy46,0,0,yymsp[-2].minor.yy46);
 }
-#line 1942 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2010 "parse.c"
         break;
       case 22:
       case 25:
@@ -1949,9 +2017,9 @@ static void yy_reduce(
       case 113:
       case 212:
       case 215:
-#line 132 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = 0;}
-#line 1957 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 132 "parse.y"
+{yygotominor.yy46 = 0;}
+#line 2025 "parse.c"
         break;
       case 23:
       case 24:
@@ -1961,40 +2029,40 @@ static void yy_reduce(
       case 111:
       case 213:
       case 216:
-#line 133 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = 1;}
-#line 1969 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 133 "parse.y"
+{yygotominor.yy46 = 1;}
+#line 2037 "parse.c"
         break;
       case 26:
-#line 139 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 139 "parse.y"
 {
-  sqlite3EndTable(pParse,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy0,0);
+  sqlite3EndTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy0,0);
 }
-#line 1976 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2044 "parse.c"
         break;
       case 27:
-#line 142 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 142 "parse.y"
 {
-  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy43);
-  sqlite3SelectDelete(yymsp[0].minor.yy43);
+  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy219);
+  sqlite3SelectDelete(yymsp[0].minor.yy219);
 }
-#line 1984 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2052 "parse.c"
         break;
       case 30:
-#line 154 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 154 "parse.y"
 {
-  yygotominor.yy178.z = yymsp[-2].minor.yy178.z;
-  yygotominor.yy178.n = (pParse->sLastToken.z-yymsp[-2].minor.yy178.z) + pParse->sLastToken.n;
+  yygotominor.yy410.z = yymsp[-2].minor.yy410.z;
+  yygotominor.yy410.n = (pParse->sLastToken.z-yymsp[-2].minor.yy410.z) + pParse->sLastToken.n;
 }
-#line 1992 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2060 "parse.c"
         break;
       case 31:
-#line 158 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 158 "parse.y"
 {
-  sqlite3AddColumn(pParse,&yymsp[0].minor.yy178);
-  yygotominor.yy178 = yymsp[0].minor.yy178;
+  sqlite3AddColumn(pParse,&yymsp[0].minor.yy410);
+  yygotominor.yy410 = yymsp[0].minor.yy410;
 }
-#line 2000 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2068 "parse.c"
         break;
       case 32:
       case 33:
@@ -2002,14 +2070,14 @@ static void yy_reduce(
       case 35:
       case 36:
       case 255:
-#line 168 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178 = yymsp[0].minor.yy0;}
-#line 2010 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 168 "parse.y"
+{yygotominor.yy410 = yymsp[0].minor.yy0;}
+#line 2078 "parse.c"
         break;
       case 38:
-#line 229 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy178);}
-#line 2015 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 229 "parse.y"
+{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy410);}
+#line 2083 "parse.c"
         break;
       case 39:
       case 42:
@@ -2022,152 +2090,142 @@ static void yy_reduce(
       case 252:
       case 253:
       case 254:
-#line 230 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178 = yymsp[0].minor.yy178;}
-#line 2030 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 230 "parse.y"
+{yygotominor.yy410 = yymsp[0].minor.yy410;}
+#line 2098 "parse.c"
         break;
       case 40:
-#line 231 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 231 "parse.y"
 {
-  yygotominor.yy178.z = yymsp[-3].minor.yy178.z;
-  yygotominor.yy178.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy178.z;
+  yygotominor.yy410.z = yymsp[-3].minor.yy410.z;
+  yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy410.z;
 }
-#line 2038 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2106 "parse.c"
         break;
       case 41:
-#line 235 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 235 "parse.y"
 {
-  yygotominor.yy178.z = yymsp[-5].minor.yy178.z;
-  yygotominor.yy178.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy178.z;
+  yygotominor.yy410.z = yymsp[-5].minor.yy410.z;
+  yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy410.z;
 }
-#line 2046 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2114 "parse.c"
         break;
       case 43:
-#line 241 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178.z=yymsp[-1].minor.yy178.z; yygotominor.yy178.n=yymsp[0].minor.yy178.n+(yymsp[0].minor.yy178.z-yymsp[-1].minor.yy178.z);}
-#line 2051 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 44:
-#line 243 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = atoi((char*)yymsp[0].minor.yy178.z); }
-#line 2056 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 45:
-#line 244 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = -atoi((char*)yymsp[0].minor.yy178.z); }
-#line 2061 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 241 "parse.y"
+{yygotominor.yy410.z=yymsp[-1].minor.yy410.z; yygotominor.yy410.n=yymsp[0].minor.yy410.n+(yymsp[0].minor.yy410.z-yymsp[-1].minor.yy410.z);}
+#line 2119 "parse.c"
         break;
       case 50:
       case 52:
-#line 253 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy450);}
-#line 2067 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 252 "parse.y"
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy172);}
+#line 2125 "parse.c"
         break;
       case 51:
-#line 254 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy450);}
-#line 2072 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 253 "parse.y"
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy172);}
+#line 2130 "parse.c"
         break;
       case 53:
-#line 256 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 255 "parse.y"
 {
-  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy450, 0, 0);
+  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
   sqlite3AddDefaultValue(pParse,p);
 }
-#line 2080 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2138 "parse.c"
         break;
       case 54:
-#line 260 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 259 "parse.y"
 {
-  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy178);
+  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy410);
   sqlite3AddDefaultValue(pParse,p);
 }
-#line 2088 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2146 "parse.c"
         break;
       case 56:
-#line 269 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy316);}
-#line 2093 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 268 "parse.y"
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy46);}
+#line 2151 "parse.c"
         break;
       case 57:
-#line 271 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy316,yymsp[0].minor.yy316,yymsp[-2].minor.yy316);}
-#line 2098 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 270 "parse.y"
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy46,yymsp[0].minor.yy46,yymsp[-2].minor.yy46);}
+#line 2156 "parse.c"
         break;
       case 58:
-#line 272 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy316,0,0,0,0);}
-#line 2103 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 271 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy46,0,0,0,0);}
+#line 2161 "parse.c"
         break;
       case 59:
-#line 273 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy450);}
-#line 2108 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 272 "parse.y"
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy172);}
+#line 2166 "parse.c"
         break;
       case 60:
-#line 275 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy178,yymsp[-1].minor.yy242,yymsp[0].minor.yy316);}
-#line 2113 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 274 "parse.y"
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy410,yymsp[-1].minor.yy174,yymsp[0].minor.yy46);}
+#line 2171 "parse.c"
         break;
       case 61:
-#line 276 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy316);}
-#line 2118 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 275 "parse.y"
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy46);}
+#line 2176 "parse.c"
         break;
       case 62:
-#line 277 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy178.z, yymsp[0].minor.yy178.n);}
-#line 2123 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 276 "parse.y"
+{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy410.z, yymsp[0].minor.yy410.n);}
+#line 2181 "parse.c"
         break;
       case 65:
-#line 290 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = OE_Restrict * 0x010101; }
-#line 2128 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 289 "parse.y"
+{ yygotominor.yy46 = OE_Restrict * 0x010101; }
+#line 2186 "parse.c"
         break;
       case 66:
-#line 291 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = (yymsp[-1].minor.yy316 & yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
-#line 2133 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 290 "parse.y"
+{ yygotominor.yy46 = (yymsp[-1].minor.yy46 & yymsp[0].minor.yy405.mask) | yymsp[0].minor.yy405.value; }
+#line 2191 "parse.c"
         break;
       case 67:
-#line 293 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy207.value = 0;     yygotominor.yy207.mask = 0x000000; }
-#line 2138 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 292 "parse.y"
+{ yygotominor.yy405.value = 0;     yygotominor.yy405.mask = 0x000000; }
+#line 2196 "parse.c"
         break;
       case 68:
-#line 294 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy207.value = yymsp[0].minor.yy316;     yygotominor.yy207.mask = 0x0000ff; }
-#line 2143 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 293 "parse.y"
+{ yygotominor.yy405.value = yymsp[0].minor.yy46;     yygotominor.yy405.mask = 0x0000ff; }
+#line 2201 "parse.c"
         break;
       case 69:
-#line 295 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy207.value = yymsp[0].minor.yy316<<8;  yygotominor.yy207.mask = 0x00ff00; }
-#line 2148 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 294 "parse.y"
+{ yygotominor.yy405.value = yymsp[0].minor.yy46<<8;  yygotominor.yy405.mask = 0x00ff00; }
+#line 2206 "parse.c"
         break;
       case 70:
-#line 296 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy207.value = yymsp[0].minor.yy316<<16; yygotominor.yy207.mask = 0xff0000; }
-#line 2153 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 295 "parse.y"
+{ yygotominor.yy405.value = yymsp[0].minor.yy46<<16; yygotominor.yy405.mask = 0xff0000; }
+#line 2211 "parse.c"
         break;
       case 71:
-#line 298 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = OE_SetNull; }
-#line 2158 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 297 "parse.y"
+{ yygotominor.yy46 = OE_SetNull; }
+#line 2216 "parse.c"
         break;
       case 72:
-#line 299 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = OE_SetDflt; }
-#line 2163 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 298 "parse.y"
+{ yygotominor.yy46 = OE_SetDflt; }
+#line 2221 "parse.c"
         break;
       case 73:
-#line 300 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = OE_Cascade; }
-#line 2168 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 299 "parse.y"
+{ yygotominor.yy46 = OE_Cascade; }
+#line 2226 "parse.c"
         break;
       case 74:
-#line 301 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = OE_Restrict; }
-#line 2173 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 300 "parse.y"
+{ yygotominor.yy46 = OE_Restrict; }
+#line 2231 "parse.c"
         break;
       case 75:
       case 76:
@@ -2176,237 +2234,237 @@ static void yy_reduce(
       case 95:
       case 96:
       case 166:
-#line 303 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = yymsp[0].minor.yy316;}
-#line 2184 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 302 "parse.y"
+{yygotominor.yy46 = yymsp[0].minor.yy46;}
+#line 2242 "parse.c"
         break;
       case 80:
-#line 313 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178.n = 0; yygotominor.yy178.z = 0;}
-#line 2189 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 312 "parse.y"
+{yygotominor.yy410.n = 0; yygotominor.yy410.z = 0;}
+#line 2247 "parse.c"
         break;
       case 81:
-#line 314 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178 = yymsp[-1].minor.yy0;}
-#line 2194 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 313 "parse.y"
+{yygotominor.yy410 = yymsp[-1].minor.yy0;}
+#line 2252 "parse.c"
         break;
       case 86:
-#line 320 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy316,yymsp[-2].minor.yy316,0);}
-#line 2199 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 319 "parse.y"
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy174,yymsp[0].minor.yy46,yymsp[-2].minor.yy46,0);}
+#line 2257 "parse.c"
         break;
       case 87:
-#line 322 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy242,yymsp[0].minor.yy316,0,0,0,0);}
-#line 2204 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 321 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy174,yymsp[0].minor.yy46,0,0,0,0);}
+#line 2262 "parse.c"
         break;
       case 88:
-#line 323 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy450);}
-#line 2209 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 322 "parse.y"
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy172);}
+#line 2267 "parse.c"
         break;
       case 89:
-#line 325 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 324 "parse.y"
 {
-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy242, &yymsp[-3].minor.yy178, yymsp[-2].minor.yy242, yymsp[-1].minor.yy316);
-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy316);
+    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy174, &yymsp[-3].minor.yy410, yymsp[-2].minor.yy174, yymsp[-1].minor.yy46);
+    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy46);
 }
-#line 2217 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2275 "parse.c"
         break;
       case 92:
       case 94:
-#line 339 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = OE_Default;}
-#line 2223 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 338 "parse.y"
+{yygotominor.yy46 = OE_Default;}
+#line 2281 "parse.c"
         break;
       case 97:
-#line 344 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = OE_Ignore;}
-#line 2228 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 343 "parse.y"
+{yygotominor.yy46 = OE_Ignore;}
+#line 2286 "parse.c"
         break;
       case 98:
       case 167:
-#line 345 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = OE_Replace;}
-#line 2234 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 344 "parse.y"
+{yygotominor.yy46 = OE_Replace;}
+#line 2292 "parse.c"
         break;
       case 99:
-#line 349 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 348 "parse.y"
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy419, 0, yymsp[-1].minor.yy316);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy373, 0, yymsp[-1].minor.yy46);
 }
-#line 2241 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2299 "parse.c"
         break;
       case 102:
-#line 359 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 358 "parse.y"
 {
-  sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy178, &yymsp[-2].minor.yy178, yymsp[0].minor.yy43, yymsp[-6].minor.yy316, yymsp[-4].minor.yy316);
+  sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, yymsp[0].minor.yy219, yymsp[-6].minor.yy46, yymsp[-4].minor.yy46);
 }
-#line 2248 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2306 "parse.c"
         break;
       case 103:
-#line 362 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 361 "parse.y"
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy419, 1, yymsp[-1].minor.yy316);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy373, 1, yymsp[-1].minor.yy46);
 }
-#line 2255 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2313 "parse.c"
         break;
       case 104:
-#line 369 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 368 "parse.y"
 {
-  sqlite3Select(pParse, yymsp[0].minor.yy43, SRT_Callback, 0, 0, 0, 0, 0);
-  sqlite3SelectDelete(yymsp[0].minor.yy43);
+  sqlite3Select(pParse, yymsp[0].minor.yy219, SRT_Callback, 0, 0, 0, 0, 0);
+  sqlite3SelectDelete(yymsp[0].minor.yy219);
 }
-#line 2263 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2321 "parse.c"
         break;
       case 105:
       case 128:
-#line 379 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy43 = yymsp[0].minor.yy43;}
-#line 2269 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 378 "parse.y"
+{yygotominor.yy219 = yymsp[0].minor.yy219;}
+#line 2327 "parse.c"
         break;
       case 106:
-#line 381 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 380 "parse.y"
 {
-  if( yymsp[0].minor.yy43 ){
-    yymsp[0].minor.yy43->op = yymsp[-1].minor.yy316;
-    yymsp[0].minor.yy43->pPrior = yymsp[-2].minor.yy43;
+  if( yymsp[0].minor.yy219 ){
+    yymsp[0].minor.yy219->op = yymsp[-1].minor.yy46;
+    yymsp[0].minor.yy219->pPrior = yymsp[-2].minor.yy219;
   }
-  yygotominor.yy43 = yymsp[0].minor.yy43;
+  yygotominor.yy219 = yymsp[0].minor.yy219;
 }
-#line 2280 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2338 "parse.c"
         break;
       case 108:
-#line 390 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = TK_ALL;}
-#line 2285 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 389 "parse.y"
+{yygotominor.yy46 = TK_ALL;}
+#line 2343 "parse.c"
         break;
       case 110:
-#line 394 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 393 "parse.y"
 {
-  yygotominor.yy43 = sqlite3SelectNew(yymsp[-6].minor.yy242,yymsp[-5].minor.yy419,yymsp[-4].minor.yy450,yymsp[-3].minor.yy242,yymsp[-2].minor.yy450,yymsp[-1].minor.yy242,yymsp[-7].minor.yy316,yymsp[0].minor.yy84.pLimit,yymsp[0].minor.yy84.pOffset);
+  yygotominor.yy219 = sqlite3SelectNew(yymsp[-6].minor.yy174,yymsp[-5].minor.yy373,yymsp[-4].minor.yy172,yymsp[-3].minor.yy174,yymsp[-2].minor.yy172,yymsp[-1].minor.yy174,yymsp[-7].minor.yy46,yymsp[0].minor.yy234.pLimit,yymsp[0].minor.yy234.pOffset);
 }
-#line 2292 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2350 "parse.c"
         break;
       case 114:
       case 237:
-#line 415 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy242 = yymsp[-1].minor.yy242;}
-#line 2298 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 414 "parse.y"
+{yygotominor.yy174 = yymsp[-1].minor.yy174;}
+#line 2356 "parse.c"
         break;
       case 115:
       case 141:
       case 149:
       case 236:
-#line 416 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy242 = 0;}
-#line 2306 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 415 "parse.y"
+{yygotominor.yy174 = 0;}
+#line 2364 "parse.c"
         break;
       case 116:
-#line 417 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 416 "parse.y"
 {
-   yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-2].minor.yy242,yymsp[-1].minor.yy450,yymsp[0].minor.yy178.n?&yymsp[0].minor.yy178:0);
+   yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy410.n?&yymsp[0].minor.yy410:0);
 }
-#line 2313 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2371 "parse.c"
         break;
       case 117:
-#line 420 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 419 "parse.y"
 {
-  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-1].minor.yy242, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-1].minor.yy174, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
 }
-#line 2320 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2378 "parse.c"
         break;
       case 118:
-#line 423 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 422 "parse.y"
 {
   Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0);
-  Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy178);
-  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-3].minor.yy242, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
+  Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy410);
+  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-3].minor.yy174, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
 }
-#line 2329 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2387 "parse.c"
         break;
       case 121:
-#line 435 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178.n = 0;}
-#line 2334 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 434 "parse.y"
+{yygotominor.yy410.n = 0;}
+#line 2392 "parse.c"
         break;
       case 122:
-#line 447 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy419 = sqliteMalloc(sizeof(*yygotominor.yy419));}
-#line 2339 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 446 "parse.y"
+{yygotominor.yy373 = sqliteMalloc(sizeof(*yygotominor.yy373));}
+#line 2397 "parse.c"
         break;
       case 123:
-#line 448 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 447 "parse.y"
 {
-  yygotominor.yy419 = yymsp[0].minor.yy419;
-  sqlite3SrcListShiftJoinType(yygotominor.yy419);
+  yygotominor.yy373 = yymsp[0].minor.yy373;
+  sqlite3SrcListShiftJoinType(yygotominor.yy373);
 }
-#line 2347 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2405 "parse.c"
         break;
       case 124:
-#line 456 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 455 "parse.y"
 {
-   yygotominor.yy419 = yymsp[-1].minor.yy419;
-   if( yygotominor.yy419 && yygotominor.yy419->nSrc>0 ) yygotominor.yy419->a[yygotominor.yy419->nSrc-1].jointype = yymsp[0].minor.yy316;
+   yygotominor.yy373 = yymsp[-1].minor.yy373;
+   if( yygotominor.yy373 && yygotominor.yy373->nSrc>0 ) yygotominor.yy373->a[yygotominor.yy373->nSrc-1].jointype = yymsp[0].minor.yy46;
 }
-#line 2355 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2413 "parse.c"
         break;
       case 125:
-#line 460 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy419 = 0;}
-#line 2360 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 459 "parse.y"
+{yygotominor.yy373 = 0;}
+#line 2418 "parse.c"
         break;
       case 126:
-#line 461 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 460 "parse.y"
 {
-  yygotominor.yy419 = sqlite3SrcListAppendFromTerm(yymsp[-5].minor.yy419,&yymsp[-4].minor.yy178,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,0,yymsp[-1].minor.yy450,yymsp[0].minor.yy352);
+  yygotominor.yy373 = sqlite3SrcListAppendFromTerm(yymsp[-5].minor.yy373,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,0,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
 }
-#line 2367 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2425 "parse.c"
         break;
       case 127:
-#line 466 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 465 "parse.y"
 {
-    yygotominor.yy419 = sqlite3SrcListAppendFromTerm(yymsp[-6].minor.yy419,0,0,&yymsp[-2].minor.yy178,yymsp[-4].minor.yy43,yymsp[-1].minor.yy450,yymsp[0].minor.yy352);
+    yygotominor.yy373 = sqlite3SrcListAppendFromTerm(yymsp[-6].minor.yy373,0,0,&yymsp[-2].minor.yy410,yymsp[-4].minor.yy219,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
   }
-#line 2374 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2432 "parse.c"
         break;
       case 129:
-#line 477 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 476 "parse.y"
 {
-     sqlite3SrcListShiftJoinType(yymsp[0].minor.yy419);
-     yygotominor.yy43 = sqlite3SelectNew(0,yymsp[0].minor.yy419,0,0,0,0,0,0,0);
+     sqlite3SrcListShiftJoinType(yymsp[0].minor.yy373);
+     yygotominor.yy219 = sqlite3SelectNew(0,yymsp[0].minor.yy373,0,0,0,0,0,0,0);
   }
-#line 2382 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2440 "parse.c"
         break;
       case 130:
-#line 484 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178.z=0; yygotominor.yy178.n=0;}
-#line 2387 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 483 "parse.y"
+{yygotominor.yy410.z=0; yygotominor.yy410.n=0;}
+#line 2445 "parse.c"
         break;
       case 132:
-#line 489 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy419 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178);}
-#line 2392 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 488 "parse.y"
+{yygotominor.yy373 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);}
+#line 2450 "parse.c"
         break;
       case 133:
-#line 493 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = JT_INNER; }
-#line 2397 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 492 "parse.y"
+{ yygotominor.yy46 = JT_INNER; }
+#line 2455 "parse.c"
         break;
       case 134:
-#line 494 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
-#line 2402 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 493 "parse.y"
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+#line 2460 "parse.c"
         break;
       case 135:
-#line 495 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy178,0); }
-#line 2407 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 494 "parse.y"
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy410,0); }
+#line 2465 "parse.c"
         break;
       case 136:
-#line 497 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy178,&yymsp[-1].minor.yy178); }
-#line 2412 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 496 "parse.y"
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy410,&yymsp[-1].minor.yy410); }
+#line 2470 "parse.c"
         break;
       case 137:
       case 145:
@@ -2417,9 +2475,9 @@ static void yy_reduce(
       case 225:
       case 227:
       case 231:
-#line 501 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy450 = yymsp[0].minor.yy450;}
-#line 2425 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 500 "parse.y"
+{yygotominor.yy172 = yymsp[0].minor.yy172;}
+#line 2483 "parse.c"
         break;
       case 138:
       case 151:
@@ -2428,230 +2486,230 @@ static void yy_reduce(
       case 226:
       case 228:
       case 232:
-#line 502 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy450 = 0;}
-#line 2436 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 501 "parse.y"
+{yygotominor.yy172 = 0;}
+#line 2494 "parse.c"
         break;
       case 139:
       case 171:
-#line 506 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy352 = yymsp[-1].minor.yy352;}
-#line 2442 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 505 "parse.y"
+{yygotominor.yy432 = yymsp[-1].minor.yy432;}
+#line 2500 "parse.c"
         break;
       case 140:
       case 170:
-#line 507 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy352 = 0;}
-#line 2448 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 506 "parse.y"
+{yygotominor.yy432 = 0;}
+#line 2506 "parse.c"
         break;
       case 142:
       case 150:
-#line 518 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy242 = yymsp[0].minor.yy242;}
-#line 2454 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 517 "parse.y"
+{yygotominor.yy174 = yymsp[0].minor.yy174;}
+#line 2512 "parse.c"
         break;
       case 143:
-#line 519 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 518 "parse.y"
 {
-  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-3].minor.yy242,yymsp[-1].minor.yy450,0);
-  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
+  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-3].minor.yy174,yymsp[-1].minor.yy172,0);
+  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
 }
-#line 2462 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2520 "parse.c"
         break;
       case 144:
-#line 523 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 522 "parse.y"
 {
-  yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[-1].minor.yy450,0);
-  if( yygotominor.yy242 && yygotominor.yy242->a ) yygotominor.yy242->a[0].sortOrder = yymsp[0].minor.yy316;
+  yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[-1].minor.yy172,0);
+  if( yygotominor.yy174 && yygotominor.yy174->a ) yygotominor.yy174->a[0].sortOrder = yymsp[0].minor.yy46;
 }
-#line 2470 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2528 "parse.c"
         break;
       case 146:
       case 148:
-#line 531 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = SQLITE_SO_ASC;}
-#line 2476 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 530 "parse.y"
+{yygotominor.yy46 = SQLITE_SO_ASC;}
+#line 2534 "parse.c"
         break;
       case 147:
-#line 532 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = SQLITE_SO_DESC;}
-#line 2481 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 531 "parse.y"
+{yygotominor.yy46 = SQLITE_SO_DESC;}
+#line 2539 "parse.c"
         break;
       case 153:
-#line 550 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy84.pLimit = 0; yygotominor.yy84.pOffset = 0;}
-#line 2486 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 557 "parse.y"
+{yygotominor.yy234.pLimit = 0; yygotominor.yy234.pOffset = 0;}
+#line 2544 "parse.c"
         break;
       case 154:
-#line 551 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy84.pLimit = yymsp[0].minor.yy450; yygotominor.yy84.pOffset = 0;}
-#line 2491 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 558 "parse.y"
+{yygotominor.yy234.pLimit = yymsp[0].minor.yy172; yygotominor.yy234.pOffset = 0;}
+#line 2549 "parse.c"
         break;
       case 155:
-#line 553 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy84.pLimit = yymsp[-2].minor.yy450; yygotominor.yy84.pOffset = yymsp[0].minor.yy450;}
-#line 2496 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 560 "parse.y"
+{yygotominor.yy234.pLimit = yymsp[-2].minor.yy172; yygotominor.yy234.pOffset = yymsp[0].minor.yy172;}
+#line 2554 "parse.c"
         break;
       case 156:
-#line 555 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy84.pOffset = yymsp[-2].minor.yy450; yygotominor.yy84.pLimit = yymsp[0].minor.yy450;}
-#line 2501 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 562 "parse.y"
+{yygotominor.yy234.pOffset = yymsp[-2].minor.yy172; yygotominor.yy234.pLimit = yymsp[0].minor.yy172;}
+#line 2559 "parse.c"
         break;
       case 157:
-#line 559 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy419,yymsp[0].minor.yy450);}
-#line 2506 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 566 "parse.y"
+{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy373,yymsp[0].minor.yy172);}
+#line 2564 "parse.c"
         break;
       case 160:
-#line 570 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Update(pParse,yymsp[-3].minor.yy419,yymsp[-1].minor.yy242,yymsp[0].minor.yy450,yymsp[-4].minor.yy316);}
-#line 2511 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 577 "parse.y"
+{sqlite3Update(pParse,yymsp[-3].minor.yy373,yymsp[-1].minor.yy174,yymsp[0].minor.yy172,yymsp[-4].minor.yy46);}
+#line 2569 "parse.c"
         break;
       case 161:
-#line 576 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242,yymsp[0].minor.yy450,&yymsp[-2].minor.yy178);}
-#line 2516 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 583 "parse.y"
+{yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
+#line 2574 "parse.c"
         break;
       case 162:
-#line 577 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[0].minor.yy450,&yymsp[-2].minor.yy178);}
-#line 2521 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 584 "parse.y"
+{yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
+#line 2579 "parse.c"
         break;
       case 163:
-#line 583 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Insert(pParse, yymsp[-5].minor.yy419, yymsp[-1].minor.yy242, 0, yymsp[-4].minor.yy352, yymsp[-7].minor.yy316);}
-#line 2526 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 590 "parse.y"
+{sqlite3Insert(pParse, yymsp[-5].minor.yy373, yymsp[-1].minor.yy174, 0, yymsp[-4].minor.yy432, yymsp[-7].minor.yy46);}
+#line 2584 "parse.c"
         break;
       case 164:
-#line 585 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Insert(pParse, yymsp[-2].minor.yy419, 0, yymsp[0].minor.yy43, yymsp[-1].minor.yy352, yymsp[-4].minor.yy316);}
-#line 2531 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 592 "parse.y"
+{sqlite3Insert(pParse, yymsp[-2].minor.yy373, 0, yymsp[0].minor.yy219, yymsp[-1].minor.yy432, yymsp[-4].minor.yy46);}
+#line 2589 "parse.c"
         break;
       case 165:
-#line 587 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Insert(pParse, yymsp[-3].minor.yy419, 0, 0, yymsp[-2].minor.yy352, yymsp[-5].minor.yy316);}
-#line 2536 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 594 "parse.y"
+{sqlite3Insert(pParse, yymsp[-3].minor.yy373, 0, 0, yymsp[-2].minor.yy432, yymsp[-5].minor.yy46);}
+#line 2594 "parse.c"
         break;
       case 168:
       case 229:
-#line 597 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-2].minor.yy242,yymsp[0].minor.yy450,0);}
-#line 2542 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 604 "parse.y"
+{yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-2].minor.yy174,yymsp[0].minor.yy172,0);}
+#line 2600 "parse.c"
         break;
       case 169:
       case 230:
-#line 598 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[0].minor.yy450,0);}
-#line 2548 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 605 "parse.y"
+{yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[0].minor.yy172,0);}
+#line 2606 "parse.c"
         break;
       case 172:
-#line 607 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy352 = sqlite3IdListAppend(yymsp[-2].minor.yy352,&yymsp[0].minor.yy178);}
-#line 2553 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 614 "parse.y"
+{yygotominor.yy432 = sqlite3IdListAppend(yymsp[-2].minor.yy432,&yymsp[0].minor.yy410);}
+#line 2611 "parse.c"
         break;
       case 173:
-#line 608 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy352 = sqlite3IdListAppend(0,&yymsp[0].minor.yy178);}
-#line 2558 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 615 "parse.y"
+{yygotominor.yy432 = sqlite3IdListAppend(0,&yymsp[0].minor.yy410);}
+#line 2616 "parse.c"
         break;
       case 175:
-#line 619 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy450 = yymsp[-1].minor.yy450; sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
-#line 2563 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 626 "parse.y"
+{yygotominor.yy172 = yymsp[-1].minor.yy172; sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+#line 2621 "parse.c"
         break;
       case 176:
       case 181:
       case 182:
-#line 620 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy450 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
-#line 2570 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 627 "parse.y"
+{yygotominor.yy172 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+#line 2628 "parse.c"
         break;
       case 177:
       case 178:
-#line 621 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy450 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
-#line 2576 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 628 "parse.y"
+{yygotominor.yy172 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+#line 2634 "parse.c"
         break;
       case 179:
-#line 623 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 630 "parse.y"
 {
-  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy178);
-  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy178);
-  yygotominor.yy450 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
+  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy410);
+  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy410);
+  yygotominor.yy172 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
 }
-#line 2585 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2643 "parse.c"
         break;
       case 180:
-#line 628 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 635 "parse.y"
 {
-  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy178);
-  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy178);
-  Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy178);
+  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy410);
+  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy410);
+  Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy410);
   Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
-  yygotominor.yy450 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
+  yygotominor.yy172 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
 }
-#line 2596 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2654 "parse.c"
         break;
       case 183:
-#line 637 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy450 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
-#line 2601 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 644 "parse.y"
+{yygotominor.yy172 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+#line 2659 "parse.c"
         break;
       case 184:
-#line 638 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 645 "parse.y"
 {
   Token *pToken = &yymsp[0].minor.yy0;
-  Expr *pExpr = yygotominor.yy450 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
+  Expr *pExpr = yygotominor.yy172 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
   sqlite3ExprAssignVarNumber(pParse, pExpr);
 }
-#line 2610 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2668 "parse.c"
         break;
       case 185:
-#line 643 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 650 "parse.y"
 {
-  yygotominor.yy450 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy450, &yymsp[0].minor.yy178);
+  yygotominor.yy172 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy172, &yymsp[0].minor.yy410);
 }
-#line 2617 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2675 "parse.c"
         break;
       case 186:
-#line 647 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 654 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy450, 0, &yymsp[-1].minor.yy178);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy172, 0, &yymsp[-1].minor.yy410);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
 }
-#line 2625 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2683 "parse.c"
         break;
       case 187:
-#line 652 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 659 "parse.y"
 {
-  yygotominor.yy450 = sqlite3ExprFunction(yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
-  if( yymsp[-2].minor.yy316 && yygotominor.yy450 ){
-    yygotominor.yy450->flags |= EP_Distinct;
+  yygotominor.yy172 = sqlite3ExprFunction(yymsp[-1].minor.yy174, &yymsp[-4].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+  if( yymsp[-2].minor.yy46 && yygotominor.yy172 ){
+    yygotominor.yy172->flags |= EP_Distinct;
   }
 }
-#line 2636 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2694 "parse.c"
         break;
       case 188:
-#line 659 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 666 "parse.y"
 {
-  yygotominor.yy450 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
 }
-#line 2644 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2702 "parse.c"
         break;
       case 189:
-#line 663 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 670 "parse.y"
 {
   /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
   ** treated as functions that return constants */
-  yygotominor.yy450 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->op = TK_CONST_FUNC;  
-    yygotominor.yy450->span = yymsp[0].minor.yy0;
+  yygotominor.yy172 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->op = TK_CONST_FUNC;  
+    yygotominor.yy172->span = yymsp[0].minor.yy0;
   }
 }
-#line 2657 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2715 "parse.c"
         break;
       case 190:
       case 191:
@@ -2661,538 +2719,527 @@ static void yy_reduce(
       case 195:
       case 196:
       case 197:
-#line 672 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy450 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy450, yymsp[0].minor.yy450, 0);}
-#line 2669 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 679 "parse.y"
+{yygotominor.yy172 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy172, yymsp[0].minor.yy172, 0);}
+#line 2727 "parse.c"
         break;
       case 198:
       case 200:
-#line 682 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 0;}
-#line 2675 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 689 "parse.y"
+{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 0;}
+#line 2733 "parse.c"
         break;
       case 199:
       case 201:
-#line 683 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 1;}
-#line 2681 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 690 "parse.y"
+{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 1;}
+#line 2739 "parse.c"
         break;
       case 204:
-#line 690 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 697 "parse.y"
 {
   ExprList *pList;
-  pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy450, 0);
-  pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy450, 0);
-  if( yymsp[0].minor.yy450 ){
-    pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy450, 0);
+  pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy172, 0);
+  pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy172, 0);
+  if( yymsp[0].minor.yy172 ){
+    pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy172, 0);
   }
-  yygotominor.yy450 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy86.eOperator);
-  if( yymsp[-2].minor.yy86.not ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450, &yymsp[-3].minor.yy450->span, &yymsp[-1].minor.yy450->span);
-  if( yygotominor.yy450 ) yygotominor.yy450->flags |= EP_InfixFunc;
+  yygotominor.yy172 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy72.eOperator);
+  if( yymsp[-2].minor.yy72.not ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy172->span, &yymsp[-1].minor.yy172->span);
+  if( yygotominor.yy172 ) yygotominor.yy172->flags |= EP_InfixFunc;
 }
-#line 2697 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2755 "parse.c"
         break;
       case 205:
-#line 703 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 710 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy450->span,&yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy172->span,&yymsp[0].minor.yy0);
 }
-#line 2705 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2763 "parse.c"
         break;
       case 206:
-#line 707 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 714 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
 }
-#line 2713 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2771 "parse.c"
         break;
       case 207:
-#line 711 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 718 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
 }
-#line 2721 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2779 "parse.c"
         break;
       case 208:
-#line 715 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 722 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy450->span,&yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,&yymsp[0].minor.yy0);
 }
-#line 2729 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2787 "parse.c"
         break;
       case 209:
-#line 719 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 726 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
+  yygotominor.yy172 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
 }
-#line 2737 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2795 "parse.c"
         break;
       case 210:
-#line 723 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 730 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
+  yygotominor.yy172 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
 }
-#line 2745 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2803 "parse.c"
         break;
       case 211:
-#line 727 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 734 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
+  yygotominor.yy172 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
 }
-#line 2753 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2811 "parse.c"
         break;
       case 214:
-#line 734 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 741 "parse.y"
 {
-  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy450, 0);
-  pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy450, 0);
-  yygotominor.yy450 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy450, 0, 0);
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->pList = pList;
+  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy172, 0);
+  pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy172, 0);
+  yygotominor.yy172 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy172, 0, 0);
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->pList = pList;
   }else{
     sqlite3ExprListDelete(pList);
   } 
-  if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy450->span);
+  if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy172->span);
 }
-#line 2769 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2827 "parse.c"
         break;
       case 217:
-#line 750 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 757 "parse.y"
 {
-    yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy450, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pList = yymsp[-1].minor.yy242;
+    yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy172, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pList = yymsp[-1].minor.yy174;
     }else{
-      sqlite3ExprListDelete(yymsp[-1].minor.yy242);
+      sqlite3ExprListDelete(yymsp[-1].minor.yy174);
     }
-    if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy0);
+    if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
   }
-#line 2783 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2841 "parse.c"
         break;
       case 218:
-#line 760 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 767 "parse.y"
 {
-    yygotominor.yy450 = sqlite3Expr(TK_SELECT, 0, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pSelect = yymsp[-1].minor.yy43;
+    yygotominor.yy172 = sqlite3Expr(TK_SELECT, 0, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy43);
+      sqlite3SelectDelete(yymsp[-1].minor.yy219);
     }
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
   }
-#line 2796 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2854 "parse.c"
         break;
       case 219:
-#line 769 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 776 "parse.y"
 {
-    yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy450, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pSelect = yymsp[-1].minor.yy43;
+    yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy172, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy43);
+      sqlite3SelectDelete(yymsp[-1].minor.yy219);
     }
-    if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy0);
+    if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
   }
-#line 2810 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2868 "parse.c"
         break;
       case 220:
-#line 779 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 786 "parse.y"
 {
-    SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178);
-    yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy450, 0, 0);
-    if( yygotominor.yy450 ){
-      yygotominor.yy450->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0);
+    SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);
+    yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy172, 0, 0);
+    if( yygotominor.yy172 ){
+      yygotominor.yy172->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0);
     }else{
       sqlite3SrcListDelete(pSrc);
     }
-    if( yymsp[-2].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy450->span,yymsp[0].minor.yy178.z?&yymsp[0].minor.yy178:&yymsp[-1].minor.yy178);
+    if( yymsp[-2].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy410.z?&yymsp[0].minor.yy410:&yymsp[-1].minor.yy410);
   }
-#line 2825 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2883 "parse.c"
         break;
       case 221:
-#line 790 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 797 "parse.y"
 {
-    Expr *p = yygotominor.yy450 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
+    Expr *p = yygotominor.yy172 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
     if( p ){
-      p->pSelect = yymsp[-1].minor.yy43;
+      p->pSelect = yymsp[-1].minor.yy219;
       sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy43);
+      sqlite3SelectDelete(yymsp[-1].minor.yy219);
     }
   }
-#line 2838 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2896 "parse.c"
         break;
       case 222:
-#line 802 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 809 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, 0);
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->pList = yymsp[-2].minor.yy242;
+  yygotominor.yy172 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, 0);
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->pList = yymsp[-2].minor.yy174;
   }else{
-    sqlite3ExprListDelete(yymsp[-2].minor.yy242);
+    sqlite3ExprListDelete(yymsp[-2].minor.yy174);
   }
-  sqlite3ExprSpan(yygotominor.yy450, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy172, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
 }
-#line 2851 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2909 "parse.c"
         break;
       case 223:
-#line 813 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 820 "parse.y"
 {
-  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242, yymsp[-2].minor.yy450, 0);
-  yygotominor.yy242 = sqlite3ExprListAppend(yygotominor.yy242, yymsp[0].minor.yy450, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174, yymsp[-2].minor.yy172, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(yygotominor.yy174, yymsp[0].minor.yy172, 0);
 }
-#line 2859 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2917 "parse.c"
         break;
       case 224:
-#line 817 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 824 "parse.y"
 {
-  yygotominor.yy242 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy450, 0);
-  yygotominor.yy242 = sqlite3ExprListAppend(yygotominor.yy242, yymsp[0].minor.yy450, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy172, 0);
+  yygotominor.yy174 = sqlite3ExprListAppend(yygotominor.yy174, yymsp[0].minor.yy172, 0);
 }
-#line 2867 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2925 "parse.c"
         break;
       case 233:
-#line 844 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 851 "parse.y"
 {
-  sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy178, &yymsp[-5].minor.yy178, sqlite3SrcListAppend(0,&yymsp[-3].minor.yy178,0), yymsp[-1].minor.yy242, yymsp[-9].minor.yy316,
-                      &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy316);
+  sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy410, &yymsp[-5].minor.yy410, sqlite3SrcListAppend(0,&yymsp[-3].minor.yy410,0), yymsp[-1].minor.yy174, yymsp[-9].minor.yy46,
+                      &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy46);
 }
-#line 2875 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2933 "parse.c"
         break;
       case 234:
-      case 282:
-#line 850 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = OE_Abort;}
-#line 2881 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 281:
+#line 857 "parse.y"
+{yygotominor.yy46 = OE_Abort;}
+#line 2939 "parse.c"
         break;
       case 235:
-#line 851 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = OE_None;}
-#line 2886 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 858 "parse.y"
+{yygotominor.yy46 = OE_None;}
+#line 2944 "parse.c"
         break;
       case 238:
-#line 861 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 868 "parse.y"
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy178.n>0 ){
+  if( yymsp[-1].minor.yy410.n>0 ){
     p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
-    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy178.z, yymsp[-1].minor.yy178.n);
+    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n);
   }
-  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242, p, &yymsp[-2].minor.yy178);
-  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
+  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy410);
+  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
 }
-#line 2899 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2957 "parse.c"
         break;
       case 239:
-#line 870 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 877 "parse.y"
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy178.n>0 ){
+  if( yymsp[-1].minor.yy410.n>0 ){
     p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
-    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy178.z, yymsp[-1].minor.yy178.n);
+    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n);
   }
-  yygotominor.yy242 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy178);
-  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
+  yygotominor.yy174 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy410);
+  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
 }
-#line 2912 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2970 "parse.c"
         break;
       case 241:
-#line 882 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy178.z = 0; yygotominor.yy178.n = 0;}
-#line 2917 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 889 "parse.y"
+{yygotominor.yy410.z = 0; yygotominor.yy410.n = 0;}
+#line 2975 "parse.c"
         break;
       case 243:
-#line 888 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy419, yymsp[-1].minor.yy316);}
-#line 2922 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 895 "parse.y"
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy373, yymsp[-1].minor.yy46);}
+#line 2980 "parse.c"
         break;
       case 244:
       case 245:
-#line 893 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 901 "parse.y"
 {sqlite3Vacuum(pParse);}
-#line 2928 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2986 "parse.c"
         break;
       case 246:
-#line 900 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy178,0);}
-#line 2933 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 909 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,0);}
+#line 2991 "parse.c"
         break;
       case 247:
-#line 901 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy0,0);}
-#line 2938 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 910 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy0,0);}
+#line 2996 "parse.c"
         break;
       case 248:
-#line 902 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 911 "parse.y"
 {
-  sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy178,1);
+  sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,1);
 }
-#line 2945 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3003 "parse.c"
         break;
       case 249:
-#line 905 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy178,&yymsp[-3].minor.yy178,&yymsp[-1].minor.yy178,0);}
-#line 2950 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 914 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-1].minor.yy410,0);}
+#line 3008 "parse.c"
         break;
       case 250:
-#line 906 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178,0,0);}
-#line 2955 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 915 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,0,0);}
+#line 3013 "parse.c"
         break;
       case 258:
-#line 920 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 929 "parse.y"
 {
   Token all;
-  all.z = yymsp[-3].minor.yy178.z;
-  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy178.z) + yymsp[0].minor.yy0.n;
-  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy75, &all);
+  all.z = yymsp[-3].minor.yy410.z;
+  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy410.z) + yymsp[0].minor.yy0.n;
+  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy243, &all);
 }
-#line 2965 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3023 "parse.c"
         break;
       case 259:
-#line 929 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 938 "parse.y"
 {
-  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy178, &yymsp[-6].minor.yy178, yymsp[-5].minor.yy316, yymsp[-4].minor.yy354.a, yymsp[-4].minor.yy354.b, yymsp[-2].minor.yy419, yymsp[-1].minor.yy316, yymsp[0].minor.yy450, yymsp[-10].minor.yy316, yymsp[-8].minor.yy316);
-  yygotominor.yy178 = (yymsp[-6].minor.yy178.n==0?yymsp[-7].minor.yy178:yymsp[-6].minor.yy178);
+  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy410, &yymsp[-6].minor.yy410, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[0].minor.yy172, yymsp[-10].minor.yy46, yymsp[-8].minor.yy46);
+  yygotominor.yy410 = (yymsp[-6].minor.yy410.n==0?yymsp[-7].minor.yy410:yymsp[-6].minor.yy410);
 }
-#line 2973 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3031 "parse.c"
         break;
       case 260:
       case 263:
-#line 935 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = TK_BEFORE; }
-#line 2979 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 944 "parse.y"
+{ yygotominor.yy46 = TK_BEFORE; }
+#line 3037 "parse.c"
         break;
       case 261:
-#line 936 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = TK_AFTER;  }
-#line 2984 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 945 "parse.y"
+{ yygotominor.yy46 = TK_AFTER;  }
+#line 3042 "parse.c"
         break;
       case 262:
-#line 937 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = TK_INSTEAD;}
-#line 2989 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 946 "parse.y"
+{ yygotominor.yy46 = TK_INSTEAD;}
+#line 3047 "parse.c"
         break;
       case 264:
       case 265:
-#line 942 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy354.a = yymsp[0].major; yygotominor.yy354.b = 0;}
-#line 2995 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 951 "parse.y"
+{yygotominor.yy370.a = yymsp[0].major; yygotominor.yy370.b = 0;}
+#line 3053 "parse.c"
         break;
       case 266:
-#line 944 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy354.a = TK_UPDATE; yygotominor.yy354.b = yymsp[0].minor.yy352;}
-#line 3000 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 267:
-      case 268:
-#line 947 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = TK_ROW; }
-#line 3006 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 953 "parse.y"
+{yygotominor.yy370.a = TK_UPDATE; yygotominor.yy370.b = yymsp[0].minor.yy432;}
+#line 3058 "parse.c"
         break;
       case 269:
-#line 949 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy316 = TK_STATEMENT; }
-#line 3011 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 960 "parse.y"
+{ yygotominor.yy172 = 0; }
+#line 3063 "parse.c"
         break;
       case 270:
-#line 953 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy450 = 0; }
-#line 3016 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 961 "parse.y"
+{ yygotominor.yy172 = yymsp[0].minor.yy172; }
+#line 3068 "parse.c"
         break;
       case 271:
-#line 954 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy450 = yymsp[0].minor.yy450; }
-#line 3021 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 272:
-#line 958 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 965 "parse.y"
 {
-  if( yymsp[-2].minor.yy75 ){
-    yymsp[-2].minor.yy75->pLast->pNext = yymsp[-1].minor.yy75;
+  if( yymsp[-2].minor.yy243 ){
+    yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243;
   }else{
-    yymsp[-2].minor.yy75 = yymsp[-1].minor.yy75;
+    yymsp[-2].minor.yy243 = yymsp[-1].minor.yy243;
   }
-  yymsp[-2].minor.yy75->pLast = yymsp[-1].minor.yy75;
-  yygotominor.yy75 = yymsp[-2].minor.yy75;
+  yymsp[-2].minor.yy243->pLast = yymsp[-1].minor.yy243;
+  yygotominor.yy243 = yymsp[-2].minor.yy243;
 }
-#line 3034 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3081 "parse.c"
+        break;
+      case 272:
+#line 974 "parse.y"
+{ yygotominor.yy243 = 0; }
+#line 3086 "parse.c"
         break;
       case 273:
-#line 967 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy75 = 0; }
-#line 3039 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 980 "parse.y"
+{ yygotominor.yy243 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy410, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); }
+#line 3091 "parse.c"
         break;
       case 274:
-#line 973 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy75 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy178, yymsp[-1].minor.yy242, yymsp[0].minor.yy450, yymsp[-4].minor.yy316); }
-#line 3044 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 985 "parse.y"
+{yygotominor.yy243 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy410, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);}
+#line 3096 "parse.c"
         break;
       case 275:
-#line 978 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy75 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy178, yymsp[-4].minor.yy352, yymsp[-1].minor.yy242, 0, yymsp[-7].minor.yy316);}
-#line 3049 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 988 "parse.y"
+{yygotominor.yy243 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy410, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);}
+#line 3101 "parse.c"
         break;
       case 276:
-#line 981 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy75 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy178, yymsp[-1].minor.yy352, 0, yymsp[0].minor.yy43, yymsp[-4].minor.yy316);}
-#line 3054 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 992 "parse.y"
+{yygotominor.yy243 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy410, yymsp[0].minor.yy172);}
+#line 3106 "parse.c"
         break;
       case 277:
-#line 985 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy75 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy178, yymsp[0].minor.yy450);}
-#line 3059 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 995 "parse.y"
+{yygotominor.yy243 = sqlite3TriggerSelectStep(yymsp[0].minor.yy219); }
+#line 3111 "parse.c"
         break;
       case 278:
-#line 988 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy75 = sqlite3TriggerSelectStep(yymsp[0].minor.yy43); }
-#line 3064 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 279:
-#line 991 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 998 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_RAISE, 0, 0, 0); 
-  if( yygotominor.yy450 ){
-    yygotominor.yy450->iColumn = OE_Ignore;
-    sqlite3ExprSpan(yygotominor.yy450, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3Expr(TK_RAISE, 0, 0, 0); 
+  if( yygotominor.yy172 ){
+    yygotominor.yy172->iColumn = OE_Ignore;
+    sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
   }
 }
-#line 3075 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3122 "parse.c"
         break;
-      case 280:
-#line 998 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 279:
+#line 1005 "parse.y"
 {
-  yygotominor.yy450 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy178); 
-  if( yygotominor.yy450 ) {
-    yygotominor.yy450->iColumn = yymsp[-3].minor.yy316;
-    sqlite3ExprSpan(yygotominor.yy450, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+  yygotominor.yy172 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy410); 
+  if( yygotominor.yy172 ) {
+    yygotominor.yy172->iColumn = yymsp[-3].minor.yy46;
+    sqlite3ExprSpan(yygotominor.yy172, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
   }
 }
-#line 3086 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3133 "parse.c"
         break;
-      case 281:
-#line 1008 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = OE_Rollback;}
-#line 3091 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 280:
+#line 1015 "parse.y"
+{yygotominor.yy46 = OE_Rollback;}
+#line 3138 "parse.c"
+        break;
+      case 282:
+#line 1017 "parse.y"
+{yygotominor.yy46 = OE_Fail;}
+#line 3143 "parse.c"
         break;
       case 283:
-#line 1010 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy316 = OE_Fail;}
-#line 3096 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1022 "parse.y"
+{
+  sqlite3DropTrigger(pParse,yymsp[0].minor.yy373,yymsp[-1].minor.yy46);
+}
+#line 3150 "parse.c"
         break;
       case 284:
-#line 1015 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 1029 "parse.y"
 {
-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy419,yymsp[-1].minor.yy316);
+  sqlite3Attach(pParse, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, yymsp[0].minor.yy386);
 }
-#line 3103 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3157 "parse.c"
         break;
       case 285:
-#line 1021 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 1032 "parse.y"
 {
-  sqlite3Attach(pParse, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, yymsp[0].minor.yy158);
+  sqlite3Detach(pParse, yymsp[0].minor.yy172);
 }
-#line 3110 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3164 "parse.c"
         break;
       case 286:
-#line 1026 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy158 = 0; }
-#line 3115 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1038 "parse.y"
+{ yygotominor.yy386 = 0; }
+#line 3169 "parse.c"
         break;
       case 287:
-#line 1027 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy158 = yymsp[0].minor.yy450; }
-#line 3120 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1039 "parse.y"
+{ yygotominor.yy386 = yymsp[0].minor.yy172; }
+#line 3174 "parse.c"
         break;
       case 290:
-#line 1033 "ext/pdo_sqlite/sqlite/src/parse.y"
-{
-  sqlite3Detach(pParse, yymsp[0].minor.yy450);
-}
-#line 3127 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1047 "parse.y"
+{sqlite3Reindex(pParse, 0, 0);}
+#line 3179 "parse.c"
         break;
       case 291:
-#line 1039 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Reindex(pParse, 0, 0);}
-#line 3132 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1048 "parse.y"
+{sqlite3Reindex(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
+#line 3184 "parse.c"
         break;
       case 292:
-#line 1040 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Reindex(pParse, &yymsp[-1].minor.yy178, &yymsp[0].minor.yy178);}
-#line 3137 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1053 "parse.y"
+{sqlite3Analyze(pParse, 0, 0);}
+#line 3189 "parse.c"
         break;
       case 293:
-#line 1045 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Analyze(pParse, 0, 0);}
-#line 3142 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1054 "parse.y"
+{sqlite3Analyze(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
+#line 3194 "parse.c"
         break;
       case 294:
-#line 1046 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Analyze(pParse, &yymsp[-1].minor.yy178, &yymsp[0].minor.yy178);}
-#line 3147 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 295:
-#line 1051 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 1059 "parse.y"
 {
-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy419,&yymsp[0].minor.yy178);
+  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy410);
 }
-#line 3154 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3201 "parse.c"
         break;
-      case 296:
-#line 1054 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 295:
+#line 1062 "parse.y"
 {
-  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy178);
+  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy410);
 }
-#line 3161 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3208 "parse.c"
         break;
-      case 297:
-#line 1057 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 296:
+#line 1065 "parse.y"
 {
-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy419);
+  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy373);
 }
-#line 3168 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3215 "parse.c"
         break;
-      case 300:
-#line 1066 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 299:
+#line 1074 "parse.y"
 {sqlite3VtabFinishParse(pParse,0);}
-#line 3173 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3220 "parse.c"
         break;
-      case 301:
-#line 1067 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 300:
+#line 1075 "parse.y"
 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
-#line 3178 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3225 "parse.c"
         break;
-      case 302:
-#line 1068 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 301:
+#line 1076 "parse.y"
 {
-    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy178, &yymsp[-2].minor.yy178, &yymsp[0].minor.yy178);
+    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, &yymsp[0].minor.yy410);
 }
-#line 3185 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3232 "parse.c"
         break;
-      case 305:
-#line 1073 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 304:
+#line 1081 "parse.y"
 {sqlite3VtabArgInit(pParse);}
-#line 3190 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3237 "parse.c"
         break;
+      case 306:
       case 307:
       case 308:
-      case 309:
-      case 311:
-#line 1075 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 310:
+#line 1083 "parse.y"
 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
-#line 3198 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3245 "parse.c"
         break;
   };
   yygoto = yyRuleInfo[yyruleno].lhs;
@@ -3249,7 +3296,7 @@ static void yy_syntax_error(
 ){
   sqlite3ParserARG_FETCH;
 #define TOKEN (yyminor.yy0)
-#line 34 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 34 "parse.y"
 
   if( !pParse->parseError ){
     if( TOKEN.z[0] ){
@@ -3259,7 +3306,7 @@ static void yy_syntax_error(
     }
     pParse->parseError = 1;
   }
-#line 3266 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3313 "parse.c"
   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
 }
 
@@ -3315,7 +3362,13 @@ void sqlite3Parser(
   /* (re)initialize the parser, if necessary */
   yypParser = (yyParser*)yyp;
   if( yypParser->yyidx<0 ){
-    /* if( yymajor==0 ) return; // not sure why this was here... */
+#if YYSTACKDEPTH<=0
+    if( yypParser->yystksz <=0 ){
+      memset(&yyminorunion, 0, sizeof(yyminorunion));
+      yyStackOverflow(yypParser, &yyminorunion);
+      return;
+    }
+#endif
     yypParser->yyidx = 0;
     yypParser->yyerrcnt = -1;
     yypParser->yystack[0].stateno = 0;
index 3a71be199d2d0024208c9d41e1a29f364b71ab53..ed848ec5c4ab1047f021bf9258766fe490f434c8 100644 (file)
 #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_VIRTUAL                        56
-#define TK_REINDEX                        57
-#define TK_RENAME                         58
-#define TK_CTIME_KW                       59
-#define TK_ANY                            60
-#define TK_OR                             61
-#define TK_AND                            62
-#define TK_IS                             63
-#define TK_BETWEEN                        64
-#define TK_IN                             65
-#define TK_ISNULL                         66
-#define TK_NOTNULL                        67
-#define TK_NE                             68
-#define TK_EQ                             69
-#define TK_GT                             70
-#define TK_LE                             71
-#define TK_LT                             72
-#define TK_GE                             73
-#define TK_ESCAPE                         74
-#define TK_BITAND                         75
-#define TK_BITOR                          76
-#define TK_LSHIFT                         77
-#define TK_RSHIFT                         78
-#define TK_PLUS                           79
-#define TK_MINUS                          80
-#define TK_STAR                           81
-#define TK_SLASH                          82
-#define TK_REM                            83
-#define TK_CONCAT                         84
-#define TK_COLLATE                        85
-#define TK_UMINUS                         86
-#define TK_UPLUS                          87
-#define TK_BITNOT                         88
-#define TK_STRING                         89
-#define TK_JOIN_KW                        90
-#define TK_CONSTRAINT                     91
-#define TK_DEFAULT                        92
-#define TK_NULL                           93
-#define TK_PRIMARY                        94
-#define TK_UNIQUE                         95
-#define TK_CHECK                          96
-#define TK_REFERENCES                     97
-#define TK_AUTOINCR                       98
-#define TK_ON                             99
-#define TK_DELETE                         100
-#define TK_UPDATE                         101
-#define TK_INSERT                         102
-#define TK_SET                            103
-#define TK_DEFERRABLE                     104
-#define TK_FOREIGN                        105
-#define TK_DROP                           106
-#define TK_UNION                          107
-#define TK_ALL                            108
-#define TK_EXCEPT                         109
-#define TK_INTERSECT                      110
-#define TK_SELECT                         111
-#define TK_DISTINCT                       112
-#define TK_DOT                            113
-#define TK_FROM                           114
-#define TK_JOIN                           115
-#define TK_USING                          116
-#define TK_ORDER                          117
-#define TK_BY                             118
-#define TK_GROUP                          119
-#define TK_HAVING                         120
-#define TK_LIMIT                          121
-#define TK_WHERE                          122
-#define TK_INTO                           123
-#define TK_VALUES                         124
-#define TK_INTEGER                        125
-#define TK_FLOAT                          126
-#define TK_BLOB                           127
-#define TK_REGISTER                       128
-#define TK_VARIABLE                       129
-#define TK_CASE                           130
-#define TK_WHEN                           131
-#define TK_THEN                           132
-#define TK_ELSE                           133
-#define TK_INDEX                          134
-#define TK_ALTER                          135
-#define TK_TO                             136
-#define TK_ADD                            137
-#define TK_COLUMNKW                       138
-#define TK_TO_TEXT                        139
-#define TK_TO_BLOB                        140
-#define TK_TO_NUMERIC                     141
-#define TK_TO_INT                         142
-#define TK_TO_REAL                        143
-#define TK_END_OF_FILE                    144
-#define TK_ILLEGAL                        145
-#define TK_SPACE                          146
-#define TK_UNCLOSED_STRING                147
-#define TK_COMMENT                        148
-#define TK_FUNCTION                       149
-#define TK_COLUMN                         150
-#define TK_AGG_FUNCTION                   151
-#define TK_AGG_COLUMN                     152
-#define TK_CONST_FUNC                     153
+#define TK_TRIGGER                        52
+#define TK_VACUUM                         53
+#define TK_VIEW                           54
+#define TK_VIRTUAL                        55
+#define TK_REINDEX                        56
+#define TK_RENAME                         57
+#define TK_CTIME_KW                       58
+#define TK_ANY                            59
+#define TK_OR                             60
+#define TK_AND                            61
+#define TK_IS                             62
+#define TK_BETWEEN                        63
+#define TK_IN                             64
+#define TK_ISNULL                         65
+#define TK_NOTNULL                        66
+#define TK_NE                             67
+#define TK_EQ                             68
+#define TK_GT                             69
+#define TK_LE                             70
+#define TK_LT                             71
+#define TK_GE                             72
+#define TK_ESCAPE                         73
+#define TK_BITAND                         74
+#define TK_BITOR                          75
+#define TK_LSHIFT                         76
+#define TK_RSHIFT                         77
+#define TK_PLUS                           78
+#define TK_MINUS                          79
+#define TK_STAR                           80
+#define TK_SLASH                          81
+#define TK_REM                            82
+#define TK_CONCAT                         83
+#define TK_COLLATE                        84
+#define TK_UMINUS                         85
+#define TK_UPLUS                          86
+#define TK_BITNOT                         87
+#define TK_STRING                         88
+#define TK_JOIN_KW                        89
+#define TK_CONSTRAINT                     90
+#define TK_DEFAULT                        91
+#define TK_NULL                           92
+#define TK_PRIMARY                        93
+#define TK_UNIQUE                         94
+#define TK_CHECK                          95
+#define TK_REFERENCES                     96
+#define TK_AUTOINCR                       97
+#define TK_ON                             98
+#define TK_DELETE                         99
+#define TK_UPDATE                         100
+#define TK_INSERT                         101
+#define TK_SET                            102
+#define TK_DEFERRABLE                     103
+#define TK_FOREIGN                        104
+#define TK_DROP                           105
+#define TK_UNION                          106
+#define TK_ALL                            107
+#define TK_EXCEPT                         108
+#define TK_INTERSECT                      109
+#define TK_SELECT                         110
+#define TK_DISTINCT                       111
+#define TK_DOT                            112
+#define TK_FROM                           113
+#define TK_JOIN                           114
+#define TK_USING                          115
+#define TK_ORDER                          116
+#define TK_BY                             117
+#define TK_GROUP                          118
+#define TK_HAVING                         119
+#define TK_LIMIT                          120
+#define TK_WHERE                          121
+#define TK_INTO                           122
+#define TK_VALUES                         123
+#define TK_INTEGER                        124
+#define TK_FLOAT                          125
+#define TK_BLOB                           126
+#define TK_REGISTER                       127
+#define TK_VARIABLE                       128
+#define TK_CASE                           129
+#define TK_WHEN                           130
+#define TK_THEN                           131
+#define TK_ELSE                           132
+#define TK_INDEX                          133
+#define TK_ALTER                          134
+#define TK_TO                             135
+#define TK_ADD                            136
+#define TK_COLUMNKW                       137
+#define TK_TO_TEXT                        138
+#define TK_TO_BLOB                        139
+#define TK_TO_NUMERIC                     140
+#define TK_TO_INT                         141
+#define TK_TO_REAL                        142
+#define TK_END_OF_FILE                    143
+#define TK_ILLEGAL                        144
+#define TK_SPACE                          145
+#define TK_UNCLOSED_STRING                146
+#define TK_COMMENT                        147
+#define TK_FUNCTION                       148
+#define TK_COLUMN                         149
+#define TK_AGG_FUNCTION                   150
+#define TK_AGG_COLUMN                     151
+#define TK_CONST_FUNC                     152
index 4380a9b76f14297763920ea230137d0706525334..332ddebe0feaca8ec2631695939fca02f92dd6db 100644 (file)
@@ -175,7 +175,7 @@ id(A) ::= ID(X).         {A = X;}
   ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT
   DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
   IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH PLAN QUERY KEY
-  OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
+  OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW
   TEMP TRIGGER VACUUM VIEW VIRTUAL
 %ifdef SQLITE_OMIT_COMPOUND_SELECT
   EXCEPT INTERSECT UNION
@@ -239,9 +239,8 @@ typetoken(A) ::= typename(X) LP signed COMMA signed RP(Y). {
 %type typename {Token}
 typename(A) ::= ids(X).             {A = X;}
 typename(A) ::= typename(X) ids(Y). {A.z=X.z; A.n=Y.n+(Y.z-X.z);}
-%type signed {int}
-signed(A) ::= plus_num(X).    { A = atoi((char*)X.z); }
-signed(A) ::= minus_num(X).   { A = -atoi((char*)X.z); }
+signed ::= plus_num.
+signed ::= minus_num.
 
 // "carglist" is a list of additional constraints that come after the
 // column name and column type in a CREATE TABLE statement.
@@ -543,10 +542,18 @@ having_opt(A) ::= .                {A = 0;}
 having_opt(A) ::= HAVING expr(X).  {A = X;}
 
 %type limit_opt {struct LimitVal}
-%destructor limit_opt {
-  sqlite3ExprDelete($$.pLimit);
-  sqlite3ExprDelete($$.pOffset);
-}
+
+// The destructor for limit_opt will never fire in the current grammar.
+// The limit_opt non-terminal only occurs at the end of a single production
+// rule for SELECT statements.  As soon as the rule that create the 
+// limit_opt non-terminal reduces, the SELECT statement rule will also
+// reduce.  So there is never a limit_opt non-terminal on the stack 
+// except as a transient.  So there is never anything to destroy.
+//
+//%destructor limit_opt {
+//  sqlite3ExprDelete($$.pLimit);
+//  sqlite3ExprDelete($$.pOffset);
+//}
 limit_opt(A) ::= .                     {A.pLimit = 0; A.pOffset = 0;}
 limit_opt(A) ::= LIMIT expr(X).        {A.pLimit = X; A.pOffset = 0;}
 limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). 
@@ -890,8 +897,10 @@ cmd ::= DROP INDEX ifexists(E) fullname(X).   {sqlite3DropIndex(pParse, X, E);}
 ///////////////////////////// The VACUUM command /////////////////////////////
 //
 %ifndef SQLITE_OMIT_VACUUM
+%ifndef SQLITE_OMIT_ATTACH
 cmd ::= VACUUM.                {sqlite3Vacuum(pParse);}
 cmd ::= VACUUM nm.             {sqlite3Vacuum(pParse);}
+%endif  SQLITE_OMIT_ATTACH
 %endif  SQLITE_OMIT_VACUUM
 
 ///////////////////////////// The PRAGMA command /////////////////////////////
@@ -926,8 +935,8 @@ cmd ::= CREATE trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). {
 
 trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z) 
                     trigger_time(C) trigger_event(D)
-                    ON fullname(E) foreach_clause(F) when_clause(G). {
-  sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, F, G, T, NOERR);
+                    ON fullname(E) foreach_clause when_clause(G). {
+  sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, G, T, NOERR);
   A = (Z.n==0?B:Z);
 }
 
@@ -943,10 +952,8 @@ trigger_event(A) ::= DELETE|INSERT(OP).       {A.a = @OP; A.b = 0;}
 trigger_event(A) ::= UPDATE(OP).              {A.a = @OP; A.b = 0;}
 trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X;}
 
-%type foreach_clause {int}
-foreach_clause(A) ::= .                   { A = TK_ROW; }
-foreach_clause(A) ::= FOR EACH ROW.       { A = TK_ROW; }
-foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }
+foreach_clause ::= .
+foreach_clause ::= FOR EACH ROW.
 
 %type when_clause {Expr*}
 %destructor when_clause {sqlite3ExprDelete($$);}
@@ -1018,9 +1025,14 @@ cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). {
 %endif  !SQLITE_OMIT_TRIGGER
 
 //////////////////////// ATTACH DATABASE file AS name /////////////////////////
+%ifndef SQLITE_OMIT_ATTACH
 cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). {
   sqlite3Attach(pParse, F, D, K);
 }
+cmd ::= DETACH database_kw_opt expr(D). {
+  sqlite3Detach(pParse, D);
+}
+
 %type key_opt {Expr *}
 %destructor key_opt {sqlite3ExprDelete($$);}
 key_opt(A) ::= .                     { A = 0; }
@@ -1028,11 +1040,7 @@ key_opt(A) ::= KEY expr(X).          { A = X; }
 
 database_kw_opt ::= DATABASE.
 database_kw_opt ::= .
-
-//////////////////////// DETACH DATABASE name /////////////////////////////////
-cmd ::= DETACH database_kw_opt expr(D). {
-  sqlite3Detach(pParse, D);
-}
+%endif SQLITE_OMIT_ATTACH
 
 ////////////////////////// REINDEX collation //////////////////////////////////
 %ifndef SQLITE_OMIT_REINDEX
index b1c5954de7eb8dfbc5cbfdd5f998a71d009c148a..831aac57bd6213b27e69e00fcd4aed9cc9431825 100644 (file)
@@ -62,6 +62,17 @@ static int getBoolean(const char *z){
   return getSafetyLevel(z)&1;
 }
 
+/*
+** Interpret the given string as a locking mode value.
+*/
+static int getLockingMode(const char *z){
+  if( z ){
+    if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE;
+    if( 0==sqlite3StrICmp(z, "normal") ) return PAGER_LOCKINGMODE_NORMAL;
+  }
+  return PAGER_LOCKINGMODE_QUERY;
+}
+
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
 /*
 ** Interpret the given string as a temp db location. Return 1 for file
@@ -89,7 +100,7 @@ static int getTempStore(const char *z){
 static int invalidateTempStorage(Parse *pParse){
   sqlite3 *db = pParse->db;
   if( db->aDb[1].pBt!=0 ){
-    if( db->flags & SQLITE_InTrans ){
+    if( !db->autoCommit ){
       sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
         "from within a transaction");
       return SQLITE_ERROR;
@@ -157,7 +168,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
     { "ignore_check_constraints", SQLITE_IgnoreChecks  },
 #endif
     /* The following is VERY experimental */
-    { "writable_schema",          SQLITE_WriteSchema   },
+    { "writable_schema",          SQLITE_WriteSchema|SQLITE_RecoveryMode },
     { "omit_readlock",            SQLITE_NoReadlock    },
 
     /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
@@ -315,6 +326,53 @@ void sqlite3Pragma(
       sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1);
     }
   }else
+
+  /*
+  **  PRAGMA [database.]locking_mode
+  **  PRAGMA [database.]locking_mode = (normal|exclusive)
+  */
+  if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){
+    const char *zRet = "normal";
+    int eMode = getLockingMode(zRight);
+
+    if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){
+      /* Simple "PRAGMA locking_mode;" statement. This is a query for
+      ** the current default locking mode (which may be different to
+      ** the locking-mode of the main database).
+      */
+      eMode = db->dfltLockMode;
+    }else{
+      Pager *pPager;
+      if( pId2->n==0 ){
+        /* This indicates that no database name was specified as part
+        ** of the PRAGMA command. In this case the locking-mode must be
+        ** set on all attached databases, as well as the main db file.
+        **
+        ** Also, the sqlite3.dfltLockMode variable is set so that
+        ** any subsequently attached databases also use the specified
+        ** locking mode.
+        */
+        int ii;
+        assert(pDb==&db->aDb[0]);
+        for(ii=2; ii<db->nDb; ii++){
+          pPager = sqlite3BtreePager(db->aDb[ii].pBt);
+          sqlite3PagerLockingMode(pPager, eMode);
+        }
+        db->dfltLockMode = eMode;
+      }
+      pPager = sqlite3BtreePager(pDb->pBt);
+      eMode = sqlite3PagerLockingMode(pPager, eMode);
+    }
+
+    assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE);
+    if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
+      zRet = "exclusive";
+    }
+    sqlite3VdbeSetNumCols(v, 1);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P3_STATIC);
+    sqlite3VdbeOp3(v, OP_String8, 0, 0, zRet, 0);
+    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+  }else
 #endif /* SQLITE_OMIT_PAGER_PRAGMAS */
 
   /*
@@ -916,7 +974,7 @@ void sqlite3Pragma(
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P3_TRANSIENT);
     }
-  }
+  }else
 #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
 
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
@@ -941,7 +999,7 @@ void sqlite3Pragma(
       if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
         sqlite3VdbeOp3(v, OP_String8, 0, 0, "closed", P3_STATIC);
       }else{
-        int j = sqlite3pager_lockstate(pPager);
+        int j = sqlite3PagerLockstate(pPager);
         sqlite3VdbeOp3(v, OP_String8, 0, 0, 
             (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);
       }
index e584f789af4d037fbe31ecde7449289e12dac8ee..a65c566bf8179c51051aabf8efc8769a182e91ee 100644 (file)
@@ -310,10 +310,17 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
     rc = SQLITE_NOMEM;
     sqlite3ResetInternalSchema(db, 0);
   }
-  if( rc==SQLITE_OK ){
+  if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
+    /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
+    ** the schema loaded, even if errors occured. In this situation the 
+    ** current sqlite3_prepare() operation will fail, but the following one
+    ** will attempt to compile the supplied statement against whatever subset
+    ** of the schema was loaded before the error occured. The primary
+    ** purpose of this is to allow access to the sqlite_master table
+    ** even when it's contents have been corrupted.
+    */
     DbSetProperty(db, iDb, DB_SchemaLoaded);
-  }else{
-    sqlite3ResetInternalSchema(db, iDb);
+    rc = SQLITE_OK;
   }
   return rc;
 }
@@ -559,7 +566,7 @@ int sqlite3Prepare(
 */
 int sqlite3Reprepare(Vdbe *p){
   int rc;
-  Vdbe *pNew;
+  sqlite3_stmt *pNew;
   const char *zSql;
   sqlite3 *db;
   
@@ -568,17 +575,17 @@ int sqlite3Reprepare(Vdbe *p){
     return 0;
   }
   db = sqlite3VdbeDb(p);
-  rc = sqlite3Prepare(db, zSql, -1, 0, (sqlite3_stmt**)&pNew, 0);
+  rc = sqlite3Prepare(db, zSql, -1, 0, &pNew, 0);
   if( rc ){
     assert( pNew==0 );
     return 0;
   }else{
     assert( pNew!=0 );
   }
-  sqlite3VdbeSwap(pNew, p);
-  sqlite3_transfer_bindings((sqlite3_stmt*)pNew, (sqlite3_stmt*)p);
-  sqlite3VdbeResetStepResult(pNew);
-  sqlite3VdbeFinalize(pNew);
+  sqlite3VdbeSwap((Vdbe*)pNew, p);
+  sqlite3_transfer_bindings(pNew, (sqlite3_stmt*)p);
+  sqlite3VdbeResetStepResult((Vdbe*)pNew);
+  sqlite3VdbeFinalize((Vdbe*)pNew);
   return 1;
 }
 
index a05fec21f634f0a92ef669460f5f4346a07ad318..17809b11eb57e2426f6498f6c754c32512a26112 100644 (file)
@@ -821,9 +821,8 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
 char *sqlite3_mprintf(const char *zFormat, ...){
   va_list ap;
   char *z;
-  char zBase[SQLITE_PRINT_BUF_SIZE];
   va_start(ap, zFormat);
-  z = base_vprintf(sqlite3_realloc, 0, zBase, sizeof(zBase), zFormat, ap);
+  z = sqlite3_vmprintf(zFormat, ap);
   va_end(ap);
   return z;
 }
index f5252d2e0d29e2f476d6031b8a484f92e16b3548..59120b32ee98f8a316e81b5e24aa68ef78bb8a63 100644 (file)
@@ -66,6 +66,7 @@ Select *sqlite3SelectNew(
   pNew->pOrderBy = pOrderBy;
   pNew->isDistinct = isDistinct;
   pNew->op = TK_SELECT;
+  assert( pOffset==0 || pLimit!=0 );
   pNew->pLimit = pLimit;
   pNew->pOffset = pOffset;
   pNew->iLimit = -1;
@@ -532,7 +533,7 @@ static int selectInnerLoop(
       }else{
         sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
         sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-        sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
+        sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
       }
       break;
     }
@@ -691,7 +692,7 @@ static void generateSortTail(
   int cont = sqlite3VdbeMakeLabel(v);
   int addr;
   int iTab;
-  int pseudoTab;
+  int pseudoTab = 0;
   ExprList *pOrderBy = p->pOrderBy;
 
   iTab = pOrderBy->iECursor;
@@ -711,7 +712,7 @@ static void generateSortTail(
     case SRT_EphemTab: {
       sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-      sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
@@ -2364,6 +2365,8 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
   iCol = pExpr->iColumn;
   pTab = pSrc->a[0].pTab;
 
+  /* This optimization cannot be used with virtual tables. */
+  if( IsVirtual(pTab) ) return 0;
 
   /* 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
@@ -3142,11 +3145,7 @@ int sqlite3Select(
         for(i=0; i<sAggInfo.nColumn; i++){
           struct AggInfo_col *pCol = &sAggInfo.aCol[i];
           if( pCol->iSorterColumn<j ) continue;
-          if( pCol->iColumn<0 ){
-            sqlite3VdbeAddOp(v, OP_Rowid, pCol->iTable, 0);
-          }else{
-            sqlite3VdbeAddOp(v, OP_Column, pCol->iTable, pCol->iColumn);
-          }
+          sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable);
           j++;
         }
         sqlite3VdbeAddOp(v, OP_MakeRecord, j, 0);
@@ -3296,7 +3295,7 @@ select_end:
   return rc;
 }
 
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+#if defined(SQLITE_DEBUG)
 /*
 *******************************************************************************
 ** The following code is used for testing and debugging only.  The code
index 0cf75e2046122a8dc0b4ebaf9f6d6dd03f5f46ab..0e4cc4e2303ff0f8de607195a433ac99fbe47530 100644 (file)
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include "sqlite3.h"
 #include <ctype.h>
+#include <stdarg.h>
 
 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) && !defined(__OS2__)
 # include <signal.h>
@@ -97,6 +98,28 @@ static char *Argv0;
 static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
 static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
 
+/*
+** Write I/O traces to the following stream.
+*/
+static FILE *iotrace = 0;
+
+/*
+** This routine works like printf in that its first argument is a
+** format string and subsequent arguments are values to be substituted
+** in place of % fields.  The result of formatting this string
+** is written to iotrace.
+*/
+static void iotracePrintf(const char *zFormat, ...){
+  va_list ap;
+  char *z;
+  if( iotrace==0 ) return;
+  va_start(ap, zFormat);
+  z = sqlite3_vmprintf(zFormat, ap);
+  va_end(ap);
+  fprintf(iotrace, "%s", z);
+  sqlite3_free(z);
+}
+
 
 /*
 ** Determines if a string is a number of not.
@@ -1219,6 +1242,26 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
+  if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
+    extern void (*sqlite3_io_trace)(const char*, ...);
+    if( iotrace && iotrace!=stdout ) fclose(iotrace);
+    iotrace = 0;
+    if( nArg<2 ){
+      sqlite3_io_trace = 0;
+    }else if( strcmp(azArg[1], "-")==0 ){
+      sqlite3_io_trace = iotracePrintf;
+      iotrace = stdout;
+    }else{
+      iotrace = fopen(azArg[1], "w");
+      if( iotrace==0 ){
+        fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
+        sqlite3_io_trace = 0;
+      }else{
+        sqlite3_io_trace = iotracePrintf;
+      }
+    }
+  }else
+
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
   if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
     const char *zFile, *zProc;
index 9c80edfc21f4f393b927bfd781119afe2dcb2d6b..8478cc27a930128d16118944d252cdfa2deb9869 100644 (file)
@@ -182,7 +182,7 @@ int sqlite3_exec(
 #define SQLITE_NOTFOUND    12   /* NOT USED. Table or record not found */
 #define SQLITE_FULL        13   /* Insertion failed because database is full */
 #define SQLITE_CANTOPEN    14   /* Unable to open the database file */
-#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
+#define SQLITE_PROTOCOL    15   /* NOT USED. Database lock protocol error */
 #define SQLITE_EMPTY       16   /* Database is empty */
 #define SQLITE_SCHEMA      17   /* The database schema changed */
 #define SQLITE_TOOBIG      18   /* NOT USED. Too much data for one row */
@@ -230,6 +230,7 @@ int sqlite3_exec(
 #define SQLITE_IOERR_FSTAT         (SQLITE_IOERR | (7<<8))
 #define SQLITE_IOERR_UNLOCK        (SQLITE_IOERR | (8<<8))
 #define SQLITE_IOERR_RDLOCK        (SQLITE_IOERR | (9<<8))
+#define SQLITE_IOERR_DELETE        (SQLITE_IOERR | (10<<8))
 
 /*
 ** Enable or disable the extended result codes.
@@ -239,25 +240,29 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
 /*
 ** Each entry in an SQLite table has a unique integer key.  (The key is
 ** the value of the INTEGER PRIMARY KEY column if there is such a column,
-** otherwise the key is generated at random.  The unique key is always
+** otherwise the key is generated automatically.  The unique key is always
 ** available as the ROWID, OID, or _ROWID_ column.)  The following routine
 ** returns the integer key of the most recent insert in the database.
-**
-** This function is similar to the mysql_insert_id() function from MySQL.
 */
 sqlite_int64 sqlite3_last_insert_rowid(sqlite3*);
 
 /*
 ** This function returns the number of database rows that were changed
-** (or inserted or deleted) by the most recent called sqlite3_exec().
+** (or inserted or deleted) by the most recent SQL statement.  Only
+** changes that are directly specified by the INSERT, UPDATE, or
+** DELETE statement are counted.  Auxiliary changes caused by
+** triggers are not counted.   Within the body of a trigger, however,
+** the sqlite3_changes() API can be called to find the number of
+** changes in the most recently completed INSERT, UPDATE, or DELETE
+** statement within the body of the trigger.
 **
 ** All changes are counted, even if they were later undone by a
 ** ROLLBACK or ABORT.  Except, changes associated with creating and
 ** dropping tables are not counted.
 **
-** If a callback invokes sqlite3_exec() recursively, then the changes
-** in the inner, recursive call are counted together with the changes
-** in the outer call.
+** If a callback invokes sqlite3_exec() or sqlite3_step() recursively,
+** then the changes in the inner, recursive call are counted together
+** with the changes in the outer call.
 **
 ** SQLite implements the command "DELETE FROM table" without a WHERE clause
 ** by dropping and recreating the table.  (This is much faster than going
@@ -292,6 +297,9 @@ int sqlite3_total_changes(sqlite3*);
 ** called in response to a user action such as pressing "Cancel"
 ** or Ctrl-C where the user wants a long query operation to halt
 ** immediately.
+**
+** It is safe to call this routine from a different thread that the
+** thread that is currently running the database operation. 
 */
 void sqlite3_interrupt(sqlite3*);
 
@@ -302,9 +310,13 @@ void sqlite3_interrupt(sqlite3*);
 ** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string
 ** is required.
 **
-** The algorithm is simple.  If the last token other than spaces
-** and comments is a semicolon, then return true.  otherwise return
-** false.
+** This routine is useful for command-line input to see of the user has
+** entered a complete statement of SQL or if the current statement needs
+** to be continued on the next line.  The algorithm is simple.  If the 
+** last token other than spaces and comments is a semicolon, then return 
+** true.  Actually, the algorithm is a little more complicated than that
+** in order to deal with triggers, but the basic idea is the same:  the
+** statement is not complete unless it ends in a semicolon.
 */
 int sqlite3_complete(const char *sql);
 int sqlite3_complete16(const void *sql);
@@ -743,31 +755,32 @@ typedef struct Mem sqlite3_value;
 
 /*
 ** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(),
-** one or more literals can be replace by parameters "?" or ":AAA" or
-** "$VVV" where AAA is an identifer and VVV is a variable name according
-** to the syntax rules of the TCL programming language.
-** The value of these parameters (also called "host parameter names") can
-** be set using the routines listed below.
-**
-** In every case, the first parameter is a pointer to the sqlite3_stmt
-** structure returned from sqlite3_prepare().  The second parameter is the
-** index of the parameter.  The first parameter as an index of 1.  For
-** named parameters (":AAA" or "$VVV") you can use 
+** one or more literals can be replace by parameters "?" or "?NNN" or 
+** ":AAA" or "@AAA" or "$VVV" where NNN is a integer, AAA is an identifer,
+** and VVV is a variable name according  to the syntax rules of the
+** TCL programming language.  The value of these parameters (also called
+** "host parameter names") can be set using the routines listed below.
+**
+** In every case, the first argument is a pointer to the sqlite3_stmt
+** structure returned from sqlite3_prepare().  The second argument is the
+** index of the host parameter name.  The first host parameter as an index 
+** of 1.  For named host parameters (":AAA" or "$VVV") you can use 
 ** sqlite3_bind_parameter_index() to get the correct index value given
-** the parameters name.  If the same named parameter occurs more than
+** the parameter name.  If the same named parameter occurs more than
 ** once, it is assigned the same index each time.
 **
-** The fifth parameter to sqlite3_bind_blob(), sqlite3_bind_text(), and
+** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
 ** text after SQLite has finished with it.  If the fifth argument is the
 ** special value SQLITE_STATIC, then the library assumes that the information
 ** is in static, unmanaged space and does not need to be freed.  If the
 ** fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its
-** own private copy of the data.
+** own private copy of the data before the sqlite3_bind_* routine returns.
 **
-** The sqlite3_bind_* routine must be called before sqlite3_step() after
-** an sqlite3_prepare() or sqlite3_reset().  Unbound parameterss are
-** interpreted as NULL.
+** The sqlite3_bind_* routine must be called before sqlite3_step() and after
+** an sqlite3_prepare() or sqlite3_reset().  Bindings persist across
+** multiple calls to sqlite3_reset() and sqlite3_step().  Unbound parameters 
+** are interpreted as NULL.
 */
 int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
 int sqlite3_bind_double(sqlite3_stmt*, int, double);
@@ -779,13 +792,13 @@ int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
 int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
 
 /*
-** Return the number of parameters in a compiled SQL statement.  This
+** Return the number of host parameters in a compiled SQL statement.  This
 ** routine was added to support DBD::SQLite.
 */
 int sqlite3_bind_parameter_count(sqlite3_stmt*);
 
 /*
-** Return the name of the i-th parameter.  Ordinary parameters "?" are
+** Return the name of the i-th name parameter.  Ordinary parameters "?" are
 ** nameless and a NULL is returned.  For parameters of the form :AAA or
 ** $VVV the complete text of the parameter name is returned, including
 ** the initial ":" or "$".  NULL is returned if the index is out of range.
@@ -821,7 +834,7 @@ const char *sqlite3_column_name(sqlite3_stmt*,int);
 const void *sqlite3_column_name16(sqlite3_stmt*,int);
 
 /*
-** The first parameter to the following calls is a compiled SQL statement.
+** The first argument 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.
 **
index 1df21d6aa9beb5d4b30bee236dc468e0f844afe1..ad47243b642b0455e7e247269359f10133c9e713 100644 (file)
@@ -142,8 +142,11 @@ struct sqlite3_api_routines {
   const void * (*value_text16be)(sqlite3_value*);
   const void * (*value_text16le)(sqlite3_value*);
   int  (*value_type)(sqlite3_value*);
-  char * (*vmprintf)(const char*,va_list);
+  char *(*vmprintf)(const char*,va_list);
   int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
+  int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
+  int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
+  int (*clear_bindings)(sqlite3_stmt*);
 };
 
 /*
@@ -232,6 +235,8 @@ struct sqlite3_api_routines {
 #define sqlite3_open16                 sqlite3_api->open16
 #define sqlite3_prepare                sqlite3_api->prepare
 #define sqlite3_prepare16              sqlite3_api->prepare16
+#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
+#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
 #define sqlite3_profile                sqlite3_api->profile
 #define sqlite3_progress_handler       sqlite3_api->progress_handler
 #define sqlite3_realloc                sqlite3_api->realloc
@@ -274,6 +279,9 @@ struct sqlite3_api_routines {
 #define sqlite3_value_type             sqlite3_api->value_type
 #define sqlite3_vmprintf               sqlite3_api->vmprintf
 #define sqlite3_overload_function      sqlite3_api->overload_function
+#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
+#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
+#define sqlite3_clear_bindings         sqlite3_api->clear_bindings
 #endif /* SQLITE_CORE */
 
 #define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api;
index efe84f0f1dbba2bc8953315ac2db951118c98a3f..0b8950d7bc730d67af230120d1575108931ae648 100644 (file)
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
 
-/*
-** Extra interface definitions for those who need them
-*/
-#ifdef SQLITE_EXTRA
-# include "sqliteExtra.h"
+#if defined(SQLITE_TCL) || defined(TCLSH)
+# include <tcl.h>
 #endif
 
 /*
@@ -215,8 +212,15 @@ typedef UINT8_TYPE i8;             /* 1-byte signed integer */
 ** evaluated at runtime.
 */
 extern const int sqlite3one;
-#define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)
-#define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
+#if defined(i386) || defined(__i386__) || defined(_M_IX86)
+# define SQLITE_BIGENDIAN    0
+# define SQLITE_LITTLEENDIAN 1
+# define SQLITE_UTF16NATIVE  SQLITE_UTF16LE
+#else
+# define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)
+# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
+# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
+#endif
 
 /*
 ** An instance of the following structure is used to store the busy-handler
@@ -414,7 +418,6 @@ struct Schema {
 #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)
 
 /*
 ** Each database is an instance of the following structure.
@@ -510,6 +513,7 @@ struct sqlite3 {
 #ifdef SQLITE_SSE
   sqlite3_stmt *pFetch;         /* Used by SSE to fetch stored statements */
 #endif
+  u8 dfltLockMode;              /* Default locking-mode for attached dbs */
 };
 
 /*
@@ -545,6 +549,8 @@ struct sqlite3 {
 #define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
 #define SQLITE_LoadExtension  0x00020000  /* Enable load_extension */
 
+#define SQLITE_RecoveryMode   0x00040000  /* Ignore schema errors */
+
 /*
 ** Possible values for the sqlite.magic field.
 ** The numbers are obtained at random and have no special meaning, other
@@ -922,6 +928,7 @@ struct AggInfo {
   ExprList *pGroupBy;     /* The group by clause */
   int nSortingColumn;     /* Number of columns in the sorting index */
   struct AggInfo_col {    /* For each column used in source tables */
+    Table *pTab;             /* Source table */
     int iTable;              /* Cursor number of the source table */
     int iColumn;             /* Column number within the source table */
     int iSorterColumn;       /* Column number in the sorting index */
@@ -1159,12 +1166,16 @@ struct WhereLevel {
   int iTabCur;          /* The VDBE cursor used to access the table */
   int iIdxCur;          /* The VDBE cursor used to acesss pIdx */
   int brk;              /* Jump here to break out of the loop */
+  int nxt;              /* Jump here to start the next IN combination */
   int cont;             /* Jump here to continue with the next loop cycle */
   int top;              /* First instruction of interior of the loop */
   int op, p1, p2;       /* Opcode used to terminate the loop */
   int nEq;              /* Number of == or IN constraints on this loop */
   int nIn;              /* Number of IN operators constraining this loop */
-  int *aInLoop;         /* Loop terminators for IN operators */
+  struct InLoop {
+    int iCur;              /* The VDBE cursor used by this IN operator */
+    int topAddr;           /* Top of the IN loop */
+  } *aInLoop;           /* Information about each nested IN operator */
   sqlite3_index_info *pBestIdx;  /* Index information for this level */
 
   /* The following field is really not part of the current level.  But
@@ -1371,6 +1382,7 @@ struct AuthContext {
 #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 */
+#define OPFLAG_APPEND    8    /* This is likely to be an append */
 
 /*
  * Each trigger present in the database schema is stored as an instance of
@@ -1395,7 +1407,6 @@ struct Trigger {
   Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
   IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                              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 */
@@ -1566,7 +1577,7 @@ void *sqlite3Realloc(void*,int);
 char *sqlite3StrDup(const char*);
 char *sqlite3StrNDup(const char*, int);
 # define sqlite3CheckMemory(a,b)
-void sqlite3ReallocOrFree(void**,int);
+void *sqlite3ReallocOrFree(void*,int);
 void sqlite3FreeX(void*);
 void *sqlite3MallocX(int);
 int sqlite3AllocSize(void *);
@@ -1598,7 +1609,6 @@ int sqlite3InitCallback(void*, int, char**, char**);
 void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
 void sqlite3ResetInternalSchema(sqlite3*, int);
 void sqlite3BeginParse(Parse*,int);
-void sqlite3RollbackInternalChanges(sqlite3*);
 void sqlite3CommitInternalChanges(sqlite3*);
 Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
 void sqlite3OpenMasterTable(Parse *, int);
@@ -1623,7 +1633,7 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
 void sqlite3DropTable(Parse*, SrcList*, int, int);
 void sqlite3DeleteTable(sqlite3*, Table*);
 void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
-int sqlite3ArrayAllocate(void**,int,int);
+void *sqlite3ArrayAllocate(void*,int,int,int*,int*,int*);
 IdList *sqlite3IdListAppend(IdList*, Token*);
 int sqlite3IdListIndex(IdList*,const char*);
 SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
@@ -1650,6 +1660,7 @@ void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
 void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
 WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
 void sqlite3WhereEnd(WhereInfo*);
+void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int);
 void sqlite3ExprCode(Parse*, Expr*);
 void sqlite3ExprCodeAndCache(Parse*, Expr*);
 int sqlite3ExprCodeExprList(Parse*, ExprList*);
@@ -1686,7 +1697,7 @@ void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
 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);
+void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int, int);
 void sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
 void sqlite3BeginWriteOperation(Parse*, int, int);
 Expr *sqlite3ExprDup(Expr*);
@@ -1705,7 +1716,7 @@ void sqlite3ChangeCookie(sqlite3*, Vdbe*, int);
 
 #ifndef SQLITE_OMIT_TRIGGER
   void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
-                           int,Expr*,int, int);
+                           Expr*,int, int);
   void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
   void sqlite3DropTrigger(Parse*, SrcList*, int);
   void sqlite3DropTriggerPtr(Parse*, Trigger*);
@@ -1895,4 +1906,18 @@ int sqlite3Reprepare(Vdbe*);
 #include "sseInt.h"
 #endif
 
+/*
+** If the SQLITE_ENABLE IOTRACE exists then the global variable
+** sqlite3_io_trace is a pointer to a printf-like routine used to
+** print I/O tracing messages. 
+*/
+#ifdef SQLITE_ENABLE_IOTRACE
+# define IOTRACE(A)  if( sqlite3_io_trace ){ sqlite3_io_trace A; }
+  void sqlite3VdbeIOTraceSql(Vdbe*);
+#else
+# define IOTRACE(A)
+# define sqlite3VdbeIOTraceSql(X)
+#endif
+extern void (*sqlite3_io_trace)(const char*,...);
+
 #endif
index e1c1c67901a11f7960aff61fd72587b7159d699c..4e30bd298f6032598656f3df679862a4f8291066 100644 (file)
@@ -9,19 +9,25 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** A TCL Interface to SQLite
+** A TCL Interface to SQLite.  Append this file to sqlite3.c and
+** compile the whole thing to build a TCL-enabled version of SQLite.
 **
 ** $Id$
 */
-#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
-
-#include "sqliteInt.h"
-#include "hash.h"
 #include "tcl.h"
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
+
+/*
+** Some additional include files are needed if this file is not
+** appended to the amalgamation.
+*/
+#ifndef SQLITE_AMALGAMATION
+# include "sqliteInt.h"
+# include "hash.h"
+# include <stdlib.h>
+# include <string.h>
+# include <assert.h>
+# include <ctype.h>
+#endif
 
 /*
  * Windows needs to know which symbols to export.  Unix does not.
@@ -2205,12 +2211,14 @@ int TCLSH_MAIN(int argc, char **argv){
     extern int Sqlitetest6_Init(Tcl_Interp*);
     extern int Sqlitetest7_Init(Tcl_Interp*);
     extern int Sqlitetest8_Init(Tcl_Interp*);
+    extern int Sqlitetest9_Init(Tcl_Interp*);
     extern int Md5_Init(Tcl_Interp*);
     extern int Sqlitetestsse_Init(Tcl_Interp*);
     extern int Sqlitetestasync_Init(Tcl_Interp*);
     extern int Sqlitetesttclvar_Init(Tcl_Interp*);
     extern int Sqlitetestschema_Init(Tcl_Interp*);
     extern int Sqlitetest_autoext_Init(Tcl_Interp*);
+    extern int Sqlitetest_hexio_Init(Tcl_Interp*);
 
     Sqlitetest1_Init(interp);
     Sqlitetest2_Init(interp);
@@ -2220,10 +2228,12 @@ int TCLSH_MAIN(int argc, char **argv){
     Sqlitetest6_Init(interp);
     Sqlitetest7_Init(interp);
     Sqlitetest8_Init(interp);
+    Sqlitetest9_Init(interp);
     Sqlitetestasync_Init(interp);
     Sqlitetesttclvar_Init(interp);
     Sqlitetestschema_Init(interp);
     Sqlitetest_autoext_Init(interp);
+    Sqlitetest_hexio_Init(interp);
     Md5_Init(interp);
 #ifdef SQLITE_SSE
     Sqlitetestsse_Init(interp);
@@ -2254,5 +2264,3 @@ int TCLSH_MAIN(int argc, char **argv){
   return 0;
 }
 #endif /* TCLSH */
-
-#endif /* !defined(NO_TCL) */
index af15a2db6711963016266b5d8119772c3787b00e..f271eee8758071ffe04e23e21c48223d4fa5410f 100644 (file)
@@ -112,7 +112,7 @@ const char *sqlite3TestErrorName(int rc){
   }
   return zName;
 }
-#define errorName sqlite3TestErrorName
+#define t1ErrorName sqlite3TestErrorName
 
 /*
 ** Convert an sqlite3_stmt* into an sqlite3*.  This depends on the
@@ -129,7 +129,7 @@ int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
     char zBuf[200];
     int r2 = sqlite3_errcode(db);
     sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",
-       errorName(rc), rc, errorName(r2), r2);
+       t1ErrorName(rc), rc, t1ErrorName(r2), r2);
     Tcl_ResetResult(interp);
     Tcl_AppendResult(interp, zBuf, 0);
     return 1;
@@ -490,7 +490,7 @@ static int sqlite_test_close(
   }
   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
   rc = sqlite3_close(db);
-  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
   return TCL_OK;
 }
 
@@ -498,7 +498,11 @@ static int sqlite_test_close(
 ** Implementation of the x_coalesce() function.
 ** Return the first argument non-NULL argument.
 */
-static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+static void t1_ifnullFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
   int i;
   for(i=0; i<argc; i++){
     if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
@@ -682,7 +686,7 @@ static int test_create_function(
   }
   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
   rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 
-        ifnullFunc, 0, 0);
+        t1_ifnullFunc, 0, 0);
   if( rc==SQLITE_OK ){
     rc = sqlite3_create_function(db, "hex8", 1, SQLITE_ANY, 0, 
           hex8Func, 0, 0);
@@ -716,7 +720,7 @@ static int test_create_function(
 #endif
 
   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
-  Tcl_SetResult(interp, (char *)errorName(rc), 0);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
   return TCL_OK;
 }
 
@@ -731,12 +735,16 @@ static int test_create_function(
 ** is reported on the step function.  If the total count is 42, then
 ** a UTF-8 error is reported on the finalize function.
 */
-typedef struct CountCtx CountCtx;
-struct CountCtx {
+typedef struct t1CountCtx t1CountCtx;
+struct t1CountCtx {
   int n;
 };
-static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
-  CountCtx *p;
+static void t1CountStep(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  t1CountCtx *p;
   p = sqlite3_aggregate_context(context, sizeof(*p));
   if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){
     p->n++;
@@ -753,8 +761,8 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
     }
   }
 }   
-static void countFinalize(sqlite3_context *context){
-  CountCtx *p;
+static void t1CountFinalize(sqlite3_context *context){
+  t1CountCtx *p;
   p = sqlite3_aggregate_context(context, sizeof(*p));
   if( p ){
     if( p->n==42 ){
@@ -794,10 +802,10 @@ static int test_create_aggregate(
   }
   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
   rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
-      countStep,countFinalize);
+      t1CountStep,t1CountFinalize);
   if( rc==SQLITE_OK ){
     sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
-        countStep,countFinalize);
+        t1CountStep,t1CountFinalize);
   }
   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
   return TCL_OK;
@@ -926,6 +934,40 @@ static int sqlite3_mprintf_str(
   return TCL_OK;
 }
 
+/*
+** Usage:  sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING
+**
+** Call mprintf with two integer arguments and one string argument
+*/
+static int sqlite3_snprintf_str(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  char **argv            /* Text of each argument */
+){
+  int a[3], i;
+  int n;
+  char *z;
+  if( argc<5 || argc>6 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " INT FORMAT INT INT ?STRING?\"", 0);
+    return TCL_ERROR;
+  }
+  if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
+  if( n<0 ){
+    Tcl_AppendResult(interp, "N must be non-negative", 0);
+    return TCL_ERROR;
+  }
+  for(i=3; i<5; i++){
+    if( Tcl_GetInt(interp, argv[i], &a[i-3]) ) return TCL_ERROR;
+  }
+  z = sqlite3_malloc( n+1 );
+  sqlite3_snprintf(n, z, argv[2], a[0], a[1], argc>4 ? argv[5] : NULL);
+  Tcl_AppendResult(interp, z, 0);
+  sqlite3_free(z);
+  return TCL_OK;
+}
+
 /*
 ** Usage:  sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE
 **
@@ -1497,7 +1539,7 @@ static int test_finalize(
     db = StmtToDb(pStmt);
   }
   rc = sqlite3_finalize(pStmt);
-  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
   if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
   return TCL_OK;
 }
@@ -1528,7 +1570,7 @@ static int test_reset(
   if( pStmt && sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ){
     return TCL_ERROR;
   }
-  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
 /*
   if( rc ){
     return TCL_ERROR;
@@ -2052,7 +2094,7 @@ static int test_errstr(
 
   zCode = Tcl_GetString(objv[1]);
   for(i=0; i<200; i++){
-    if( 0==strcmp(errorName(i), zCode) ) break;
+    if( 0==strcmp(t1ErrorName(i), zCode) ) break;
   }
   Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0);
   return TCL_OK;
@@ -2504,7 +2546,7 @@ static int test_errcode(
   }else{
     sprintf(zBuf,"+%d", rc>>8);
   }
-  Tcl_AppendResult(interp, (char *)errorName(rc), zBuf, 0);
+  Tcl_AppendResult(interp, (char *)t1ErrorName(rc), zBuf, 0);
   return TCL_OK;
 }
 
@@ -2900,7 +2942,7 @@ static int test_step(
   rc = sqlite3_step(pStmt);
 
   /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
-  Tcl_SetResult(interp, (char *)errorName(rc), 0);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
   return TCL_OK;
 }
 
@@ -3137,7 +3179,7 @@ static int test_global_recover(
     return TCL_ERROR;
   }
   rc = sqlite3_global_recover();
-  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
 #endif
   return TCL_OK;
 }
@@ -3235,7 +3277,7 @@ static int test_sqlite3OsOpenReadWrite(
 
   rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), &pFile, &dummy);
   if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
     return TCL_ERROR;
   }
   sqlite3TestMakePointerStr(interp, zBuf, pFile);
@@ -3266,7 +3308,7 @@ static int test_sqlite3OsClose(
   }
   rc = sqlite3OsClose(&pFile);
   if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
     return TCL_ERROR;
   }
   return TCL_OK;
@@ -3314,7 +3356,7 @@ static int test_sqlite3OsLock(
   }
 
   if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
     return TCL_ERROR;
   }
   return TCL_OK;
@@ -3343,7 +3385,7 @@ static int test_sqlite3OsUnlock(
   }
   rc = sqlite3OsUnlock(pFile, NO_LOCK);
   if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
     return TCL_ERROR;
   }
   return TCL_OK;
@@ -3363,7 +3405,7 @@ static int test_sqlite3OsTempFileName(
 
   rc = sqlite3OsTempFileName(zFile);
   if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
     return TCL_ERROR;
   }
   Tcl_AppendResult(interp, zFile, 0);
@@ -3492,7 +3534,7 @@ static int delete_function(
   }
   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0);
-  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
   return TCL_OK;
 }
 
@@ -3518,7 +3560,7 @@ static int delete_collation(
   }
   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
   rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0);
-  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
   return TCL_OK;
 }
 
@@ -3708,6 +3750,44 @@ static int test_thread_cleanup(
 }
 
 
+/*
+** Usage:   sqlite3_pager_refcounts  DB
+**
+** Return a list of numbers which are the PagerRefcount for all
+** pagers on each database connection.
+*/
+static int test_pager_refcounts(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3 *db;
+  int i;
+  int v, *a;
+  Tcl_Obj *pResult;
+
+  if( objc!=2 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"",
+        Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+  pResult = Tcl_NewObj();
+  for(i=0; i<db->nDb; i++){
+    if( db->aDb[i].pBt==0 ){
+      v = -1;
+    }else{
+      a = sqlite3PagerStats(sqlite3BtreePager(db->aDb[i].pBt));
+      v = a[0];
+    }
+    Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(v));
+  }
+  Tcl_SetObjResult(interp, pResult);
+  return TCL_OK;
+}
+
+
 /*
 ** This routine sets entries in the global ::sqlite_options() array variable
 ** according to the compile-time configuration of the database.  Test
@@ -3750,6 +3830,12 @@ static void set_options(Tcl_Interp *interp){
   Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY);
 #endif
 
+#ifdef SQLITE_OMIT_ATTACH
+  Tcl_SetVar2(interp, "sqlite_options", "attach", "0", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "attach", "1", TCL_GLOBAL_ONLY);
+#endif
+
 #ifdef SQLITE_OMIT_AUTHORIZATION
   Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY);
 #else
@@ -3893,6 +3979,12 @@ static void set_options(Tcl_Interp *interp){
   Tcl_SetVar2(interp, "sqlite_options", "like_opt", "1", TCL_GLOBAL_ONLY);
 #endif
 
+#ifdef SQLITE_OMIT_LOAD_EXTENSION
+  Tcl_SetVar2(interp, "sqlite_options", "load_ext", "0", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "load_ext", "1", TCL_GLOBAL_ONLY);
+#endif
+
 #ifdef SQLITE_OMIT_MEMORYDB
   Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY);
 #else
@@ -4008,7 +4100,7 @@ static void set_options(Tcl_Interp *interp){
   Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY);
 #endif
 
-#ifdef SQLITE_OMIT_VACUUM
+#if defined(SQLITE_OMIT_VACUUM) || defined(SQLITE_OMIT_ATTACH)
   Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY);
 #else
   Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY);
@@ -4025,6 +4117,25 @@ static void set_options(Tcl_Interp *interp){
 #else
   Tcl_SetVar2(interp, "sqlite_options", "vtab", "1", TCL_GLOBAL_ONLY);
 #endif
+
+#ifdef SQLITE_DEFAULT_FILE_FORMAT
+  Tcl_ObjSetVar2(interp, 
+      Tcl_NewStringObj("sqlite_default_file_format", -1), 0, 
+      Tcl_NewIntObj(SQLITE_DEFAULT_FILE_FORMAT), TCL_GLOBAL_ONLY
+  );
+#endif
+#ifdef SQLITE_MAX_PAGE_SIZE
+  Tcl_ObjSetVar2(interp, 
+      Tcl_NewStringObj("SQLITE_MAX_PAGE_SIZE", -1), 0, 
+      Tcl_NewIntObj(SQLITE_MAX_PAGE_SIZE), TCL_GLOBAL_ONLY
+  );
+#endif
+#ifdef TEMP_STORE
+  Tcl_ObjSetVar2(interp, 
+      Tcl_NewStringObj("TEMP_STORE", -1), 0, 
+      Tcl_NewIntObj(TEMP_STORE), TCL_GLOBAL_ONLY
+  );
+#endif
 }
 
 /*
@@ -4072,6 +4183,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
      { "sqlite3_mprintf_int64",         (Tcl_CmdProc*)sqlite3_mprintf_int64  },
      { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
+     { "sqlite3_snprintf_str",          (Tcl_CmdProc*)sqlite3_snprintf_str   },
      { "sqlite3_mprintf_stronly",       (Tcl_CmdProc*)sqlite3_mprintf_stronly},
      { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
      { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
@@ -4146,6 +4258,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_clear_tsd_memdebug",    test_clear_tsd_memdebug, 0},
      { "sqlite3_tsd_release",           test_tsd_release,        0},
      { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
+     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},
 
      { "sqlite3_load_extension",        test_load_extension,     0},
      { "sqlite3_enable_load_extension", test_enable_load,        0},
@@ -4220,10 +4333,11 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
   extern int sqlite3_sync_count, sqlite3_fullsync_count;
   extern int sqlite3_opentemp_count;
   extern int sqlite3_memUsed;
-  extern int sqlite3_malloc_id;
+  extern char *sqlite3_malloc_id;
   extern int sqlite3_memMax;
   extern int sqlite3_like_count;
   extern int sqlite3_tsd_count;
+  extern int sqlite3_xferopt_count;
 #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE
   extern int threadsOverrideEachOthersLocks;
 #endif
@@ -4261,6 +4375,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
       (char*)&sqlite3_os_trace, TCL_LINK_INT);
   Tcl_LinkVar(interp, "sqlite3_tsd_count",
       (char*)&sqlite3_tsd_count, TCL_LINK_INT);
+  Tcl_LinkVar(interp, "sqlite3_xferopt_count",
+      (char*)&sqlite3_xferopt_count, TCL_LINK_INT);
 #ifndef SQLITE_OMIT_UTF16
   Tcl_LinkVar(interp, "unaligned_string_counter",
       (char*)&unaligned_string_counter, TCL_LINK_INT);
index 80e57cd87e6e5eb13da197013b34c17c4ac52dcf..9be8a58bafce6170d938f93e6303c752ad3fc02b 100644 (file)
@@ -78,13 +78,13 @@ static int pager_open(
     return TCL_ERROR;
   }
   if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
-  rc = sqlite3pager_open(&pPager, argv[1], 0, 0);
+  rc = sqlite3PagerOpen(&pPager, argv[1], 0, 0);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
   }
-  sqlite3pager_set_cachesize(pPager, nPage);
-  sqlite3pager_set_pagesize(pPager, test_pagesize);
+  sqlite3PagerSetCachesize(pPager, nPage);
+  sqlite3PagerSetPagesize(pPager, test_pagesize);
   sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPager);
   Tcl_AppendResult(interp, zBuf, 0);
   return TCL_OK;
@@ -109,7 +109,7 @@ static int pager_close(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_close(pPager);
+  rc = sqlite3PagerClose(pPager);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -136,7 +136,7 @@ static int pager_rollback(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_rollback(pPager);
+  rc = sqlite3PagerRollback(pPager);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -163,7 +163,12 @@ static int pager_commit(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_commit(pPager);
+  rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0);
+  if( rc!=SQLITE_OK ){
+    Tcl_AppendResult(interp, errorName(rc), 0);
+    return TCL_ERROR;
+  }
+  rc = sqlite3PagerCommitPhaseTwo(pPager);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -190,7 +195,7 @@ static int pager_stmt_begin(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_stmt_begin(pPager);
+  rc = sqlite3PagerStmtBegin(pPager);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -217,7 +222,7 @@ static int pager_stmt_rollback(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_stmt_rollback(pPager);
+  rc = sqlite3PagerStmtRollback(pPager);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -244,7 +249,7 @@ static int pager_stmt_commit(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_stmt_commit(pPager);
+  rc = sqlite3PagerStmtCommit(pPager);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -271,7 +276,7 @@ static int pager_stats(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  a = sqlite3pager_stats(pPager);
+  a = sqlite3PagerStats(pPager);
   for(i=0; i<9; i++){
     static char *zName[] = {
       "ref", "page", "max", "size", "state", "err",
@@ -304,7 +309,7 @@ static int pager_pagecount(
     return TCL_ERROR;
   }
   pPager = sqlite3TextToPtr(argv[1]);
-  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",sqlite3pager_pagecount(pPager));
+  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",sqlite3PagerPagecount(pPager));
   Tcl_AppendResult(interp, zBuf, 0);
   return TCL_OK;
 }
@@ -322,7 +327,7 @@ static int page_get(
 ){
   Pager *pPager;
   char zBuf[100];
-  void *pPage;
+  DbPage *pPage;
   int pgno;
   int rc;
   if( argc!=3 ){
@@ -332,7 +337,7 @@ static int page_get(
   }
   pPager = sqlite3TextToPtr(argv[1]);
   if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
-  rc = sqlite3pager_get(pPager, pgno, &pPage);
+  rc = sqlite3PagerGet(pPager, pgno, &pPage);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -356,7 +361,7 @@ static int page_lookup(
 ){
   Pager *pPager;
   char zBuf[100];
-  void *pPage;
+  DbPage *pPage;
   int pgno;
   if( argc!=3 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
@@ -365,7 +370,7 @@ static int page_lookup(
   }
   pPager = sqlite3TextToPtr(argv[1]);
   if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
-  pPage = sqlite3pager_lookup(pPager, pgno);
+  pPage = sqlite3PagerLookup(pPager, pgno);
   if( pPage ){
     sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
     Tcl_AppendResult(interp, zBuf, 0);
@@ -392,7 +397,7 @@ static int pager_truncate(
   }
   pPager = sqlite3TextToPtr(argv[1]);
   if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
-  rc = sqlite3pager_truncate(pPager, pgno);
+  rc = sqlite3PagerTruncate(pPager, pgno);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -412,15 +417,15 @@ static int page_unref(
   int argc,              /* Number of arguments */
   const char **argv      /* Text of each argument */
 ){
-  void *pPage;
+  DbPage *pPage;
   int rc;
   if( argc!=2 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
        " PAGE\"", 0);
     return TCL_ERROR;
   }
-  pPage = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_unref(pPage);
+  pPage = (DbPage *)sqlite3TextToPtr(argv[1]);
+  rc = sqlite3PagerUnref(pPage);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -440,14 +445,14 @@ static int page_read(
   const char **argv      /* Text of each argument */
 ){
   char zBuf[100];
-  void *pPage;
+  DbPage *pPage;
   if( argc!=2 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
        " PAGE\"", 0);
     return TCL_ERROR;
   }
   pPage = sqlite3TextToPtr(argv[1]);
-  memcpy(zBuf, pPage, sizeof(zBuf));
+  memcpy(zBuf, sqlite3PagerGetData(pPage), sizeof(zBuf));
   Tcl_AppendResult(interp, zBuf, 0);
   return TCL_OK;
 }
@@ -464,14 +469,14 @@ static int page_number(
   const char **argv      /* Text of each argument */
 ){
   char zBuf[100];
-  void *pPage;
+  DbPage *pPage;
   if( argc!=2 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
        " PAGE\"", 0);
     return TCL_ERROR;
   }
-  pPage = sqlite3TextToPtr(argv[1]);
-  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3pager_pagenumber(pPage));
+  pPage = (DbPage *)sqlite3TextToPtr(argv[1]);
+  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3PagerPagenumber(pPage));
   Tcl_AppendResult(interp, zBuf, 0);
   return TCL_OK;
 }
@@ -487,21 +492,23 @@ static int page_write(
   int argc,              /* Number of arguments */
   const char **argv      /* Text of each argument */
 ){
-  void *pPage;
+  DbPage *pPage;
+  char *pData;
   int rc;
   if( argc!=3 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
        " PAGE DATA\"", 0);
     return TCL_ERROR;
   }
-  pPage = sqlite3TextToPtr(argv[1]);
-  rc = sqlite3pager_write(pPage);
+  pPage = (DbPage *)sqlite3TextToPtr(argv[1]);
+  rc = sqlite3PagerWrite(pPage);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
   }
-  strncpy((char*)pPage, argv[2], test_pagesize-1);
-  ((char*)pPage)[test_pagesize-1] = 0;
+  pData = sqlite3PagerGetData(pPage);
+  strncpy(pData, argv[2], test_pagesize-1);
+  pData[test_pagesize-1] = 0;
   return TCL_OK;
 }
 
@@ -558,10 +565,12 @@ static int fake_big_file(
 ** Register commands with the TCL interpreter.
 */
 int Sqlitetest2_Init(Tcl_Interp *interp){
+  extern int sqlite3_io_error_persist;
   extern int sqlite3_io_error_pending;
   extern int sqlite3_io_error_hit;
   extern int sqlite3_diskfull_pending;
   extern int sqlite3_diskfull;
+  extern int sqlite3_pager_n_sort_bucket;
   static struct {
     char *zName;
     Tcl_CmdProc *xProc;
@@ -592,6 +601,8 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
   }
   Tcl_LinkVar(interp, "sqlite_io_error_pending",
      (char*)&sqlite3_io_error_pending, TCL_LINK_INT);
+  Tcl_LinkVar(interp, "sqlite_io_error_persist",
+     (char*)&sqlite3_io_error_persist, TCL_LINK_INT);
   Tcl_LinkVar(interp, "sqlite_io_error_hit",
      (char*)&sqlite3_io_error_hit, TCL_LINK_INT);
   Tcl_LinkVar(interp, "sqlite_diskfull_pending",
@@ -602,5 +613,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
      (char*)&sqlite3_pending_byte, TCL_LINK_INT);
   Tcl_LinkVar(interp, "pager_pagesize",
      (char*)&test_pagesize, TCL_LINK_INT);
+  Tcl_LinkVar(interp, "sqlite_pager_n_sort_bucket",
+     (char*)&sqlite3_pager_n_sort_bucket, TCL_LINK_INT);
   return TCL_OK;
 }
index 5483abaf75b950fa088486a3a969b627f1158f0d..f2540cacd96cda526558a2c6b818087fdbc6d1ec 100644 (file)
@@ -511,7 +511,7 @@ static int btree_pager_stats(
     return TCL_ERROR;
   }
   pBt = sqlite3TextToPtr(argv[1]);
-  a = sqlite3pager_stats(sqlite3BtreePager(pBt));
+  a = sqlite3PagerStats(sqlite3BtreePager(pBt));
   for(i=0; i<11; i++){
     static char *zName[] = {
       "ref", "page", "max", "size", "state", "err",
@@ -545,7 +545,7 @@ static int btree_pager_ref_dump(
   }
   pBt = sqlite3TextToPtr(argv[1]);
 #ifdef SQLITE_DEBUG
-  sqlite3pager_refdump(sqlite3BtreePager(pBt));
+  sqlite3PagerRefdump(sqlite3BtreePager(pBt));
 #endif
   return TCL_OK;
 }
@@ -706,9 +706,9 @@ static int btree_move_to(
   if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
     int iKey;
     if( Tcl_GetInt(interp, argv[2], &iKey) ) return TCL_ERROR;
-    rc = sqlite3BtreeMoveto(pCur, 0, iKey, &res);
+    rc = sqlite3BtreeMoveto(pCur, 0, iKey, 0, &res);
   }else{
-    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);  
+    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), 0, &res);  
   }
   if( rc ){
     Tcl_AppendResult(interp, errorName(rc), 0);
@@ -775,7 +775,7 @@ static int btree_insert(
     unsigned char *pBuf;
     if( Tcl_GetWideIntFromObj(interp, objv[2], &iKey) ) return TCL_ERROR;
     pBuf = Tcl_GetByteArrayFromObj(objv[3], &len);
-    rc = sqlite3BtreeInsert(pCur, 0, iKey, pBuf, len);
+    rc = sqlite3BtreeInsert(pCur, 0, iKey, pBuf, len, 0);
   }else{
     int keylen;
     int dlen;
@@ -783,7 +783,7 @@ static int btree_insert(
     unsigned char *pDBuf;
     pKBuf = Tcl_GetByteArrayFromObj(objv[2], &keylen);
     pDBuf = Tcl_GetByteArrayFromObj(objv[3], &dlen);
-    rc = sqlite3BtreeInsert(pCur, pKBuf, keylen, pDBuf, dlen);
+    rc = sqlite3BtreeInsert(pCur, pKBuf, keylen, pDBuf, dlen, 0);
   }
   if( rc ){
     Tcl_AppendResult(interp, errorName(rc), 0);
@@ -1229,7 +1229,7 @@ static int btree_cursor_info(
 /*
 ** Copied from btree.c:
 */
-static u32 get4byte(unsigned char *p){
+static u32 t4Get4byte(unsigned char *p){
   return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
 }
 
@@ -1282,15 +1282,17 @@ static int btree_ovfl_info(
   n = (n + dataSize - 1)/dataSize;
   pgno = (u32)aResult[10];
   while( pgno && n-- ){
+    DbPage *pDbPage;
     sprintf(zElem, "%d", pgno);
     Tcl_DStringAppendElement(&str, zElem);
-    if( sqlite3pager_get(pPager, pgno, &pPage)!=SQLITE_OK ){
+    if( sqlite3PagerGet(pPager, pgno, &pDbPage)!=SQLITE_OK ){
       Tcl_DStringFree(&str);
       Tcl_AppendResult(interp, "unable to get page ", zElem, 0);
       return TCL_ERROR;
     }
-    pgno = get4byte((unsigned char*)pPage);
-    sqlite3pager_unref(pPage);
+    pPage = sqlite3PagerGetData(pDbPage);
+    pgno = t4Get4byte((unsigned char*)pPage);
+    sqlite3PagerUnref(pDbPage);
   }
   Tcl_DStringResult(interp, &str);
   return SQLITE_OK;
index a6eabbf62a096357564be2298fa2ed996f602a06..4a929adde0cab8a6f73614d543fbc782fae24749 100644 (file)
@@ -47,7 +47,6 @@ void sqlite3BeginTrigger(
   int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
   IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
   SrcList *pTableName,/* The name of the table/view the trigger applies to */
-  int foreach,        /* One of TK_ROW or TK_STATEMENT */
   Expr *pWhen,        /* WHEN clause */
   int isTemp,         /* True if the TEMPORARY keyword is present */
   int noErr           /* Suppress errors if the trigger already exists */
@@ -180,7 +179,6 @@ void sqlite3BeginTrigger(
   pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
   pTrigger->pWhen = sqlite3ExprDup(pWhen);
   pTrigger->pColumns = sqlite3IdListDup(pColumns);
-  pTrigger->foreach = foreach;
   sqlite3TokenCopy(&pTrigger->nameToken,pName);
   assert( pParse->pNewTrigger==0 );
   pParse->pNewTrigger = pTrigger;
@@ -390,7 +388,11 @@ TriggerStep *sqlite3TriggerUpdateStep(
   int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
 ){
   TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
-  if( pTriggerStep==0 ) return 0;
+  if( pTriggerStep==0 ){
+     sqlite3ExprListDelete(pEList);
+     sqlite3ExprDelete(pWhere);
+     return 0;
+  }
 
   pTriggerStep->op = TK_UPDATE;
   pTriggerStep->target  = *pTableName;
@@ -409,7 +411,10 @@ TriggerStep *sqlite3TriggerUpdateStep(
 */
 TriggerStep *sqlite3TriggerDeleteStep(Token *pTableName, Expr *pWhere){
   TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
-  if( pTriggerStep==0 ) return 0;
+  if( pTriggerStep==0 ){
+    sqlite3ExprDelete(pWhere);
+    return 0;
+  }
 
   pTriggerStep->op = TK_DELETE;
   pTriggerStep->target  = *pTableName;
index f1cd038b217fd0976fd7305bebfaccf35ddfd910..07647a3d56de78ee0507f15d5a826bd59301b69b 100644 (file)
@@ -465,7 +465,7 @@ void sqlite3Update(
 
     /* Create the new index entries and the new record.
     */
-    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1);
+    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1, 0);
   }
 
   /* Increment the row counter 
@@ -617,6 +617,7 @@ static void updateVirtualTable(
   sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, 
                      (const char*)pTab->pVtab, P3_VTAB);
   sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr);
+  sqlite3VdbeJumpHere(v, addr-1);
   sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0);
 
   /* Cleanup */
index 6b78a6dee6621412205dfa6810b18d7e76addbf6..58c9647598c741a9631bdea786e0bbd89aaa04f9 100644 (file)
 #include <assert.h>
 #include "vdbeInt.h"
 
+/*
+** The following constant value is used by the SQLITE_BIGENDIAN and
+** SQLITE_LITTLEENDIAN macros.
+*/
+const int sqlite3one = 1;
+
 /*
 ** This table maps from the first byte of a UTF-8 character to the number
 ** of trailing bytes expected. A value '4' indicates that the table key
index bdb381d4b7807c1be6cf22ec461fe96c2e0c280d..d95a8828b9f56371c788750389f32815384c731d 100644 (file)
@@ -83,7 +83,7 @@ void sqlite3_soft_heap_limit(int n){
 ** Release memory held by SQLite instances created by the current thread.
 */
 int sqlite3_release_memory(int n){
-  return sqlite3pager_release_memory(n);
+  return sqlite3PagerReleaseMemory(n);
 }
 #else
 /* If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, then define a version
@@ -661,12 +661,13 @@ void *sqlite3Malloc(int n, int doMemManage){
   }
   return p;
 }
-void sqlite3ReallocOrFree(void **pp, int n){
-  void *p = sqlite3Realloc(*pp, n);
-  if( !p ){
-    sqlite3FreeX(*pp);
+void *sqlite3ReallocOrFree(void *p, int n){
+  void *pNew;
+  pNew = sqlite3Realloc(p, n);
+  if( !pNew ){
+    sqlite3FreeX(p);
   }
-  *pp = p;
+  return pNew;
 }
 
 /*
@@ -750,7 +751,7 @@ void sqlite3SetString(char **pz, ...){
   const char *z;
   char *zResult;
 
-  if( pz==0 ) return;
+  assert( pz!=0 );
   nByte = 1;
   va_start(ap, pz);
   while( (z = va_arg(ap, const char*))!=0 ){
@@ -1132,6 +1133,13 @@ int sqlite3FitsIn64Bits(const char *zNum){
 ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
 ** when this routine is called.
 **
+** This routine is called when entering an SQLite API.  The SQLITE_MAGIC_OPEN
+** value indicates that the database connection passed into the API is
+** open and is not being used by another thread.  By changing the value
+** to SQLITE_MAGIC_BUSY we indicate that the connection is in use.
+** sqlite3SafetyOff() below will change the value back to SQLITE_MAGIC_OPEN
+** when the API exits. 
+**
 ** This routine is a attempt to detect if two threads use the
 ** same sqlite* pointer at the same time.  There is a race 
 ** condition so it is possible that the error is not detected.
@@ -1165,11 +1173,11 @@ int sqlite3SafetyOff(sqlite3 *db){
   if( db->magic==SQLITE_MAGIC_BUSY ){
     db->magic = SQLITE_MAGIC_OPEN;
     return 0;
-  }else if( db->magic==SQLITE_MAGIC_OPEN ){
+  }else {
     db->magic = SQLITE_MAGIC_ERROR;
     db->u1.isInterrupted = 1;
+    return 1;
   }
-  return 1;
 }
 
 /*
@@ -1384,11 +1392,11 @@ void *sqlite3TextToPtr(const char *z){
     z++;
   }
   if( sizeof(p)==sizeof(v) ){
-    p = *(void**)&v;
+    memcpy(&p, &v, sizeof(p));
   }else{
     assert( sizeof(p)==sizeof(v2) );
     v2 = (u32)v;
-    p = *(void**)&v2;
+    memcpy(&p, &v2, sizeof(p));
   }
   return p;
 }
@@ -1461,9 +1469,11 @@ int sqlite3MallocFailed(){
 ** Set the "malloc has failed" condition to true for this thread.
 */
 void sqlite3FailedMalloc(){
-  sqlite3OsEnterMutex();
-  assert( mallocHasFailed==0 );
-  mallocHasFailed = 1;
+  if( !sqlite3MallocFailed() ){
+    sqlite3OsEnterMutex();
+    assert( mallocHasFailed==0 );
+    mallocHasFailed = 1;
+  }
 }
 
 #ifdef SQLITE_MEMDEBUG
index 07f62ae77f6248610079c0638d217507e8a00400..3f40573827882ade7e4877da3a0a77842d931b50 100644 (file)
@@ -20,7 +20,7 @@
 #include "vdbeInt.h"
 #include "os.h"
 
-#ifndef SQLITE_OMIT_VACUUM
+#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
 /*
 ** Execute zSql on database db. Return an error code.
 */
@@ -83,13 +83,11 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   char *zSql = 0;         /* SQL statements */
   int saved_flags;        /* Saved value of the db->flags */
   Db *pDb = 0;            /* Database to detach at end of vacuum */
-  char zTemp[SQLITE_TEMPNAME_SIZE+20];  /* Name of the TEMP file */
 
   /* Save the current value of the write-schema flag before setting it. */
   saved_flags = db->flags;
   db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
 
-  sqlite3OsTempFileName(zTemp);
   if( !db->autoCommit ){
     sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
        (char*)0);
@@ -106,20 +104,18 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   **
   ** An optimisation would be to use a non-journaled pager.
   */
-  zSql = sqlite3MPrintf("ATTACH '%q' AS vacuum_db;", zTemp);
-  if( !zSql ){
-    rc = SQLITE_NOMEM;
-    goto end_of_vacuum;
-  }
+  zSql = "ATTACH '' AS vacuum_db;";
   rc = execSql(db, zSql);
-  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));
+  if( sqlite3MallocFailed() ){
+    rc = SQLITE_NOMEM;
+    goto end_of_vacuum;
+  }
   assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
   rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
   if( rc!=SQLITE_OK ){
@@ -259,12 +255,8 @@ end_of_vacuum:
     pDb->pSchema = 0;
   }
 
-  sqlite3OsDelete(zTemp);
-  strcat(zTemp, "-journal");
-  sqlite3OsDelete(zTemp);
-  sqliteFree( zSql );
   sqlite3ResetInternalSchema(db, 0);
 
   return rc;
 }
-#endif  /* SQLITE_OMIT_VACUUM */
+#endif  /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
index 2e5b3957b9f3a9587a50a6abaf832617e387ab89..cab35069ccb31fdc4b22a868724acf95756df7c2 100644 (file)
@@ -211,7 +211,7 @@ static void applyNumericAffinity(Mem *pRec){
       sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
       if( !realnum && sqlite3atoi64(pRec->z, &value) ){
         sqlite3VdbeMemRelease(pRec);
-        pRec->i = value;
+        pRec->u.i = value;
         pRec->flags = MEM_Int;
       }else{
         sqlite3VdbeMemRealify(pRec);
@@ -454,6 +454,7 @@ int sqlite3VdbeExec(
   p->resOnStack = 0;
   db->busyHandler.nBusy = 0;
   CHECK_FOR_INTERRUPT;
+  sqlite3VdbeIOTraceSql(p);
 #ifdef SQLITE_DEBUG
   if( (p->db->flags & SQLITE_VdbeListing)!=0
     || sqlite3OsFileExists("vdbe_explain")
@@ -669,7 +670,7 @@ case OP_Halt: {            /* no-push */
 case OP_Integer: {
   pTos++;
   pTos->flags = MEM_Int;
-  pTos->i = pOp->p1;
+  pTos->u.i = pOp->p1;
   break;
 }
 
@@ -685,7 +686,7 @@ case OP_Int64: {
   pTos->z = pOp->p3;
   pTos->n = strlen(pTos->z);
   pTos->enc = SQLITE_UTF8;
-  pTos->i = sqlite3VdbeIntValue(pTos);
+  pTos->u.i = sqlite3VdbeIntValue(pTos);
   pTos->flags |= MEM_Int;
   break;
 }
@@ -1098,8 +1099,8 @@ case OP_Remainder: {           /* same as TK_REM, no-push */
     pTos->flags = MEM_Null;
   }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
     i64 a, b;
-    a = pTos->i;
-    b = pNos->i;
+    a = pTos->u.i;
+    b = pNos->u.i;
     switch( pOp->opcode ){
       case OP_Add:         b += a;       break;
       case OP_Subtract:    b -= a;       break;
@@ -1118,7 +1119,7 @@ case OP_Remainder: {           /* same as TK_REM, no-push */
     Release(pTos);
     pTos--;
     Release(pTos);
-    pTos->i = b;
+    pTos->u.i = b;
     pTos->flags = MEM_Int;
   }else{
     double a, b;
@@ -1309,7 +1310,7 @@ case OP_ShiftRight: {           /* same as TK_RSHIFT, no-push */
   Release(pTos);
   pTos--;
   Release(pTos);
-  pTos->i = a;
+  pTos->u.i = a;
   pTos->flags = MEM_Int;
   break;
 }
@@ -1324,7 +1325,7 @@ case OP_ShiftRight: {           /* same as TK_RSHIFT, no-push */
 case OP_AddImm: {            /* no-push */
   assert( pTos>=p->aStack );
   sqlite3VdbeMemIntegerify(pTos);
-  pTos->i += pOp->p1;
+  pTos->u.i += pOp->p1;
   break;
 }
 
@@ -1349,7 +1350,7 @@ case OP_ForceInt: {            /* no-push */
     break;
   }
   if( pTos->flags & MEM_Int ){
-    v = pTos->i + (pOp->p1!=0);
+    v = pTos->u.i + (pOp->p1!=0);
   }else{
     /* FIX ME:  should this not be assert( pTos->flags & MEM_Real ) ??? */
     sqlite3VdbeMemRealify(pTos);
@@ -1358,7 +1359,7 @@ case OP_ForceInt: {            /* no-push */
     if( pOp->p1 && pTos->r==(double)v ) v++;
   }
   Release(pTos);
-  pTos->i = v;
+  pTos->u.i = v;
   pTos->flags = MEM_Int;
   break;
 }
@@ -1647,7 +1648,7 @@ case OP_Ge: {             /* same as TK_GE, no-push */
   }else{
     pTos++;
     pTos->flags = MEM_Int;
-    pTos->i = res;
+    pTos->u.i = res;
   }
   break;
 }
@@ -1674,13 +1675,13 @@ case OP_Or: {             /* same as TK_OR, no-push */
     v1 = 2;
   }else{
     sqlite3VdbeMemIntegerify(pTos);
-    v1 = pTos->i==0;
+    v1 = pTos->u.i==0;
   }
   if( pNos->flags & MEM_Null ){
     v2 = 2;
   }else{
     sqlite3VdbeMemIntegerify(pNos);
-    v2 = pNos->i==0;
+    v2 = pNos->u.i==0;
   }
   if( pOp->opcode==OP_And ){
     static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
@@ -1694,7 +1695,7 @@ case OP_Or: {             /* same as TK_OR, no-push */
   if( v1==2 ){
     pTos->flags = MEM_Null;
   }else{
-    pTos->i = v1==0;
+    pTos->u.i = v1==0;
     pTos->flags = MEM_Int;
   }
   break;
@@ -1724,8 +1725,8 @@ case OP_AbsValue: {
     pTos->flags = MEM_Real;
   }else if( pTos->flags & MEM_Int ){
     Release(pTos);
-    if( pOp->opcode==OP_Negative || pTos->i<0 ){
-      pTos->i = -pTos->i;
+    if( pOp->opcode==OP_Negative || pTos->u.i<0 ){
+      pTos->u.i = -pTos->u.i;
     }
     pTos->flags = MEM_Int;
   }else if( pTos->flags & MEM_Null ){
@@ -1748,7 +1749,7 @@ case OP_Not: {                /* same as TK_NOT, no-push */
   if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
   sqlite3VdbeMemIntegerify(pTos);
   assert( (pTos->flags & MEM_Dyn)==0 );
-  pTos->i = !pTos->i;
+  pTos->u.i = !pTos->u.i;
   pTos->flags = MEM_Int;
   break;
 }
@@ -1764,7 +1765,7 @@ case OP_BitNot: {             /* same as TK_BITNOT, no-push */
   if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
   sqlite3VdbeMemIntegerify(pTos);
   assert( (pTos->flags & MEM_Dyn)==0 );
-  pTos->i = ~pTos->i;
+  pTos->u.i = ~pTos->u.i;
   pTos->flags = MEM_Int;
   break;
 }
@@ -1936,6 +1937,9 @@ case OP_Column: {
   ** which is the number of records.
   */
   pC = p->apCsr[p1];
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+  assert( pC->pVtabCursor==0 );
+#endif
   assert( pC!=0 );
   if( pC->pCursor!=0 ){
     /* The record is stored in a B-Tree */
@@ -2445,7 +2449,7 @@ case OP_ReadCookie: {
   */
   rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1 + pOp->p2, (u32 *)&iMeta);
   pTos++;
-  pTos->i = iMeta;
+  pTos->u.i = iMeta;
   pTos->flags = MEM_Int;
   break;
 }
@@ -2469,14 +2473,14 @@ case OP_SetCookie: {       /* no-push */
   assert( pTos>=p->aStack );
   sqlite3VdbeMemIntegerify(pTos);
   /* See note about index shifting on OP_ReadCookie */
-  rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i);
+  rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->u.i);
   if( pOp->p2==0 ){
     /* When the schema cookie changes, record the new cookie internally */
-    pDb->pSchema->schema_cookie = pTos->i;
+    pDb->pSchema->schema_cookie = pTos->u.i;
     db->flags |= SQLITE_InternChanges;
   }else if( pOp->p2==1 ){
     /* Record changes in the file format */
-    pDb->pSchema->file_format = pTos->i;
+    pDb->pSchema->file_format = pTos->u.i;
   }
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
@@ -2578,7 +2582,7 @@ case OP_OpenWrite: {       /* no-push */
   
   assert( pTos>=p->aStack );
   sqlite3VdbeMemIntegerify(pTos);
-  iDb = pTos->i;
+  iDb = pTos->u.i;
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
   assert( iDb>=0 && iDb<db->nDb );
@@ -2596,7 +2600,7 @@ case OP_OpenWrite: {       /* no-push */
   if( p2<=0 ){
     assert( pTos>=p->aStack );
     sqlite3VdbeMemIntegerify(pTos);
-    p2 = pTos->i;
+    p2 = pTos->u.i;
     assert( (pTos->flags & MEM_Dyn)==0 );
     pTos--;
     assert( p2>=2 );
@@ -2822,7 +2826,7 @@ case OP_MoveGt: {       /* no-push */
     if( pC->isTable ){
       i64 iKey;
       sqlite3VdbeMemIntegerify(pTos);
-      iKey = intToKey(pTos->i);
+      iKey = intToKey(pTos->u.i);
       if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){
         pC->movetoTarget = iKey;
         pC->deferredMoveto = 1;
@@ -2830,16 +2834,16 @@ case OP_MoveGt: {       /* no-push */
         pTos--;
         break;
       }
-      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
+      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, 0, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      pC->lastRowid = pTos->i;
+      pC->lastRowid = pTos->u.i;
       pC->rowidIsValid = res==0;
     }else{
       assert( pTos->flags & MEM_Blob );
       /* Stringify(pTos, encoding); */
-      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
@@ -2946,7 +2950,7 @@ case OP_Found: {        /* no-push */
     int res, rx;
     assert( pC->isTable==0 );
     Stringify(pTos, encoding);
-    rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+    rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
     alreadyExists = rx==SQLITE_OK && res==0;
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
@@ -2995,7 +2999,7 @@ case OP_IsUnique: {        /* no-push */
   */
   assert( pNos>=p->aStack );
   sqlite3VdbeMemIntegerify(pTos);
-  R = pTos->i;
+  R = pTos->u.i;
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
   assert( i>=0 && i<p->nCursor );
@@ -3024,7 +3028,7 @@ case OP_IsUnique: {        /* no-push */
     */
     assert( pCx->deferredMoveto==0 );
     pCx->cacheStatus = CACHE_STALE;
-    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
+    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, 0, &res);
     if( rc!=SQLITE_OK ){
       goto abort_due_to_error;
     }
@@ -3061,7 +3065,7 @@ case OP_IsUnique: {        /* no-push */
     ** constraint.)
     */
     pTos++;
-    pTos->i = v;
+    pTos->u.i = v;
     pTos->flags = MEM_Int;
   }
   break;
@@ -3093,15 +3097,17 @@ case OP_NotExists: {        /* no-push */
     u64 iKey;
     assert( pTos->flags & MEM_Int );
     assert( p->apCsr[i]->isTable );
-    iKey = intToKey(pTos->i);
-    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
-    pC->lastRowid = pTos->i;
+    iKey = intToKey(pTos->u.i);
+    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, 0,&res);
+    pC->lastRowid = pTos->u.i;
     pC->rowidIsValid = res==0;
     pC->nullRow = 0;
     pC->cacheStatus = CACHE_STALE;
     /* res might be uninitialized if rc!=SQLITE_OK.  But if rc!=SQLITE_OK
     ** processing is about to abort so we really do not care whether or not
-    ** the following jump is taken. */
+    ** the following jump is taken.  (In other words, do not stress over
+    ** the error that valgrind sometimes shows on the next statement when
+    ** running ioerr.test and similar failure-recovery test scripts.) */
     if( res!=0 ){
       pc = pOp->p2 - 1;
       pC->rowidIsValid = 0;
@@ -3124,7 +3130,7 @@ case OP_Sequence: {
   assert( i>=0 && i<p->nCursor );
   assert( p->apCsr[i]!=0 );
   pTos++;
-  pTos->i = p->apCsr[i]->seqCount++;
+  pTos->u.i = p->apCsr[i]->seqCount++;
   pTos->flags = MEM_Int;
   break;
 }
@@ -3233,14 +3239,14 @@ case OP_NewRowid: {
         pMem = &p->aMem[pOp->p2];
         sqlite3VdbeMemIntegerify(pMem);
         assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P2) holds an integer */
-        if( pMem->i==MAX_ROWID || pC->useRandomRowid ){
+        if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
           rc = SQLITE_FULL;
           goto abort_due_to_error;
         }
-        if( v<pMem->i+1 ){
-          v = pMem->i + 1;
+        if( v<pMem->u.i+1 ){
+          v = pMem->u.i + 1;
         }
-        pMem->i = v;
+        pMem->u.i = v;
       }
 #endif
 
@@ -3266,7 +3272,7 @@ case OP_NewRowid: {
         }
         if( v==0 ) continue;
         x = intToKey(v);
-        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, &res);
+        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, 0, &res);
         cnt++;
       }while( cnt<1000 && rx==SQLITE_OK && res==0 );
       db->priorNewRowid = v;
@@ -3280,7 +3286,7 @@ case OP_NewRowid: {
     pC->cacheStatus = CACHE_STALE;
   }
   pTos++;
-  pTos->i = v;
+  pTos->u.i = v;
   pTos->flags = MEM_Int;
   break;
 }
@@ -3317,11 +3323,11 @@ case OP_Insert: {         /* no-push */
 
     assert( pNos->flags & MEM_Int );
     assert( pC->isTable );
-    iKey = intToKey(pNos->i);
+    iKey = intToKey(pNos->u.i);
 
     if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
-    if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
-    if( pC->nextRowidValid && pNos->i>=pC->nextRowid ){
+    if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->u.i;
+    if( pC->nextRowidValid && pNos->u.i>=pC->nextRowid ){
       pC->nextRowidValid = 0;
     }
     if( pTos->flags & MEM_Null ){
@@ -3346,7 +3352,9 @@ case OP_Insert: {         /* no-push */
       }
       pC->nullRow = 0;
     }else{
-      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
+      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
+                              pTos->z, pTos->n,
+                              pOp->p2 & OPFLAG_APPEND);
     }
     
     pC->rowidIsValid = 0;
@@ -3500,9 +3508,9 @@ case OP_RowData: {
       pTos->z = z;
     }
     if( pC->isIndex ){
-      sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
+      rc = sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
     }else{
-      sqlite3BtreeData(pCrsr, 0, n, pTos->z);
+      rc = sqlite3BtreeData(pCrsr, 0, n, pTos->z);
     }
   }else if( pC->pseudoTable ){
     pTos->n = pC->nData;
@@ -3543,7 +3551,7 @@ case OP_Rowid: {
     sqlite3BtreeKeySize(pC->pCursor, &v);
     v = keyToInt(v);
   }
-  pTos->i = v;
+  pTos->u.i = v;
   pTos->flags = MEM_Int;
   break;
 }
@@ -3673,7 +3681,9 @@ case OP_Next: {        /* no-push */
   CHECK_FOR_INTERRUPT;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
-  assert( pC!=0 );
+  if( pC==0 ){
+    break;  /* See ticket #2273 */
+  }
   if( (pCrsr = pC->pCursor)!=0 ){
     int res;
     if( pC->nullRow ){
@@ -3698,12 +3708,15 @@ case OP_Next: {        /* no-push */
   break;
 }
 
-/* Opcode: IdxInsert P1 * *
+/* Opcode: IdxInsert P1 P2 *
 **
 ** 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.
 **
+** P2 is a flag that provides a hint to the b-tree layer that this
+** insert is likely to be an append.
+**
 ** This instruction only works for indices.  The equivalent instruction
 ** for tables is OP_Insert.
 */
@@ -3715,12 +3728,11 @@ case OP_IdxInsert: {        /* no-push */
   assert( i>=0 && i<p->nCursor );
   assert( p->apCsr[i]!=0 );
   assert( pTos->flags & MEM_Blob );
-  assert( pOp->p2==0 );
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
     int nKey = pTos->n;
     const char *zKey = pTos->z;
     assert( pC->isTable==0 );
-    rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
+    rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, pOp->p2);
     assert( pC->deferredMoveto==0 );
     pC->cacheStatus = CACHE_STALE;
   }
@@ -3745,7 +3757,7 @@ case OP_IdxDelete: {        /* no-push */
   assert( p->apCsr[i]!=0 );
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
     int res;
-    rc = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
+    rc = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, 0, &res);
     if( rc==SQLITE_OK && res==0 ){
       rc = sqlite3BtreeDelete(pCrsr);
     }
@@ -3787,7 +3799,7 @@ case OP_IdxRowid: {
         goto abort_due_to_error;
       }
       pTos->flags = MEM_Int;
-      pTos->i = rowid;
+      pTos->u.i = rowid;
     }
   }
   break;
@@ -3914,7 +3926,7 @@ case OP_Destroy: {
     rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1, &iMoved);
     pTos++;
     pTos->flags = MEM_Int;
-    pTos->i = iMoved;
+    pTos->u.i = iMoved;
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( rc==SQLITE_OK && iMoved!=0 ){
       sqlite3RootPageMoved(&db->aDb[pOp->p2], iMoved, pOp->p1);
@@ -4013,7 +4025,7 @@ case OP_CreateTable: {
   rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
   pTos++;
   if( rc==SQLITE_OK ){
-    pTos->i = pgno;
+    pTos->u.i = pgno;
     pTos->flags = MEM_Int;
   }else{
     pTos->flags = MEM_Null;
@@ -4160,14 +4172,14 @@ case OP_IntegrityCk: {
   assert( (pnErr->flags & MEM_Int)!=0 );
   for(j=0; j<nRoot; j++){
     Mem *pMem = &pTos[-j];
-    aRoot[j] = pMem->i;
+    aRoot[j] = pMem->u.i;
   }
   aRoot[j] = 0;
   popStack(&pTos, nRoot);
   pTos++;
   z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot,
-                                 pnErr->i, &nErr);
-  pnErr->i -= nErr;
+                                 pnErr->u.i, &nErr);
+  pnErr->u.i -= nErr;
   if( nErr==0 ){
     assert( z==0 );
     pTos->flags = MEM_Null;
@@ -4192,7 +4204,7 @@ case OP_IntegrityCk: {
 case OP_FifoWrite: {        /* no-push */
   assert( pTos>=p->aStack );
   sqlite3VdbeMemIntegerify(pTos);
-  sqlite3VdbeFifoPush(&p->sFifo, pTos->i);
+  sqlite3VdbeFifoPush(&p->sFifo, pTos->u.i);
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
   break;
@@ -4211,7 +4223,7 @@ case OP_FifoRead: {
     pc = pOp->p2 - 1;
   }else{
     pTos++;
-    pTos->i = v;
+    pTos->u.i = v;
     pTos->flags = MEM_Int;
   }
   break;
@@ -4232,7 +4244,8 @@ case OP_ContextPush: {        /* no-push */
   /* FIX ME: This should be allocated as part of the vdbe at compile-time */
   if( i>=p->contextStackDepth ){
     p->contextStackDepth = i+1;
-    sqliteReallocOrFree((void**)&p->contextStack, sizeof(Context)*(i+1));
+    p->contextStack = sqliteReallocOrFree(p->contextStack,
+                                          sizeof(Context)*(i+1));
     if( p->contextStack==0 ) goto no_mem;
   }
   pContext = &p->contextStack[i];
@@ -4317,8 +4330,8 @@ case OP_MemMax: {        /* no-push */
   pMem = &p->aMem[i];
   sqlite3VdbeMemIntegerify(pMem);
   sqlite3VdbeMemIntegerify(pTos);
-  if( pMem->i<pTos->i){
-    pMem->i = pTos->i;
+  if( pMem->u.i<pTos->u.i){
+    pMem->u.i = pTos->u.i;
   }
   break;
 }
@@ -4337,7 +4350,7 @@ case OP_MemIncr: {        /* no-push */
   assert( i>=0 && i<p->nMem );
   pMem = &p->aMem[i];
   assert( pMem->flags==MEM_Int );
-  pMem->i += pOp->p1;
+  pMem->u.i += pOp->p1;
   break;
 }
 
@@ -4354,7 +4367,7 @@ case OP_IfMemPos: {        /* no-push */
   assert( i>=0 && i<p->nMem );
   pMem = &p->aMem[i];
   assert( pMem->flags==MEM_Int );
-  if( pMem->i>0 ){
+  if( pMem->u.i>0 ){
      pc = pOp->p2 - 1;
   }
   break;
@@ -4373,7 +4386,7 @@ case OP_IfMemNeg: {        /* no-push */
   assert( i>=0 && i<p->nMem );
   pMem = &p->aMem[i];
   assert( pMem->flags==MEM_Int );
-  if( pMem->i<0 ){
+  if( pMem->u.i<0 ){
      pc = pOp->p2 - 1;
   }
   break;
@@ -4392,7 +4405,7 @@ case OP_IfMemZero: {        /* no-push */
   assert( i>=0 && i<p->nMem );
   pMem = &p->aMem[i];
   assert( pMem->flags==MEM_Int );
-  if( pMem->i==0 ){
+  if( pMem->u.i==0 ){
      pc = pOp->p2 - 1;
   }
   break;
@@ -4506,7 +4519,7 @@ case OP_AggFinal: {        /* no-push */
 }
 
 
-#ifndef SQLITE_OMIT_VACUUM
+#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
 /* Opcode: Vacuum * * *
 **
 ** Vacuum the entire database.  This opcode will cause other virtual
@@ -4679,7 +4692,7 @@ case OP_VFilter: {   /* no-push */
   /* Grab the index number and argc parameters off the top of the stack. */
   assert( (&pTos[-1])>=p->aStack );
   assert( (pTos[0].flags&MEM_Int)!=0 && pTos[-1].flags==MEM_Int );
-  nArg = pTos[-1].i;
+  nArg = pTos[-1].u.i;
 
   /* Invoke the xFilter method */
   {
@@ -4693,7 +4706,7 @@ case OP_VFilter: {   /* no-push */
 
     if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
     p->inVtabMethod = 1;
-    rc = pModule->xFilter(pCur->pVtabCursor, pTos->i, pOp->p3, nArg, apArg);
+    rc = pModule->xFilter(pCur->pVtabCursor, pTos->u.i, pOp->p3, nArg, apArg);
     p->inVtabMethod = 0;
     if( rc==SQLITE_OK ){
       res = pModule->xEof(pCur->pVtabCursor);
@@ -4735,7 +4748,7 @@ case OP_VRowid: {
 
     pTos++;
     pTos->flags = MEM_Int;
-    pTos->i = iRow;
+    pTos->u.i = iRow;
   }
 
   break;
@@ -4934,9 +4947,9 @@ default: {
         if( pTos[i].flags & MEM_Null ){
           fprintf(p->trace, " NULL");
         }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
-          fprintf(p->trace, " si:%lld", pTos[i].i);
+          fprintf(p->trace, " si:%lld", pTos[i].u.i);
         }else if( pTos[i].flags & MEM_Int ){
-          fprintf(p->trace, " i:%lld", pTos[i].i);
+          fprintf(p->trace, " i:%lld", pTos[i].u.i);
         }else if( pTos[i].flags & MEM_Real ){
           fprintf(p->trace, " r:%g", pTos[i].r);
         }else{
index d2f737c990349941b80f2df1c471d0ef506ab94c..11c906100c1f2fd300d2316e178f666ab752e9db 100644 (file)
@@ -31,7 +31,7 @@
 ** array is defined in a separate source code file named opcode.c which is
 ** automatically generated by the makefile.
 */
-extern char *sqlite3OpcodeNames[];
+extern const char *const sqlite3OpcodeNames[];
 
 /*
 ** SQL is translated into a sequence of instructions to be
@@ -125,7 +125,10 @@ typedef struct Cursor Cursor;
 ** SQLITE_BLOB.
 */
 struct Mem {
-  i64 i;              /* Integer value. Or FuncDef* when flags==MEM_Agg */
+  union {
+    i64 i;              /* Integer value. Or FuncDef* when flags==MEM_Agg */
+    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
+  } u;
   double r;           /* Real value */
   char *z;            /* String or BLOB value */
   int n;              /* Number of characters in string value, including '\0' */
index 9440bbd10539a1167a0c27fd3357ab2adbb7ef95..3d3d815c7fa7fd2dea521dec9f4361cef3ff3116 100644 (file)
@@ -341,7 +341,7 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
     }else{
       pMem->flags = MEM_Agg;
       pMem->xDel = sqlite3FreeX;
-      *(FuncDef**)&pMem->i = p->pFunc;
+      pMem->u.pDef = p->pFunc;
       if( nByte<=NBFS ){
         pMem->z = pMem->zShort;
         memset(pMem->z, 0, nByte);
@@ -443,7 +443,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
   Vdbe *pVm = (Vdbe *)pStmt;
   int vals = sqlite3_data_count(pStmt);
   if( i>=vals || i<0 ){
-    static const Mem nullMem = {0, 0.0, "", 0, MEM_Null, MEM_Null };
+    static const Mem nullMem = {{0}, 0.0, "", 0, MEM_Null, MEM_Null };
     sqlite3Error(pVm->db, SQLITE_RANGE, 0);
     return (Mem*)&nullMem;
   }
index be85e7b8cb3ac0a73a9559484eb6a967100df8c8..064849a36a4ffaba45c7faf38ab27852f4687702 100644 (file)
@@ -195,8 +195,8 @@ int sqlite3VdbeMakeLabel(Vdbe *p){
   assert( p->magic==VDBE_MAGIC_INIT );
   if( i>=p->nLabelAlloc ){
     p->nLabelAlloc = p->nLabelAlloc*2 + 10;
-    sqliteReallocOrFree((void**)&p->aLabel,
-                          p->nLabelAlloc*sizeof(p->aLabel[0]));
+    p->aLabel = sqliteReallocOrFree(p->aLabel,
+                                    p->nLabelAlloc*sizeof(p->aLabel[0]));
   }
   if( p->aLabel ){
     p->aLabel[i] = -1;
@@ -719,11 +719,11 @@ int sqlite3VdbeList(
     Mem *pMem = p->aStack;
     pMem->flags = MEM_Int;
     pMem->type = SQLITE_INTEGER;
-    pMem->i = i;                                /* Program counter */
+    pMem->u.i = i;                                /* Program counter */
     pMem++;
 
     pMem->flags = MEM_Static|MEM_Str|MEM_Term;
-    pMem->z = sqlite3OpcodeNames[pOp->opcode];  /* Opcode */
+    pMem->z = (char*)sqlite3OpcodeNames[pOp->opcode];  /* Opcode */
     assert( pMem->z!=0 );
     pMem->n = strlen(pMem->z);
     pMem->type = SQLITE_TEXT;
@@ -731,12 +731,12 @@ int sqlite3VdbeList(
     pMem++;
 
     pMem->flags = MEM_Int;
-    pMem->i = pOp->p1;                          /* P1 */
+    pMem->u.i = pOp->p1;                          /* P1 */
     pMem->type = SQLITE_INTEGER;
     pMem++;
 
     pMem->flags = MEM_Int;
-    pMem->i = pOp->p2;                          /* P2 */
+    pMem->u.i = pOp->p2;                          /* P2 */
     pMem->type = SQLITE_INTEGER;
     pMem++;
 
@@ -757,11 +757,11 @@ int sqlite3VdbeList(
 }
 #endif /* SQLITE_OMIT_EXPLAIN */
 
+#ifdef SQLITE_DEBUG
 /*
 ** Print the SQL that was used to generate a VDBE program.
 */
 void sqlite3VdbePrintSql(Vdbe *p){
-#ifdef SQLITE_DEBUG
   int nOp = p->nOp;
   VdbeOp *pOp;
   if( nOp<1 ) return;
@@ -771,8 +771,39 @@ void sqlite3VdbePrintSql(Vdbe *p){
     while( isspace(*(u8*)z) ) z++;
     printf("SQL: [%s]\n", z);
   }
+}
 #endif
+
+#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
+/*
+** Print an IOTRACE message showing SQL content.
+*/
+void sqlite3VdbeIOTraceSql(Vdbe *p){
+  int nOp = p->nOp;
+  VdbeOp *pOp;
+  if( sqlite3_io_trace==0 ) return;
+  if( nOp<1 ) return;
+  pOp = &p->aOp[nOp-1];
+  if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
+    char *z = sqlite3StrDup(pOp->p3);
+    int i, j;
+    for(i=0; isspace(z[i]); i++){}
+    for(j=0; z[i]; i++){
+      if( isspace(z[i]) ){
+        if( z[i-1]!=' ' ){
+          z[j++] = ' ';
+        }
+      }else{
+        z[j++] = z[i];
+      }
+    }
+    z[j] = 0;
+    sqlite3_io_trace("SQL %s\n", z);
+    sqliteFree(z);
+  }
 }
+#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
+
 
 /*
 ** Prepare a virtual machine for execution.  This involves things such
@@ -1059,18 +1090,22 @@ static int vdbeCommit(sqlite3 *db){
     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
       Btree *pBt = db->aDb[i].pBt;
       if( pBt ){
-        rc = sqlite3BtreeSync(pBt, 0);
+        rc = sqlite3BtreeCommitPhaseOne(pBt, 0);
       }
     }
 
-    /* Do the commit only if all databases successfully synced */
-    if( rc==SQLITE_OK ){
-      for(i=0; i<db->nDb; i++){
-        Btree *pBt = db->aDb[i].pBt;
-        if( pBt ){
-          sqlite3BtreeCommit(pBt);
-        }
+    /* Do the commit only if all databases successfully complete phase 1. 
+    ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an
+    ** IO error while deleting or truncating a journal file. It is unlikely,
+    ** but could happen. In this case abandon processing and return the error.
+    */
+    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+      Btree *pBt = db->aDb[i].pBt;
+      if( pBt ){
+        rc = sqlite3BtreeCommitPhaseTwo(pBt);
       }
+    }
+    if( rc==SQLITE_OK ){
       sqlite3VtabCommit(db);
     }
   }
@@ -1147,16 +1182,16 @@ static int vdbeCommit(sqlite3 *db){
     ** sets the master journal pointer in each individual journal. If
     ** an error occurs here, do not delete the master journal file.
     **
-    ** If the error occurs during the first call to sqlite3BtreeSync(),
-    ** then there is a chance that the master journal file will be
-    ** orphaned. But we cannot delete it, in case the master journal
-    ** file name was written into the journal file before the failure
-    ** occured.
+    ** If the error occurs during the first call to
+    ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
+    ** master journal file will be orphaned. But we cannot delete it,
+    ** in case the master journal file name was written into the journal
+    ** file before the failure occured.
     */
     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
       Btree *pBt = db->aDb[i].pBt;
       if( pBt && sqlite3BtreeIsInTrans(pBt) ){
-        rc = sqlite3BtreeSync(pBt, zMaster);
+        rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
       }
     }
     sqlite3OsClose(&master);
@@ -1170,11 +1205,11 @@ static int vdbeCommit(sqlite3 *db){
     ** transaction files are deleted.
     */
     rc = sqlite3OsDelete(zMaster);
+    sqliteFree(zMaster);
+    zMaster = 0;
     if( rc ){
       return rc;
     }
-    sqliteFree(zMaster);
-    zMaster = 0;
     rc = sqlite3OsSyncDirectory(zMainFile);
     if( rc!=SQLITE_OK ){
       /* This is not good. The master journal file has been deleted, but
@@ -1188,18 +1223,21 @@ static int vdbeCommit(sqlite3 *db){
     }
 
     /* All files and directories have already been synced, so the following
-    ** calls to sqlite3BtreeCommit() are only closing files and deleting
-    ** journals. If something goes wrong while this is happening we don't
-    ** really care. The integrity of the transaction is already guaranteed,
-    ** but some stray 'cold' journals may be lying around. Returning an
-    ** error code won't help matters.
+    ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
+    ** deleting or truncating journals. If something goes wrong while
+    ** this is happening we don't really care. The integrity of the
+    ** transaction is already guaranteed, but some stray 'cold' journals
+    ** may be lying around. Returning an error code won't help matters.
     */
+    disable_simulated_io_errors();
     for(i=0; i<db->nDb; i++){ 
       Btree *pBt = db->aDb[i].pBt;
       if( pBt ){
-        sqlite3BtreeCommit(pBt);
+        sqlite3BtreeCommitPhaseTwo(pBt);
       }
     }
+    enable_simulated_io_errors();
+
     sqlite3VtabCommit(db);
   }
 #endif
@@ -1470,10 +1508,6 @@ void sqlite3VdbeResetStepResult(Vdbe *p){
 */
 int sqlite3VdbeReset(Vdbe *p){
   sqlite3 *db;
-  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
-    sqlite3Error(p->db, SQLITE_MISUSE, 0);
-    return SQLITE_MISUSE;
-  }
   db = p->db;
 
   /* If the VM did not run to completion or if it encountered an
@@ -1624,12 +1658,7 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
     extern int sqlite3_search_count;
 #endif
     assert( p->isTable );
-    if( p->isTable ){
-      rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
-    }else{
-      rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
-                              sizeof(i64),&res);
-    }
+    rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, 0, &res);
     if( rc ) return rc;
     *p->pIncrKey = 0;
     p->lastRowid = keyToInt(p->movetoTarget);
@@ -1701,7 +1730,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
   if( flags&MEM_Int ){
     /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
 #   define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
-    i64 i = pMem->i;
+    i64 i = pMem->u.i;
     u64 u;
     if( file_format>=4 && (i&1)==i ){
       return 8+i;
@@ -1722,10 +1751,8 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
     assert( n>=0 );
     return ((n*2) + 13);
   }
-  if( flags&MEM_Blob ){
-    return (pMem->n*2 + 12);
-  }
-  return 0;
+  assert( (flags & MEM_Blob)!=0 );
+  return (pMem->n*2 + 12);
 }
 
 /*
@@ -1754,9 +1781,10 @@ int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem, int file_format){
     u64 v;
     int i;
     if( serial_type==7 ){
-      v = *(u64*)&pMem->r;
+      assert( sizeof(v)==sizeof(pMem->r) );
+      memcpy(&v, &pMem->r, sizeof(v));
     }else{
-      v = *(u64*)&pMem->i;
+      v = pMem->u.i;
     }
     len = i = sqlite3VdbeSerialTypeLen(serial_type);
     while( i-- ){
@@ -1794,22 +1822,22 @@ int sqlite3VdbeSerialGet(
       break;
     }
     case 1: { /* 1-byte signed integer */
-      pMem->i = (signed char)buf[0];
+      pMem->u.i = (signed char)buf[0];
       pMem->flags = MEM_Int;
       return 1;
     }
     case 2: { /* 2-byte signed integer */
-      pMem->i = (((signed char)buf[0])<<8) | buf[1];
+      pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
       pMem->flags = MEM_Int;
       return 2;
     }
     case 3: { /* 3-byte signed integer */
-      pMem->i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
+      pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
       pMem->flags = MEM_Int;
       return 3;
     }
     case 4: { /* 4-byte signed integer */
-      pMem->i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
+      pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
       pMem->flags = MEM_Int;
       return 4;
     }
@@ -1817,7 +1845,7 @@ int sqlite3VdbeSerialGet(
       u64 x = (((signed char)buf[0])<<8) | buf[1];
       u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
       x = (x<<32) | y;
-      pMem->i = *(i64*)&x;
+      pMem->u.i = *(i64*)&x;
       pMem->flags = MEM_Int;
       return 6;
     }
@@ -1830,24 +1858,27 @@ int sqlite3VdbeSerialGet(
       ** byte order.  The byte order differs on some (broken) architectures.
       */
       static const u64 t1 = ((u64)0x3ff00000)<<32;
-      assert( 1.0==*(double*)&t1 );
+      static const double r1 = 1.0;
+      assert( sizeof(r1)==sizeof(t1) && memcmp(&r1, &t1, sizeof(r1))==0 );
 #endif
 
       x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
       y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
       x = (x<<32) | y;
       if( serial_type==6 ){
-        pMem->i = *(i64*)&x;
+        pMem->u.i = *(i64*)&x;
         pMem->flags = MEM_Int;
       }else{
-        pMem->r = *(double*)&x;
+        assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
+        memcpy(&pMem->r, &x, sizeof(x));
+        /* pMem->r = *(double*)&x; */
         pMem->flags = MEM_Real;
       }
       return 8;
     }
     case 8:    /* Integer 0 */
     case 9: {  /* Integer 1 */
-      pMem->i = serial_type-8;
+      pMem->u.i = serial_type-8;
       pMem->flags = MEM_Int;
       return 0;
     }
@@ -1984,7 +2015,7 @@ int sqlite3VdbeIdxRowidLen(const u8 *aKey){
 ** Return SQLITE_OK if everything works, or an error code otherwise.
 */
 int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
-  i64 nCellKey;
+  i64 nCellKey = 0;
   int rc;
   u32 szHdr;        /* Size of the header */
   u32 typeRowid;    /* Serial type of the rowid */
@@ -2003,7 +2034,7 @@ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
   sqlite3GetVarint32((u8*)&m.z[szHdr-1], &typeRowid);
   lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
   sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
-  *rowid = v.i;
+  *rowid = v.u.i;
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;
 }
@@ -2023,7 +2054,7 @@ int sqlite3VdbeIdxKeyCompare(
   int nKey, const u8 *pKey,   /* The key to compare */
   int *res                    /* Write the comparison result here */
 ){
-  i64 nCellKey;
+  i64 nCellKey = 0;
   int rc;
   BtCursor *pCur = pC->pCursor;
   int lenRowid;
index 7ea6c050f9bbdf94756d1fb834335735f42b769a..a7c419ae5e09540f0bde2c944d7a9ad47a5b9788 100644 (file)
@@ -19,7 +19,7 @@
 ** Allocate a new FifoPage and return a pointer to it.  Return NULL if
 ** we run out of memory.  Leave space on the page for nEntry entries.
 */
-static FifoPage *allocatePage(int nEntry){
+static FifoPage *allocateFifoPage(int nEntry){
   FifoPage *pPage;
   if( nEntry>32767 ){
     nEntry = 32767;
@@ -50,12 +50,12 @@ int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
   FifoPage *pPage;
   pPage = pFifo->pLast;
   if( pPage==0 ){
-    pPage = pFifo->pLast = pFifo->pFirst = allocatePage(20);
+    pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(20);
     if( pPage==0 ){
       return SQLITE_NOMEM;
     }
   }else if( pPage->iWrite>=pPage->nSlot ){
-    pPage->pNext = allocatePage(pFifo->nEntry);
+    pPage->pNext = allocateFifoPage(pFifo->nEntry);
     if( pPage->pNext==0 ){
       return SQLITE_NOMEM;
     }
index 87059c8a8d6b5bbfe0e4c9a5516426a193d7ee9d..5aed1df3dbc9f7598ef7be4c603cd090895dea10 100644 (file)
@@ -170,7 +170,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){
   ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
   */
   if( fg & MEM_Int ){
-    sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
+    sqlite3_snprintf(NBFS, z, "%lld", pMem->u.i);
   }else{
     assert( fg & MEM_Real );
     sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
@@ -195,7 +195,7 @@ 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 );
+    assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
     ctx.s.flags = MEM_Null;
     ctx.s.z = pMem->zShort;
     ctx.pMem = pMem;
@@ -225,7 +225,7 @@ void sqlite3VdbeMemRelease(Mem *p){
   if( p->flags & (MEM_Dyn|MEM_Agg) ){
     if( p->xDel ){
       if( p->flags & MEM_Agg ){
-        sqlite3VdbeMemFinalize(p, *(FuncDef**)&p->i);
+        sqlite3VdbeMemFinalize(p, p->u.pDef);
         assert( (p->flags & MEM_Agg)==0 );
         sqlite3VdbeMemRelease(p);
       }else{
@@ -252,7 +252,7 @@ void sqlite3VdbeMemRelease(Mem *p){
 i64 sqlite3VdbeIntValue(Mem *pMem){
   int flags = pMem->flags;
   if( flags & MEM_Int ){
-    return pMem->i;
+    return pMem->u.i;
   }else if( flags & MEM_Real ){
     return (i64)pMem->r;
   }else if( flags & (MEM_Str|MEM_Blob) ){
@@ -279,7 +279,7 @@ double sqlite3VdbeRealValue(Mem *pMem){
   if( pMem->flags & MEM_Real ){
     return pMem->r;
   }else if( pMem->flags & MEM_Int ){
-    return (double)pMem->i;
+    return (double)pMem->u.i;
   }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
     double val = 0.0;
     if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
@@ -300,8 +300,8 @@ double sqlite3VdbeRealValue(Mem *pMem){
 */
 void sqlite3VdbeIntegerAffinity(Mem *pMem){
   assert( pMem->flags & MEM_Real );
-  pMem->i = pMem->r;
-  if( ((double)pMem->i)==pMem->r ){
+  pMem->u.i = pMem->r;
+  if( ((double)pMem->u.i)==pMem->r ){
     pMem->flags |= MEM_Int;
   }
 }
@@ -310,7 +310,7 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
 ** Convert pMem to type integer.  Invalidate any prior representations.
 */
 int sqlite3VdbeMemIntegerify(Mem *pMem){
-  pMem->i = sqlite3VdbeIntValue(pMem);
+  pMem->u.i = sqlite3VdbeIntValue(pMem);
   sqlite3VdbeMemRelease(pMem);
   pMem->flags = MEM_Int;
   return SQLITE_OK;
@@ -353,7 +353,7 @@ void sqlite3VdbeMemSetNull(Mem *pMem){
 */
 void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
   sqlite3VdbeMemRelease(pMem);
-  pMem->i = val;
+  pMem->u.i = val;
   pMem->flags = MEM_Int;
   pMem->type = SQLITE_INTEGER;
 }
@@ -538,12 +538,12 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
     if( (f1 & f2 & MEM_Int)==0 ){
       double r1, r2;
       if( (f1&MEM_Real)==0 ){
-        r1 = pMem1->i;
+        r1 = pMem1->u.i;
       }else{
         r1 = pMem1->r;
       }
       if( (f2&MEM_Real)==0 ){
-        r2 = pMem2->i;
+        r2 = pMem2->u.i;
       }else{
         r2 = pMem2->r;
       }
@@ -553,8 +553,8 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
     }else{
       assert( f1&MEM_Int );
       assert( f2&MEM_Int );
-      if( pMem1->i < pMem2->i ) return -1;
-      if( pMem1->i > pMem2->i ) return 1;
+      if( pMem1->u.i < pMem2->u.i ) return -1;
+      if( pMem1->u.i > pMem2->u.i ) return 1;
       return 0;
     }
   }
@@ -637,14 +637,15 @@ int sqlite3VdbeMemFromBtree(
   int key,          /* If true, retrieve from the btree key, not data. */
   Mem *pMem         /* OUT: Return data in this Mem structure. */
 ){
-  char *zData;      /* Data from the btree layer */
-  int available;    /* Number of bytes available on the local btree page */
+  char *zData;       /* Data from the btree layer */
+  int available = 0; /* Number of bytes available on the local btree page */
 
   if( key ){
     zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
   }else{
     zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
   }
+  assert( zData!=0 );
 
   pMem->n = amt;
   if( offset+amt<=available ){
@@ -735,7 +736,7 @@ void sqlite3VdbeMemSanity(Mem *pMem){
           || (pMem->flags&MEM_Null)==0 );
   /* If the MEM is both real and integer, the values are equal */
   assert( (pMem->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) 
-          || pMem->r==pMem->i );
+          || pMem->r==pMem->u.i );
 }
 #endif
 
@@ -831,7 +832,7 @@ int sqlite3ValueFromExpr(
     }
   }else if( op==TK_UMINUS ) {
     if( SQLITE_OK==sqlite3ValueFromExpr(pExpr->pLeft, enc, affinity, &pVal) ){
-      pVal->i = -1 * pVal->i;
+      pVal->u.i = -1 * pVal->u.i;
       pVal->r = -1.0 * pVal->r;
     }
   }
index f603dfc9242da3dc47fcb381aa6dc7ef9954021d..ac3df19d50b4e04a02e297c11b5331d448614681 100644 (file)
@@ -35,9 +35,9 @@
 */
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
 int sqlite3_where_trace = 0;
-# define TRACE(X)  if(sqlite3_where_trace) sqlite3DebugPrintf X
+# define WHERETRACE(X)  if(sqlite3_where_trace) sqlite3DebugPrintf X
 #else
-# define TRACE(X)
+# define WHERETRACE(X)
 #endif
 
 /* Forward reference
@@ -220,6 +220,9 @@ static void whereClauseClear(WhereClause *pWC){
 ** Add a new entries to the WhereClause structure.  Increase the allocated
 ** space as necessary.
 **
+** If the flags argument includes TERM_DYNAMIC, then responsibility
+** for freeing the expression p is assumed by the WhereClause object.
+**
 ** WARNING:  This routine might reallocate the space used to store
 ** WhereTerms.  All pointers to WhereTerms should be invalided after
 ** calling this routine.  Such pointers may be reinitialized by referencing
@@ -231,7 +234,12 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
   if( pWC->nTerm>=pWC->nSlot ){
     WhereTerm *pOld = pWC->a;
     pWC->a = sqliteMalloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
-    if( pWC->a==0 ) return 0;
+    if( pWC->a==0 ){
+      if( flags & TERM_DYNAMIC ){
+        sqlite3ExprDelete(p);
+      }
+      return 0;
+    }
     memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
     if( pOld!=pWC->aStatic ){
       sqliteFree(pOld);
@@ -523,6 +531,10 @@ static int isLikeOrGlob(
   }
   pColl = pLeft->pColl;
   if( pColl==0 ){
+    /* TODO: Coverage testing doesn't get this case. Is it actually possible
+    ** for an expression of type TK_COLUMN to not have an assigned collation 
+    ** sequence at this point?
+    */
     pColl = db->pDfltColl;
   }
   if( (pColl->type!=SQLITE_COLL_BINARY || noCase) &&
@@ -582,6 +594,92 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
   pDerived->iRightJoinTable = pBase->iRightJoinTable;
 }
 
+#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
+/*
+** Return TRUE if the given term of an OR clause can be converted
+** into an IN clause.  The iCursor and iColumn define the left-hand
+** side of the IN clause.
+**
+** The context is that we have multiple OR-connected equality terms
+** like this:
+**
+**           a=<expr1> OR  a=<expr2> OR b=<expr3>  OR ...
+**
+** The pOrTerm input to this routine corresponds to a single term of
+** this OR clause.  In order for the term to be a condidate for
+** conversion to an IN operator, the following must be true:
+**
+**     *  The left-hand side of the term must be the column which
+**        is identified by iCursor and iColumn.
+**
+**     *  If the right-hand side is also a column, then the affinities
+**        of both right and left sides must be such that no type
+**        conversions are required on the right.  (Ticket #2249)
+**
+** If both of these conditions are true, then return true.  Otherwise
+** return false.
+*/
+static int orTermIsOptCandidate(WhereTerm *pOrTerm, int iCursor, int iColumn){
+  int affLeft, affRight;
+  assert( pOrTerm->eOperator==WO_EQ );
+  if( pOrTerm->leftCursor!=iCursor ){
+    return 0;
+  }
+  if( pOrTerm->leftColumn!=iColumn ){
+    return 0;
+  }
+  affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight);
+  if( affRight==0 ){
+    return 1;
+  }
+  affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft);
+  if( affRight!=affLeft ){
+    return 0;
+  }
+  return 1;
+}
+
+/*
+** Return true if the given term of an OR clause can be ignored during
+** a check to make sure all OR terms are candidates for optimization.
+** In other words, return true if a call to the orTermIsOptCandidate()
+** above returned false but it is not necessary to disqualify the
+** optimization.
+**
+** Suppose the original OR phrase was this:
+**
+**           a=4  OR  a=11  OR  a=b
+**
+** During analysis, the third term gets flipped around and duplicate
+** so that we are left with this:
+**
+**           a=4  OR  a=11  OR  a=b  OR  b=a
+**
+** Since the last two terms are duplicates, only one of them
+** has to qualify in order for the whole phrase to qualify.  When
+** this routine is called, we know that pOrTerm did not qualify.
+** This routine merely checks to see if pOrTerm has a duplicate that
+** might qualify.  If there is a duplicate that has not yet been
+** disqualified, then return true.  If there are no duplicates, or
+** the duplicate has also been disqualifed, return false.
+*/
+static int orTermHasOkDuplicate(WhereClause *pOr, WhereTerm *pOrTerm){
+  if( pOrTerm->flags & TERM_COPIED ){
+    /* This is the original term.  The duplicate is to the left had
+    ** has not yet been analyzed and thus has not yet been disqualified. */
+    return 1;
+  }
+  if( (pOrTerm->flags & TERM_VIRTUAL)!=0
+     && (pOr->a[pOrTerm->iParent].flags & TERM_OR_OK)!=0 ){
+    /* This is a duplicate term.  The original qualified so this one
+    ** does not have to. */
+    return 1;
+  }
+  /* This is either a singleton term or else it is a duplicate for
+  ** which the original did not qualify.  Either way we are done for. */
+  return 0;
+}
+#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
 
 /*
 ** The input to this routine is an WhereTerm structure with only the
@@ -644,7 +742,7 @@ static void exprAnalyze(
         int idxNew;
         pDup = sqlite3ExprDup(pExpr);
         if( sqlite3MallocFailed() ){
-          sqliteFree(pDup);
+          sqlite3ExprDelete(pDup);
           return;
         }
         idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
@@ -716,9 +814,10 @@ static void exprAnalyze(
     whereClauseInit(&sOr, pWC->pParse, pMaskSet);
     whereSplit(&sOr, pExpr, TK_OR);
     exprAnalyzeAll(pSrc, &sOr);
-    assert( sOr.nTerm>0 );
+    assert( sOr.nTerm>=2 );
     j = 0;
     do{
+      assert( j<sOr.nTerm );
       iColumn = sOr.a[j].leftColumn;
       iCursor = sOr.a[j].leftCursor;
       ok = iCursor>=0;
@@ -726,17 +825,15 @@ static void exprAnalyze(
         if( pOrTerm->eOperator!=WO_EQ ){
           goto or_not_possible;
         }
-        if( pOrTerm->leftCursor==iCursor && pOrTerm->leftColumn==iColumn ){
+        if( orTermIsOptCandidate(pOrTerm, iCursor, iColumn) ){
           pOrTerm->flags |= TERM_OR_OK;
-        }else if( (pOrTerm->flags & TERM_COPIED)!=0 ||
-                    ((pOrTerm->flags & TERM_VIRTUAL)!=0 &&
-                     (sOr.a[pOrTerm->iParent].flags & TERM_OR_OK)!=0) ){
+        }else if( orTermHasOkDuplicate(&sOr, pOrTerm) ){
           pOrTerm->flags &= ~TERM_OR_OK;
         }else{
           ok = 0;
         }
       }
-    }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<sOr.nTerm );
+    }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<2 );
     if( ok ){
       ExprList *pList = 0;
       Expr *pNew, *pDup;
@@ -1041,8 +1138,7 @@ static double estLog(double N){
 ** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
 ** are no-ops.
 */
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && \
-        (defined(SQLITE_TEST) || defined(SQLITE_DEBUG))
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)
 static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
   int i;
   if( !sqlite3_where_trace ) return;
@@ -1124,7 +1220,7 @@ static double bestVirtualIndex(
   if( pIdxInfo==0 ){
     WhereTerm *pTerm;
     int nTerm;
-    TRACE(("Recomputing index info for %s...\n", pTab->zName));
+    WHERETRACE(("Recomputing index info for %s...\n", pTab->zName));
 
     /* Count the number of possible WHERE clause constraints referring
     ** to this virtual table */
@@ -1207,13 +1303,19 @@ static double bestVirtualIndex(
   ** xBestIndex.
   */
 
-  /* The module name must be defined */
+  /* The module name must be defined. Also, by this point there must
+  ** be a pointer to an sqlite3_vtab structure. Otherwise
+  ** sqlite3ViewGetColumnNames() would have picked up the error. 
+  */
   assert( pTab->azModuleArg && pTab->azModuleArg[0] );
+  assert( pTab->pVtab );
+#if 0
   if( pTab->pVtab==0 ){
     sqlite3ErrorMsg(pParse, "undefined module %s for table %s",
         pTab->azModuleArg[0], pTab->zName);
     return 0.0;
   }
+#endif
 
   /* Set the aConstraint[].usable fields and initialize all 
   ** output variables to zero.
@@ -1257,7 +1359,7 @@ static double bestVirtualIndex(
   }
 
   sqlite3SafetyOff(pParse->db);
-  TRACE(("xBestIndex for %s\n", pTab->zName));
+  WHERETRACE(("xBestIndex for %s\n", pTab->zName));
   TRACE_IDX_INPUTS(pIdxInfo);
   rc = pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo);
   TRACE_IDX_OUTPUTS(pIdxInfo);
@@ -1272,6 +1374,7 @@ static double bestVirtualIndex(
     rc = sqlite3SafetyOn(pParse->db);
   }
   *(int*)&pIdxInfo->nOrderBy = nOrderBy;
+
   return pIdxInfo->estimatedCost;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -1317,7 +1420,7 @@ static double bestIndex(
   int eqTermMask;             /* Mask of valid equality operators */
   double cost;                /* Cost of using pProbe */
 
-  TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
+  WHERETRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
   lowestCost = SQLITE_BIG_DBL;
   pProbe = pSrc->pTab->pIndex;
 
@@ -1348,7 +1451,7 @@ static double bestIndex(
       ** a single row is generated, output is always in sorted order */
       *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
       *pnEq = 1;
-      TRACE(("... best is rowid\n"));
+      WHERETRACE(("... best is rowid\n"));
       return 0.0;
     }else if( (pExpr = pTerm->pExpr)->pList!=0 ){
       /* Rowid IN (LIST): cost is NlogN where N is the number of list
@@ -1361,14 +1464,14 @@ static double bestIndex(
       ** that value so make a wild guess. */
       lowestCost = 200;
     }
-    TRACE(("... rowid IN cost: %.9g\n", lowestCost));
+    WHERETRACE(("... rowid IN cost: %.9g\n", lowestCost));
   }
 
   /* 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.
   */
   cost = pProbe ? pProbe->aiRowEst[0] : 1000000;
-  TRACE(("... table scan base cost: %.9g\n", cost));
+  WHERETRACE(("... table scan base cost: %.9g\n", cost));
   flags = WHERE_ROWID_RANGE;
 
   /* Check for constraints on a range of rowids in a table scan.
@@ -1383,7 +1486,7 @@ static double bestIndex(
       flags |= WHERE_BTM_LIMIT;
       cost /= 3;  /* Guess that rowid>EXPR eliminates two-thirds of rows */
     }
-    TRACE(("... rowid range reduces cost to %.9g\n", cost));
+    WHERETRACE(("... rowid range reduces cost to %.9g\n", cost));
   }else{
     flags = 0;
   }
@@ -1398,7 +1501,7 @@ static double bestIndex(
       }
     }else{
       cost += cost*estLog(cost);
-      TRACE(("... sorting increases cost to %.9g\n", cost));
+      WHERETRACE(("... sorting increases cost to %.9g\n", cost));
     }
   }
   if( cost<lowestCost ){
@@ -1423,7 +1526,7 @@ static double bestIndex(
     int i;                       /* Loop counter */
     double inMultiplier = 1;
 
-    TRACE(("... index %s:\n", pProbe->zName));
+    WHERETRACE(("... index %s:\n", pProbe->zName));
 
     /* Count the number of columns in the index that are satisfied
     ** by x=EXPR constraints or x IN (...) constraints.
@@ -1450,7 +1553,7 @@ static double bestIndex(
          && nEq==pProbe->nColumn ){
       flags |= WHERE_UNIQUE;
     }
-    TRACE(("...... nEq=%d inMult=%.9g cost=%.9g\n", nEq, inMultiplier, cost));
+    WHERETRACE(("...... nEq=%d inMult=%.9g cost=%.9g\n", nEq, inMultiplier, cost));
 
     /* Look for range constraints
     */
@@ -1467,7 +1570,7 @@ static double bestIndex(
           flags |= WHERE_BTM_LIMIT;
           cost /= 3;
         }
-        TRACE(("...... range reduces cost to %.9g\n", cost));
+        WHERETRACE(("...... range reduces cost to %.9g\n", cost));
       }
     }
 
@@ -1485,7 +1588,7 @@ static double bestIndex(
         }
       }else{
         cost += cost*estLog(cost);
-        TRACE(("...... orderby increases cost to %.9g\n", cost));
+        WHERETRACE(("...... orderby increases cost to %.9g\n", cost));
       }
     }
 
@@ -1505,7 +1608,7 @@ static double bestIndex(
       if( m==0 ){
         flags |= WHERE_IDX_ONLY;
         cost /= 2;
-        TRACE(("...... idx-only reduces cost to %.9g\n", cost));
+        WHERETRACE(("...... idx-only reduces cost to %.9g\n", cost));
       }
     }
 
@@ -1523,7 +1626,7 @@ static double bestIndex(
   /* Report the best result
   */
   *ppIndex = bestIdx;
-  TRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
+  WHERETRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
         bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq));
   *pFlags = bestFlags | eqTermMask;
   *pnEq = bestNEq;
@@ -1601,7 +1704,6 @@ static void buildIndexProbe(
 static void codeEqualityTerm(
   Parse *pParse,      /* The parsing context */
   WhereTerm *pTerm,   /* The term of the WHERE clause to be coded */
-  int brk,            /* Jump here to abandon the loop */
   WhereLevel *pLevel  /* When level of the FROM clause we are working on */
 ){
   Expr *pX = pTerm->pExpr;
@@ -1613,21 +1715,25 @@ static void codeEqualityTerm(
 #ifndef SQLITE_OMIT_SUBQUERY
   }else{
     int iTab;
-    int *aIn;
+    struct InLoop *pIn;
 
     assert( pX->op==TK_IN );
     sqlite3CodeSubselect(pParse, pX);
     iTab = pX->iTable;
     sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
     VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));
+    if( pLevel->nIn==0 ){
+      pLevel->nxt = sqlite3VdbeMakeLabel(v);
+    }
     pLevel->nIn++;
-    sqliteReallocOrFree((void**)&pLevel->aInLoop,
-                                 sizeof(pLevel->aInLoop[0])*2*pLevel->nIn);
-    aIn = pLevel->aInLoop;
-    if( aIn ){
-      aIn += pLevel->nIn*2 - 2;
-      aIn[0] = iTab;
-      aIn[1] = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
+    pLevel->aInLoop = sqliteReallocOrFree(pLevel->aInLoop,
+                                    sizeof(pLevel->aInLoop[0])*pLevel->nIn);
+    pIn = pLevel->aInLoop;
+    if( pIn ){
+      pIn += pLevel->nIn - 1;
+      pIn->iCur = iTab;
+      pIn->topAddr = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
+      sqlite3VdbeAddOp(v, OP_IsNull, -1, 0);
     }else{
       pLevel->nIn = 0;
     }
@@ -1663,8 +1769,7 @@ static void codeAllEqualityTerms(
   Parse *pParse,        /* Parsing context */
   WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
   WhereClause *pWC,     /* The WHERE clause */
-  Bitmask notReady,     /* Which parts of FROM have not yet been coded */
-  int brk               /* Jump here to end the loop */
+  Bitmask notReady      /* Which parts of FROM have not yet been coded */
 ){
   int nEq = pLevel->nEq;        /* The number of == or IN constraints to code */
   int termsInMem = 0;           /* If true, store value in mem[] cells */
@@ -1693,9 +1798,9 @@ static void codeAllEqualityTerms(
     pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx);
     if( pTerm==0 ) break;
     assert( (pTerm->flags & TERM_CODED)==0 );
-    codeEqualityTerm(pParse, pTerm, brk, pLevel);
-    if( (pTerm->eOperator & WO_ISNULL)==0 ){
-      sqlite3VdbeAddOp(v, OP_IsNull, termsInMem ? -1 : -(j+1), brk);
+    codeEqualityTerm(pParse, pTerm, pLevel);
+    if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
+      sqlite3VdbeAddOp(v, OP_IsNull, termsInMem ? -1 : -(j+1), pLevel->brk);
     }
     if( termsInMem ){
       sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1);
@@ -1734,6 +1839,10 @@ static void whereInfoFree(WhereInfo *pWInfo){
       sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
       if( pInfo ){
         if( pInfo->needToFreeIdxStr ){
+          /* Coverage: Don't think this can be reached. By the time this
+          ** function is called, the index-strings have been passed
+          ** to the vdbe layer for deletion.
+          */
           sqlite3_free(pInfo->idxStr);
         }
         sqliteFree(pInfo);
@@ -1917,7 +2026,7 @@ WhereInfo *sqlite3WhereBegin(
   pTabItem = pTabList->a;
   pLevel = pWInfo->a;
   andFlags = ~0;
-  TRACE(("*** Optimizer Start ***\n"));
+  WHERETRACE(("*** Optimizer Start ***\n"));
   for(i=iFrom=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
     Index *pIdx;                /* Index for FROM table at pTabItem */
     int flags;                  /* Flags asssociated with pIdx */
@@ -1958,6 +2067,14 @@ WhereInfo *sqlite3WhereBegin(
         }
         pIdx = 0;
         nEq = 0;
+        if( (SQLITE_BIG_DBL/2.0)<cost ){
+          /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
+          ** inital value of lowestCost in this loop. If it is, then
+          ** the (cost<lowestCost) test below will never be true and
+          ** pLevel->pBestIdx never set.
+          */ 
+          cost = (SQLITE_BIG_DBL/2.0);
+        }
       }else 
 #endif
       {
@@ -1977,7 +2094,7 @@ WhereInfo *sqlite3WhereBegin(
       }
       if( doNotReorder ) break;
     }
-    TRACE(("*** Optimizer choose table %d for loop %d\n", bestJ,
+    WHERETRACE(("*** Optimizer choose table %d for loop %d\n", bestJ,
            pLevel-pWInfo->a));
     if( (bestFlags & WHERE_ORDERBY)!=0 ){
       *ppOrderBy = 0;
@@ -1996,7 +2113,7 @@ WhereInfo *sqlite3WhereBegin(
     notReady &= ~getMask(&maskSet, pTabList->a[bestJ].iCursor);
     pLevel->iFrom = bestJ;
   }
-  TRACE(("*** Optimizer Finished ***\n"));
+  WHERETRACE(("*** Optimizer Finished ***\n"));
 
   /* If the total query only selects a single row, then the ORDER BY
   ** clause is irrelevant.
@@ -2090,6 +2207,7 @@ WhereInfo *sqlite3WhereBegin(
     int j;
     int iCur = pTabItem->iCursor;  /* The VDBE cursor for the table */
     Index *pIdx;       /* The index we will be using */
+    int nxt;           /* Where to jump to continue with the next IN case */
     int iIdxCur;       /* The VDBE cursor for the index */
     int omitTable;     /* True if we use the index only */
     int bRev;          /* True if we need to scan in reverse order */
@@ -2105,8 +2223,13 @@ WhereInfo *sqlite3WhereBegin(
     ** for the current loop.  Jump to brk to break out of a loop.
     ** Jump to cont to go immediately to the next iteration of the
     ** loop.
+    **
+    ** When there is an IN operator, we also have a "nxt" label that
+    ** means to continue with the next IN value combination.  When
+    ** there are no IN operators in the constraints, the "nxt" label
+    ** is the same as "brk".
     */
-    brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
+    brk = pLevel->brk = pLevel->nxt = sqlite3VdbeMakeLabel(v);
     cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
 
     /* If this is the right table of a LEFT OUTER JOIN, allocate and
@@ -2172,9 +2295,10 @@ WhereInfo *sqlite3WhereBegin(
       assert( pTerm->pExpr!=0 );
       assert( pTerm->leftCursor==iCur );
       assert( omitTable==0 );
-      codeEqualityTerm(pParse, pTerm, brk, pLevel);
-      sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk);
-      sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk);
+      codeEqualityTerm(pParse, pTerm, pLevel);
+      nxt = pLevel->nxt;
+      sqlite3VdbeAddOp(v, OP_MustBeInt, 1, nxt);
+      sqlite3VdbeAddOp(v, OP_NotExists, iCur, nxt);
       VdbeComment((v, "pk"));
       pLevel->op = OP_Noop;
     }else if( pLevel->flags & WHERE_ROWID_RANGE ){
@@ -2253,7 +2377,7 @@ WhereInfo *sqlite3WhereBegin(
       /* Generate code to evaluate all constraint terms using == or IN
       ** and level the values of those terms on the stack.
       */
-      codeAllEqualityTerms(pParse, pLevel, &wc, notReady, brk);
+      codeAllEqualityTerms(pParse, pLevel, &wc, notReady);
 
       /* Duplicate the equality term values because they will all be
       ** used twice: once to make the termination key and once to make the
@@ -2284,6 +2408,7 @@ WhereInfo *sqlite3WhereBegin(
       ** 2002-Dec-04: On a reverse-order scan, the so-called "termination"
       ** key computed here really ends up being the start key.
       */
+      nxt = pLevel->nxt;
       if( topLimit ){
         Expr *pX;
         int k = pIdx->aiColumn[j];
@@ -2292,7 +2417,7 @@ WhereInfo *sqlite3WhereBegin(
         pX = pTerm->pExpr;
         assert( (pTerm->flags & TERM_CODED)==0 );
         sqlite3ExprCode(pParse, pX->pRight);
-        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
+        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), nxt);
         topEq = pTerm->eOperator & (WO_LE|WO_GE);
         disableTerm(pLevel, pTerm);
         testOp = OP_IdxGE;
@@ -2306,7 +2431,7 @@ WhereInfo *sqlite3WhereBegin(
         buildIndexProbe(v, nCol, pIdx);
         if( bRev ){
           int op = topEq ? OP_MoveLe : OP_MoveLt;
-          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
+          sqlite3VdbeAddOp(v, op, iIdxCur, nxt);
         }else{
           sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
         }
@@ -2331,7 +2456,7 @@ WhereInfo *sqlite3WhereBegin(
         pX = pTerm->pExpr;
         assert( (pTerm->flags & TERM_CODED)==0 );
         sqlite3ExprCode(pParse, pX->pRight);
-        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
+        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), nxt);
         btmEq = pTerm->eOperator & (WO_LE|WO_GE);
         disableTerm(pLevel, pTerm);
       }else{
@@ -2346,7 +2471,7 @@ WhereInfo *sqlite3WhereBegin(
           testOp = OP_IdxLT;
         }else{
           int op = btmEq ? OP_MoveGe : OP_MoveGt;
-          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
+          sqlite3VdbeAddOp(v, op, iIdxCur, nxt);
         }
       }else if( bRev ){
         testOp = OP_Noop;
@@ -2361,7 +2486,7 @@ WhereInfo *sqlite3WhereBegin(
       start = sqlite3VdbeCurrentAddr(v);
       if( testOp!=OP_Noop ){
         sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-        sqlite3VdbeAddOp(v, testOp, iIdxCur, brk);
+        sqlite3VdbeAddOp(v, testOp, iIdxCur, nxt);
         if( (topEq && !bRev) || (!btmEq && bRev) ){
           sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
         }
@@ -2390,7 +2515,8 @@ WhereInfo *sqlite3WhereBegin(
       /* Generate code to evaluate all constraint terms using == or IN
       ** and leave the values of those terms on the stack.
       */
-      codeAllEqualityTerms(pParse, pLevel, &wc, notReady, brk);
+      codeAllEqualityTerms(pParse, pLevel, &wc, notReady);
+      nxt = pLevel->nxt;
 
       /* Generate a single key that will be used to both start and terminate
       ** the search
@@ -2399,21 +2525,21 @@ WhereInfo *sqlite3WhereBegin(
       sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
 
       /* Generate code (1) to move to the first matching element of the table.
-      ** Then generate code (2) that jumps to "brk" after the cursor is past
+      ** Then generate code (2) that jumps to "nxt" after the cursor is past
       ** the last matching element of the table.  The code (1) is executed
       ** once to initialize the search, the code (2) is executed before each
       ** iteration of the scan to see if the scan has finished. */
       if( bRev ){
         /* Scan in reverse order */
-        sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, brk);
+        sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, nxt);
         start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-        sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, brk);
+        sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, nxt);
         pLevel->op = OP_Prev;
       }else{
         /* Scan in the forward order */
-        sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, brk);
+        sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, nxt);
         start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-        sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC);
+        sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, nxt, "+", P3_STATIC);
         pLevel->op = OP_Next;
       }
       if( !omitTable ){
@@ -2546,16 +2672,18 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
     if( pLevel->op!=OP_Noop ){
       sqlite3VdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
     }
-    sqlite3VdbeResolveLabel(v, pLevel->brk);
     if( pLevel->nIn ){
-      int *a;
+      struct InLoop *pIn;
       int j;
-      for(j=pLevel->nIn, a=&pLevel->aInLoop[j*2-2]; j>0; j--, a-=2){
-        sqlite3VdbeAddOp(v, OP_Next, a[0], a[1]);
-        sqlite3VdbeJumpHere(v, a[1]-1);
+      sqlite3VdbeResolveLabel(v, pLevel->nxt);
+      for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){
+        sqlite3VdbeJumpHere(v, pIn->topAddr+1);
+        sqlite3VdbeAddOp(v, OP_Next, pIn->iCur, pIn->topAddr);
+        sqlite3VdbeJumpHere(v, pIn->topAddr-1);
       }
       sqliteFree(pLevel->aInLoop);
     }
+    sqlite3VdbeResolveLabel(v, pLevel->brk);
     if( pLevel->iLeftJoin ){
       int addr;
       addr = sqlite3VdbeAddOp(v, OP_IfMemPos, pLevel->iLeftJoin, 0);