]> granicus.if.org Git - php/commitdiff
Upgraded SQLite 3 to version 3.3.12
authorIlia Alshanetsky <iliaa@php.net>
Fri, 9 Feb 2007 03:17:47 +0000 (03:17 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Fri, 9 Feb 2007 03:17:47 +0000 (03:17 +0000)
49 files changed:
NEWS
ext/pdo_sqlite/sqlite/VERSION
ext/pdo_sqlite/sqlite/src/alter.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/insert.c
ext/pdo_sqlite/sqlite/src/legacy.c
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.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.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/random.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/table.c
ext/pdo_sqlite/sqlite/src/tclsqlite.c
ext/pdo_sqlite/sqlite/src/test1.c
ext/pdo_sqlite/sqlite/src/test3.c
ext/pdo_sqlite/sqlite/src/tokenize.c
ext/pdo_sqlite/sqlite/src/trigger.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/vdbe.h
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/vdbemem.c
ext/pdo_sqlite/sqlite/src/vtab.c
ext/pdo_sqlite/sqlite/src/where.c

diff --git a/NEWS b/NEWS
index d10960ac1f70cd381b9348c29be0e9cc77c736d0..9bf86d5029c47fc462229d3ae176e4475f0abe1d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2007, PHP 5.2.2
+- Upgraded SQLite 3 to version 3.3.12 (Ilia)
 - Add --ri switch to CLI which allows to check extension information. (Marcus)
 - Fixed bug #39836 (SplObjectStorage empty after unserialize). (Marcus)
 
index 86fb6504403518a9d6027674d8ce1120235310e9..4d541eb209657e03bd0ba8c44e6c3041e2ca97c0 100644 (file)
@@ -1 +1 @@
-3.3.7
+3.3.12
index 0d6bfbf9dcfa231b6d3fbf56f4cd25a612229be5..81c53ffbd9ddf9ab9b9e69e12db1928b766d5fa7 100644 (file)
@@ -28,7 +28,7 @@
 ** This function is used by SQL generated to implement the 
 ** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
 ** CREATE INDEX command. The second is a table name. The table name in 
-** the CREATE TABLE or CREATE INDEX statement is replaced with the second
+** the CREATE TABLE or CREATE INDEX statement is replaced with the third
 ** argument and the result returned. Examples:
 **
 ** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
@@ -78,10 +78,10 @@ static void renameTableFunc(
 }
 
 #ifndef SQLITE_OMIT_TRIGGER
-/* This function is used by SQL generated to implement the ALTER TABLE
+/* This function is used by SQL generated to implement the
 ** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
 ** statement. The second is a table name. The table name in the CREATE 
-** TRIGGER statement is replaced with the second argument and the result 
+** TRIGGER statement is replaced with the third argument and the result 
 ** returned. This is analagous to renameTableFunc() above, except for CREATE
 ** TRIGGER, not CREATE INDEX and CREATE TABLE.
 */
index 52bc749a3272dee75bf4f7935b5417c955e00d36..595f19ffa1aa79dbe6dd723eb8cc61af4d1012f1 100644 (file)
@@ -387,17 +387,13 @@ struct BtCursor {
   CellInfo info;            /* A parse of the cell we are pointing at */
   u8 wrFlag;                /* True if writable */
   u8 eState;                /* One of the CURSOR_XXX constants (see below) */
-#ifndef SQLITE_OMIT_SHARED_CACHE
   void *pKey;      /* Saved key that was cursor's last known position */
   i64 nKey;        /* Size of pKey, or last integer key */
   int skip;        /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */
-#endif
 };
 
 /*
-** Potential values for BtCursor.eState. The first two values (VALID and 
-** INVALID) may occur in any build. The third (REQUIRESEEK) may only occur 
-** if sqlite was compiled without the OMIT_SHARED_CACHE symbol defined.
+** Potential values for BtCursor.eState.
 **
 ** CURSOR_VALID:
 **   Cursor points to a valid entry. getPayload() etc. may be called.
@@ -425,7 +421,8 @@ struct BtCursor {
 */
 #if SQLITE_TEST
 # define TRACE(X)   if( sqlite3_btree_trace )\
-                        { sqlite3DebugPrintf X; fflush(stdout); }
+/*                        { sqlite3DebugPrintf X; fflush(stdout); } */ \
+{ printf X; fflush(stdout); }
 int sqlite3_btree_trace=0;  /* True to enable tracing */
 #else
 # define TRACE(X)
@@ -434,7 +431,7 @@ int sqlite3_btree_trace=0;  /* True to enable tracing */
 /*
 ** Forward declaration
 */
-static int checkReadLocks(BtShared*,Pgno,BtCursor*);
+static int checkReadLocks(Btree*,Pgno,BtCursor*);
 
 /*
 ** Read or write a two- and four-byte big-endian integer values.
@@ -509,105 +506,8 @@ struct BtLock {
   #define queryTableLock(a,b,c) SQLITE_OK
   #define lockTable(a,b,c) SQLITE_OK
   #define unlockAllTables(a)
-  #define restoreOrClearCursorPosition(a,b) SQLITE_OK
-  #define saveAllCursors(a,b,c) SQLITE_OK
-
 #else
 
-static void releasePage(MemPage *pPage);
-
-/*
-** Save the current cursor position in the variables BtCursor.nKey 
-** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
-*/
-static int saveCursorPosition(BtCursor *pCur){
-  int rc;
-
-  assert( CURSOR_VALID==pCur->eState );
-  assert( 0==pCur->pKey );
-
-  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
-
-  /* If this is an intKey table, then the above call to BtreeKeySize()
-  ** stores the integer key in pCur->nKey. In this case this value is
-  ** all that is required. Otherwise, if pCur is not open on an intKey
-  ** table, then malloc space for and store the pCur->nKey bytes of key 
-  ** data.
-  */
-  if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
-    void *pKey = sqliteMalloc(pCur->nKey);
-    if( pKey ){
-      rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
-      if( rc==SQLITE_OK ){
-        pCur->pKey = pKey;
-      }else{
-        sqliteFree(pKey);
-      }
-    }else{
-      rc = SQLITE_NOMEM;
-    }
-  }
-  assert( !pCur->pPage->intKey || !pCur->pKey );
-
-  if( rc==SQLITE_OK ){
-    releasePage(pCur->pPage);
-    pCur->pPage = 0;
-    pCur->eState = CURSOR_REQUIRESEEK;
-  }
-
-  return rc;
-}
-
-/*
-** Save the positions of all cursors except pExcept open on the table 
-** with root-page iRoot. Usually, this is called just before cursor
-** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
-*/
-static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
-  BtCursor *p;
-  if( sqlite3ThreadDataReadOnly()->useSharedData ){
-    for(p=pBt->pCursor; p; p=p->pNext){
-      if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && 
-          p->eState==CURSOR_VALID ){
-        int rc = saveCursorPosition(p);
-        if( SQLITE_OK!=rc ){
-          return rc;
-        }
-      }
-    }
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Restore the cursor to the position it was in (or as close to as possible)
-** when saveCursorPosition() was called. Note that this call deletes the 
-** saved position info stored by saveCursorPosition(), so there can be
-** at most one effective restoreOrClearCursorPosition() call after each 
-** saveCursorPosition().
-**
-** If the second argument argument - doSeek - is false, then instead of 
-** returning the cursor to it's saved position, any saved position is deleted
-** and the cursor state set to CURSOR_INVALID.
-*/
-static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
-  int rc = SQLITE_OK;
-  assert( sqlite3ThreadDataReadOnly()->useSharedData );
-  assert( pCur->eState==CURSOR_REQUIRESEEK );
-  pCur->eState = CURSOR_INVALID;
-  if( doSeek ){
-    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
-  }
-  if( rc==SQLITE_OK ){
-    sqliteFree(pCur->pKey);
-    pCur->pKey = 0;
-    assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
-  }
-  return rc;
-}
-
-#define restoreOrClearCursorPosition(p,x) \
-  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
 
 /*
 ** Query to see if btree handle p may obtain a lock of type eLock 
@@ -747,6 +647,98 @@ static void unlockAllTables(Btree *p){
 }
 #endif /* SQLITE_OMIT_SHARED_CACHE */
 
+static void releasePage(MemPage *pPage);  /* Forward reference */
+
+/*
+** Save the current cursor position in the variables BtCursor.nKey 
+** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
+*/
+static int saveCursorPosition(BtCursor *pCur){
+  int rc;
+
+  assert( CURSOR_VALID==pCur->eState );
+  assert( 0==pCur->pKey );
+
+  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
+
+  /* If this is an intKey table, then the above call to BtreeKeySize()
+  ** stores the integer key in pCur->nKey. In this case this value is
+  ** all that is required. Otherwise, if pCur is not open on an intKey
+  ** table, then malloc space for and store the pCur->nKey bytes of key 
+  ** data.
+  */
+  if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
+    void *pKey = sqliteMalloc(pCur->nKey);
+    if( pKey ){
+      rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
+      if( rc==SQLITE_OK ){
+        pCur->pKey = pKey;
+      }else{
+        sqliteFree(pKey);
+      }
+    }else{
+      rc = SQLITE_NOMEM;
+    }
+  }
+  assert( !pCur->pPage->intKey || !pCur->pKey );
+
+  if( rc==SQLITE_OK ){
+    releasePage(pCur->pPage);
+    pCur->pPage = 0;
+    pCur->eState = CURSOR_REQUIRESEEK;
+  }
+
+  return rc;
+}
+
+/*
+** Save the positions of all cursors except pExcept open on the table 
+** with root-page iRoot. Usually, this is called just before cursor
+** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
+*/
+static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
+  BtCursor *p;
+  for(p=pBt->pCursor; p; p=p->pNext){
+    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && 
+        p->eState==CURSOR_VALID ){
+      int rc = saveCursorPosition(p);
+      if( SQLITE_OK!=rc ){
+        return rc;
+      }
+    }
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Restore the cursor to the position it was in (or as close to as possible)
+** when saveCursorPosition() was called. Note that this call deletes the 
+** saved position info stored by saveCursorPosition(), so there can be
+** at most one effective restoreOrClearCursorPosition() call after each 
+** saveCursorPosition().
+**
+** If the second argument argument - doSeek - is false, then instead of 
+** returning the cursor to it's saved position, any saved position is deleted
+** and the cursor state set to CURSOR_INVALID.
+*/
+static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
+  int rc = SQLITE_OK;
+  assert( pCur->eState==CURSOR_REQUIRESEEK );
+  pCur->eState = CURSOR_INVALID;
+  if( doSeek ){
+    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
+  }
+  if( rc==SQLITE_OK ){
+    sqliteFree(pCur->pKey);
+    pCur->pKey = 0;
+    assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
+  }
+  return rc;
+}
+
+#define restoreOrClearCursorPosition(p,x) \
+  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
+
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
 ** These macros define the location of the pointer-map entry for a 
@@ -1048,91 +1040,6 @@ static int ptrmapPutOvfl(MemPage *pPage, int iCell){
 #endif
 
 
-/*
-** Do sanity checking on a page.  Throw an exception if anything is
-** not right.
-**
-** This routine is used for internal error checking only.  It is omitted
-** from most builds.
-*/
-#if defined(BTREE_DEBUG) && !defined(NDEBUG) && 0
-static void _pageIntegrity(MemPage *pPage){
-  int usableSize;
-  u8 *data;
-  int i, j, idx, c, pc, hdr, nFree;
-  int cellOffset;
-  int nCell, cellLimit;
-  u8 *used;
-
-  used = sqliteMallocRaw( pPage->pBt->pageSize );
-  if( used==0 ) return;
-  usableSize = pPage->pBt->usableSize;
-  assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] );
-  hdr = pPage->hdrOffset;
-  assert( hdr==(pPage->pgno==1 ? 100 : 0) );
-  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
-  c = pPage->aData[hdr];
-  if( pPage->isInit ){
-    assert( pPage->leaf == ((c & PTF_LEAF)!=0) );
-    assert( pPage->zeroData == ((c & PTF_ZERODATA)!=0) );
-    assert( pPage->leafData == ((c & PTF_LEAFDATA)!=0) );
-    assert( pPage->intKey == ((c & (PTF_INTKEY|PTF_LEAFDATA))!=0) );
-    assert( pPage->hasData ==
-             !(pPage->zeroData || (!pPage->leaf && pPage->leafData)) );
-    assert( pPage->cellOffset==pPage->hdrOffset+12-4*pPage->leaf );
-    assert( pPage->nCell = get2byte(&pPage->aData[hdr+3]) );
-  }
-  data = pPage->aData;
-  memset(used, 0, usableSize);
-  for(i=0; i<hdr+10-pPage->leaf*4; i++) used[i] = 1;
-  nFree = 0;
-  pc = get2byte(&data[hdr+1]);
-  while( pc ){
-    int size;
-    assert( pc>0 && pc<usableSize-4 );
-    size = get2byte(&data[pc+2]);
-    assert( pc+size<=usableSize );
-    nFree += size;
-    for(i=pc; i<pc+size; i++){
-      assert( used[i]==0 );
-      used[i] = 1;
-    }
-    pc = get2byte(&data[pc]);
-  }
-  idx = 0;
-  nCell = get2byte(&data[hdr+3]);
-  cellLimit = get2byte(&data[hdr+5]);
-  assert( pPage->isInit==0 
-         || pPage->nFree==nFree+data[hdr+7]+cellLimit-(cellOffset+2*nCell) );
-  cellOffset = pPage->cellOffset;
-  for(i=0; i<nCell; i++){
-    int size;
-    pc = get2byte(&data[cellOffset+2*i]);
-    assert( pc>0 && pc<usableSize-4 );
-    size = cellSize(pPage, &data[pc]);
-    assert( pc+size<=usableSize );
-    for(j=pc; j<pc+size; j++){
-      assert( used[j]==0 );
-      used[j] = 1;
-    }
-  }
-  for(i=cellOffset+2*nCell; i<cellimit; i++){
-    assert( used[i]==0 );
-    used[i] = 1;
-  }
-  nFree = 0;
-  for(i=0; i<usableSize; i++){
-    assert( used[i]<=1 );
-    if( used[i]==0 ) nFree++;
-  }
-  assert( nFree==data[hdr+7] );
-  sqliteFree(used);
-}
-#define pageIntegrity(X) _pageIntegrity(X)
-#else
-# define pageIntegrity(X)
-#endif
-
 /* A bunch of assert() statements to check the transaction state variables
 ** of handle p (type Btree*) are internally consistent.
 */
@@ -1439,7 +1346,6 @@ static int initPage(
   }
 
   pPage->isInit = 1;
-  pageIntegrity(pPage);
   return SQLITE_OK;
 }
 
@@ -1470,7 +1376,6 @@ static void zeroPage(MemPage *pPage, int flags){
   pPage->idxShift = 0;
   pPage->nCell = 0;
   pPage->isInit = 1;
-  pageIntegrity(pPage);
 }
 
 /*
@@ -1591,9 +1496,9 @@ int sqlite3BtreeOpen(
   */
 #if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
   #ifdef SQLITE_OMIT_MEMORYDB
-  const int isMemdb = !zFilename;
+    const int isMemdb = 0;
   #else
-  const int isMemdb = !zFilename || (strcmp(zFilename, ":memory:")?0:1);
+    const int isMemdb = zFilename && !strcmp(zFilename, ":memory:");
   #endif
 #endif
 
@@ -1645,8 +1550,13 @@ int sqlite3BtreeOpen(
     return SQLITE_NOMEM;
   }
   rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3pager_read_fileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
+  }
   if( rc!=SQLITE_OK ){
-    if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
+    if( pBt->pPager ){
+      sqlite3pager_close(pBt->pPager);
+    }
     sqliteFree(pBt);
     sqliteFree(p);
     *ppBtree = 0;
@@ -1659,7 +1569,6 @@ int sqlite3BtreeOpen(
   pBt->pCursor = 0;
   pBt->pPage1 = 0;
   pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
-  sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
   pBt->pageSize = get2byte(&zDbHeader[16]);
   if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
        || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
@@ -2022,13 +1931,15 @@ static int lockBtreeWithRetry(Btree *pRef){
 */
 static void unlockBtreeIfUnused(BtShared *pBt){
   if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
-    if( pBt->pPage1->aData==0 ){
-      MemPage *pPage = pBt->pPage1;
-      pPage->aData = &((u8*)pPage)[-pBt->pageSize];
-      pPage->pBt = pBt;
-      pPage->pgno = 1;
+    if( sqlite3pager_refcount(pBt->pPager)>=1 ){
+      if( pBt->pPage1->aData==0 ){
+        MemPage *pPage = pBt->pPage1;
+        pPage->aData = &((u8*)pPage)[-pBt->pageSize];
+        pPage->pBt = pBt;
+        pPage->pgno = 1;
+      }
+      releasePage(pBt->pPage1);
     }
-    releasePage(pBt->pPage1);
     pBt->pPage1 = 0;
     pBt->inStmt = 0;
   }
@@ -2548,7 +2459,7 @@ static int countWriteCursors(BtShared *pBt){
 }
 #endif
 
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
 /*
 ** Print debugging information about all cursors to standard output.
 */
@@ -2778,7 +2689,7 @@ int sqlite3BtreeCursor(
     if( pBt->readOnly ){
       return SQLITE_READONLY;
     }
-    if( checkReadLocks(pBt, iTable, 0) ){
+    if( checkReadLocks(p, iTable, 0) ){
       return SQLITE_LOCKED;
     }
   }
@@ -2980,7 +2891,6 @@ static int getPayload(
   assert( pCur->eState==CURSOR_VALID );
   pBt = pCur->pBtree->pBt;
   pPage = pCur->pPage;
-  pageIntegrity(pPage);
   assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
   getCellInfo(pCur);
   aPayload = pCur->info.pCell + pCur->info.nHeader;
@@ -3118,7 +3028,6 @@ static const unsigned char *fetchPayload(
   assert( pCur!=0 && pCur->pPage!=0 );
   assert( pCur->eState==CURSOR_VALID );
   pPage = pCur->pPage;
-  pageIntegrity(pPage);
   assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
   getCellInfo(pCur);
   aPayload = pCur->info.pCell;
@@ -3180,7 +3089,6 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
   assert( pCur->eState==CURSOR_VALID );
   rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
   if( rc ) return rc;
-  pageIntegrity(pNewPage);
   pNewPage->idxParent = pCur->idx;
   pOldPage = pCur->pPage;
   pOldPage->idxShift = 0;
@@ -3228,10 +3136,8 @@ static void moveToParent(BtCursor *pCur){
   pPage = pCur->pPage;
   assert( pPage!=0 );
   assert( !isRootPage(pPage) );
-  pageIntegrity(pPage);
   pParent = pPage->pParent;
   assert( pParent!=0 );
-  pageIntegrity(pParent);
   idxParent = pPage->idxParent;
   sqlite3pager_ref(pParent->aData);
   releasePage(pPage);
@@ -3261,7 +3167,6 @@ static int moveToRoot(BtCursor *pCur){
       return rc;
     }
     releasePage(pCur->pPage);
-    pageIntegrity(pRoot);
     pCur->pPage = pRoot;
   }
   pCur->idx = 0;
@@ -3405,7 +3310,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
     assert( pCur->pPage->nCell==0 );
     return SQLITE_OK;
   }
-   for(;;){
+  for(;;){
     int lwr, upr;
     Pgno chldPg;
     MemPage *pPage = pCur->pPage;
@@ -3415,7 +3320,6 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
     if( !pPage->intKey && pKey==0 ){
       return SQLITE_CORRUPT_BKPT;
     }
-    pageIntegrity(pPage);
     while( lwr<=upr ){
       void *pCellKey;
       i64 nCellKey;
@@ -3668,14 +3572,14 @@ static int allocatePage(
   int rc;
   int n;     /* Number of pages on the freelist */
   int k;     /* Number of leaves on the trunk of the freelist */
+  MemPage *pTrunk = 0;
+  MemPage *pPrevTrunk = 0;
 
   pPage1 = pBt->pPage1;
   n = get4byte(&pPage1->aData[36]);
   if( n>0 ){
     /* There are pages on the freelist.  Reuse one of those pages. */
-    MemPage *pTrunk = 0;
     Pgno iTrunk;
-    MemPage *pPrevTrunk = 0;
     u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
     
     /* If the 'exact' parameter was true and a query of the pointer-map
@@ -3716,16 +3620,8 @@ static int allocatePage(
       }
       rc = getPage(pBt, iTrunk, &pTrunk);
       if( rc ){
-        releasePage(pPrevTrunk);
-        return rc;
-      }
-
-      /* TODO: This should move to after the loop? */
-      rc = sqlite3pager_write(pTrunk->aData);
-      if( rc ){
-        releasePage(pTrunk);
-        releasePage(pPrevTrunk);
-        return rc;
+        pTrunk = 0;
+        goto end_allocate_page;
       }
 
       k = get4byte(&pTrunk->aData[4]);
@@ -3734,6 +3630,10 @@ 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);
+        if( rc ){
+          goto end_allocate_page;
+        }
         *pPgno = iTrunk;
         memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
         *ppPage = pTrunk;
@@ -3741,7 +3641,8 @@ static int allocatePage(
         TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
       }else if( k>pBt->usableSize/4 - 8 ){
         /* Value of k is out of range.  Database corruption */
-        return SQLITE_CORRUPT_BKPT;
+        rc = SQLITE_CORRUPT_BKPT;
+        goto end_allocate_page;
 #ifndef SQLITE_OMIT_AUTOVACUUM
       }else if( searchList && nearby==iTrunk ){
         /* The list is being searched and this trunk page is the page
@@ -3750,6 +3651,10 @@ static int allocatePage(
         assert( *pPgno==iTrunk );
         *ppPage = pTrunk;
         searchList = 0;
+        rc = sqlite3pager_write(pTrunk->aData);
+        if( rc ){
+          goto end_allocate_page;
+        }
         if( k==0 ){
           if( !pPrevTrunk ){
             memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
@@ -3765,26 +3670,26 @@ static int allocatePage(
           Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
           rc = getPage(pBt, iNewTrunk, &pNewTrunk);
           if( rc!=SQLITE_OK ){
-            releasePage(pTrunk);
-            releasePage(pPrevTrunk);
-            return rc;
+            goto end_allocate_page;
           }
           rc = sqlite3pager_write(pNewTrunk->aData);
           if( rc!=SQLITE_OK ){
             releasePage(pNewTrunk);
-            releasePage(pTrunk);
-            releasePage(pPrevTrunk);
-            return rc;
+            goto end_allocate_page;
           }
           memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
           put4byte(&pNewTrunk->aData[4], k-1);
           memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
+          releasePage(pNewTrunk);
           if( !pPrevTrunk ){
             put4byte(&pPage1->aData[32], iNewTrunk);
           }else{
+            rc = sqlite3pager_write(pPrevTrunk->aData);
+            if( rc ){
+              goto end_allocate_page;
+            }
             put4byte(&pPrevTrunk->aData[0], iNewTrunk);
           }
-          releasePage(pNewTrunk);
         }
         pTrunk = 0;
         TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
@@ -3794,6 +3699,10 @@ static int allocatePage(
         int closest;
         Pgno iPage;
         unsigned char *aData = pTrunk->aData;
+        rc = sqlite3pager_write(aData);
+        if( rc ){
+          goto end_allocate_page;
+        }
         if( nearby>0 ){
           int i, dist;
           closest = 0;
@@ -3837,8 +3746,8 @@ static int allocatePage(
         }
       }
       releasePage(pPrevTrunk);
+      pPrevTrunk = 0;
     }while( searchList );
-    releasePage(pTrunk);
   }else{
     /* There are no pages on the freelist, so create a new page at the
     ** end of the file */
@@ -3867,6 +3776,10 @@ static int allocatePage(
   }
 
   assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+
+end_allocate_page:
+  releasePage(pTrunk);
+  releasePage(pPrevTrunk);
   return rc;
 }
 
@@ -4267,7 +4180,6 @@ static int insertCell(
     put2byte(&data[ins], idx);
     put2byte(&data[hdr+3], pPage->nCell);
     pPage->idxShift = 1;
-    pageIntegrity(pPage);
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( pPage->pBt->autoVacuum ){
       /* The cell may contain a pointer to an overflow page. If so, write
@@ -5007,8 +4919,6 @@ static int balance_nonroot(MemPage *pPage){
   ** But the parent page will always be initialized.
   */
   assert( pParent->isInit );
-  /* assert( pPage->isInit ); // No! pPage might have been added to freelist */
-  /* pageIntegrity(pPage);    // No! pPage might have been added to freelist */ 
   rc = balance(pParent, 0);
   
   /*
@@ -5215,27 +5125,35 @@ static int balance(MemPage *pPage, int insert){
 
 /*
 ** This routine checks all cursors that point to table pgnoRoot.
-** If any of those cursors other than pExclude were opened with 
-** wrFlag==0 then this routine returns SQLITE_LOCKED.  If all
-** cursors that point to pgnoRoot were opened with wrFlag==1
-** then this routine returns SQLITE_OK.
+** If any of those cursors were opened with wrFlag==0 in a different
+** database connection (a database connection that shares the pager
+** cache with the current connection) and that other connection 
+** is not in the ReadUncommmitted state, then this routine returns 
+** SQLITE_LOCKED.
 **
 ** In addition to checking for read-locks (where a read-lock 
 ** means a cursor opened with wrFlag==0) this routine also moves
-** all cursors other than pExclude so that they are pointing to the 
-** first Cell on root page.  This is necessary because an insert 
+** all cursors write cursors so that they are pointing to the 
+** first Cell on the root page.  This is necessary because an insert 
 ** or delete might change the number of cells on a page or delete
 ** a page entirely and we do not want to leave any cursors 
 ** pointing to non-existant pages or cells.
 */
-static int checkReadLocks(BtShared *pBt, Pgno pgnoRoot, BtCursor *pExclude){
+static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
   BtCursor *p;
+  BtShared *pBt = pBtree->pBt;
+  sqlite3 *db = pBtree->pSqlite;
   for(p=pBt->pCursor; p; p=p->pNext){
-    u32 flags = (p->pBtree->pSqlite ? p->pBtree->pSqlite->flags : 0);
-    if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue;
-    if( p->wrFlag==0 && flags&SQLITE_ReadUncommitted ) continue;
-    if( p->wrFlag==0 ) return SQLITE_LOCKED;
-    if( p->pPage->pgno!=p->pgnoRoot ){
+    if( p==pExclude ) continue;
+    if( p->eState!=CURSOR_VALID ) continue;
+    if( p->pgnoRoot!=pgnoRoot ) continue;
+    if( p->wrFlag==0 ){
+      sqlite3 *dbOther = p->pBtree->pSqlite;
+      if( dbOther==0 ||
+         (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
+        return SQLITE_LOCKED;
+      }
+    }else if( p->pPage->pgno!=p->pgnoRoot ){
       moveToRoot(p);
     }
   }
@@ -5272,7 +5190,7 @@ int sqlite3BtreeInsert(
   if( !pCur->wrFlag ){
     return SQLITE_PERM;   /* Cursor not open for writing */
   }
-  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
+  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
     return SQLITE_LOCKED; /* The table pCur points to has a read lock */
   }
 
@@ -5354,7 +5272,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
   if( !pCur->wrFlag ){
     return SQLITE_PERM;   /* Did not open this cursor for writing */
   }
-  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
+  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
     return SQLITE_LOCKED; /* The table pCur points to has a read lock */
   }
 
@@ -5631,25 +5549,13 @@ cleardatabasepage_out:
 */
 int sqlite3BtreeClearTable(Btree *p, int iTable){
   int rc;
-  BtCursor *pCur;
   BtShared *pBt = p->pBt;
-  sqlite3 *db = p->pSqlite;
   if( p->inTrans!=TRANS_WRITE ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
-
-  /* If this connection is not in read-uncommitted mode and currently has
-  ** a read-cursor open on the table being cleared, return SQLITE_LOCKED.
-  */
-  if( 0==db || 0==(db->flags&SQLITE_ReadUncommitted) ){
-    for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-      if( pCur->pBtree==p && pCur->pgnoRoot==(Pgno)iTable ){
-        if( 0==pCur->wrFlag ){
-          return SQLITE_LOCKED;
-        }
-        moveToRoot(pCur);
-      }
-    }
+  rc = checkReadLocks(p, iTable, 0);
+  if( rc ){
+    return rc;
   }
 
   /* Save the position of all cursors open on this table */
@@ -5969,7 +5875,7 @@ int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){
 }
 #endif
 
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
 /*
 ** Fill aResult[] with information about the entry and page that the
 ** cursor is pointing to.
@@ -5997,14 +5903,12 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
     return rc;
   }
 
-  pageIntegrity(pPage);
   assert( pPage->isInit );
   getTempCursor(pCur, &tmpCur);
   while( upCnt-- ){
     moveToParent(&tmpCur);
   }
   pPage = tmpCur.pPage;
-  pageIntegrity(pPage);
   aResult[0] = sqlite3pager_pagenumber(pPage->aData);
   assert( aResult[0]==pPage->pgno );
   aResult[1] = tmpCur.idx;
@@ -6054,10 +5958,12 @@ Pager *sqlite3BtreePager(Btree *p){
 typedef struct IntegrityCk IntegrityCk;
 struct IntegrityCk {
   BtShared *pBt;    /* The tree being checked out */
-  Pager *pPager; /* The associated pager.  Also accessible by pBt->pPager */
-  int nPage;     /* Number of pages in the database */
-  int *anRef;    /* Number of times each page is referenced */
-  char *zErrMsg; /* An error message.  NULL of no errors seen. */
+  Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
+  int nPage;        /* Number of pages in the database */
+  int *anRef;       /* Number of times each page is referenced */
+  int mxErr;        /* Stop accumulating errors when this reaches zero */
+  char *zErrMsg;    /* An error message.  NULL if no errors seen. */
+  int nErr;         /* Number of messages written to zErrMsg so far */
 };
 
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
@@ -6072,6 +5978,9 @@ static void checkAppendMsg(
 ){
   va_list ap;
   char *zMsg2;
+  if( !pCheck->mxErr ) return;
+  pCheck->mxErr--;
+  pCheck->nErr++;
   va_start(ap, zFormat);
   zMsg2 = sqlite3VMPrintf(zFormat, ap);
   va_end(ap);
@@ -6155,7 +6064,7 @@ static void checkList(
   int i;
   int expected = N;
   int iFirst = iPage;
-  while( N-- > 0 ){
+  while( N-- > 0 && pCheck->mxErr ){
     unsigned char *pOvfl;
     if( iPage<1 ){
       checkAppendMsg(pCheck, zContext,
@@ -6267,7 +6176,7 @@ static int checkTreePage(
   /* Check out all the cells.
   */
   depth = 0;
-  for(i=0; i<pPage->nCell; i++){
+  for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
     u8 *pCell;
     int sz;
     CellInfo info;
@@ -6382,7 +6291,13 @@ static int checkTreePage(
 ** and a pointer to that error message is returned.  The calling function
 ** is responsible for freeing the error message when it is done.
 */
-char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
+char *sqlite3BtreeIntegrityCheck(
+  Btree *p,     /* The btree to be checked */
+  int *aRoot,   /* An array of root pages numbers for individual trees */
+  int nRoot,    /* Number of entries in aRoot[] */
+  int mxErr,    /* Stop reporting errors after this many */
+  int *pnErr    /* Write number of errors seen to this variable */
+){
   int i;
   int nRef;
   IntegrityCk sCheck;
@@ -6395,6 +6310,9 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
   sCheck.pBt = pBt;
   sCheck.pPager = pBt->pPager;
   sCheck.nPage = sqlite3pager_pagecount(sCheck.pPager);
+  sCheck.mxErr = mxErr;
+  sCheck.nErr = 0;
+  *pnErr = 0;
   if( sCheck.nPage==0 ){
     unlockBtreeIfUnused(pBt);
     return 0;
@@ -6402,6 +6320,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
   sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
   if( !sCheck.anRef ){
     unlockBtreeIfUnused(pBt);
+    *pnErr = 1;
     return sqlite3MPrintf("Unable to malloc %d bytes", 
         (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
   }
@@ -6419,7 +6338,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
 
   /* Check all the tables.
   */
-  for(i=0; i<nRoot; i++){
+  for(i=0; i<nRoot && sCheck.mxErr; i++){
     if( aRoot[i]==0 ) continue;
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( pBt->autoVacuum && aRoot[i]>1 ){
@@ -6431,7 +6350,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
 
   /* Make sure every page in the file is referenced
   */
-  for(i=1; i<=sCheck.nPage; i++){
+  for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
 #ifdef SQLITE_OMIT_AUTOVACUUM
     if( sCheck.anRef[i]==0 ){
       checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
@@ -6464,6 +6383,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
   /* Clean  up and report errors.
   */
   sqliteFree(sCheck.anRef);
+  *pnErr = sCheck.nErr;
   return sCheck.zErrMsg;
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -6522,7 +6442,6 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
     rc = sqlite3pager_get(pBtFrom->pPager, i, &pPage);
     if( rc ) break;
     rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage);
-    if( rc ) break;
     sqlite3pager_unref(pPage);
   }
   for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
index 896ebf11b13a6bb24511d7b6a08e6384acc2a2f2..2f573e27f858ae6b89871c04f15417262fadddfd 100644 (file)
@@ -131,7 +131,7 @@ const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
 int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
 int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
 
-char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
+char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
 struct Pager *sqlite3BtreePager(Btree*);
 
 
index 5294c1a3161292e315ade396f06a4eeff2defb59..f600395b480decb1f1f08973de0b172be101329d 100644 (file)
@@ -1077,8 +1077,12 @@ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
       sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
           pCol->zName);
     }else{
+      Expr *pCopy;
       sqlite3ExprDelete(pCol->pDflt);
-      pCol->pDflt = sqlite3ExprDup(pExpr);
+      pCol->pDflt = pCopy = sqlite3ExprDup(pExpr);
+      if( pCopy ){
+        sqlite3TokenCopy(&pCopy->span, &pExpr->span);
+      }
     }
   }
   sqlite3ExprDelete(pExpr);
@@ -1586,7 +1590,8 @@ void sqlite3CreateView(
   Token *pName1,     /* The token that holds the name of the view */
   Token *pName2,     /* The token that holds the name of the view */
   Select *pSelect,   /* A SELECT statement that will become the new view */
-  int isTemp         /* TRUE for a TEMPORARY view */
+  int isTemp,        /* TRUE for a TEMPORARY view */
+  int noErr          /* Suppress error messages if VIEW already exists */
 ){
   Table *p;
   int n;
@@ -1601,7 +1606,7 @@ void sqlite3CreateView(
     sqlite3SelectDelete(pSelect);
     return;
   }
-  sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, 0);
+  sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
   p = pParse->pNewTable;
   if( p==0 || pParse->nErr ){
     sqlite3SelectDelete(pSelect);
@@ -2935,15 +2940,6 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
   }
 }
 
-/*
-** Add an alias to the last identifier on the given identifier list.
-*/
-void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){
-  if( pList && pList->nSrc>0 ){
-    pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken);
-  }
-}
-
 /*
 ** Delete an entire SrcList including all its substructure.
 */
@@ -2963,6 +2959,74 @@ void sqlite3SrcListDelete(SrcList *pList){
   sqliteFree(pList);
 }
 
+/*
+** This routine is called by the parser to add a new term to the
+** end of a growing FROM clause.  The "p" parameter is the part of
+** the FROM clause that has already been constructed.  "p" is NULL
+** if this is the first term of the FROM clause.  pTable and pDatabase
+** are the name of the table and database named in the FROM clause term.
+** pDatabase is NULL if the database name qualifier is missing - the
+** usual case.  If the term has a alias, then pAlias points to the
+** alias token.  If the term is a subquery, then pSubquery is the
+** SELECT statement that the subquery encodes.  The pTable and
+** pDatabase parameters are NULL for subqueries.  The pOn and pUsing
+** parameters are the content of the ON and USING clauses.
+**
+** Return a new SrcList which encodes is the FROM with the new
+** term added.
+*/
+SrcList *sqlite3SrcListAppendFromTerm(
+  SrcList *p,             /* The left part of the FROM clause already seen */
+  Token *pTable,          /* Name of the table to add to the FROM clause */
+  Token *pDatabase,       /* Name of the database containing pTable */
+  Token *pAlias,          /* The right-hand side of the AS subexpression */
+  Select *pSubquery,      /* A subquery used in place of a table name */
+  Expr *pOn,              /* The ON clause of a join */
+  IdList *pUsing          /* The USING clause of a join */
+){
+  struct SrcList_item *pItem;
+  p = sqlite3SrcListAppend(p, pTable, pDatabase);
+  if( p==0 || p->nSrc==0 ){
+    sqlite3ExprDelete(pOn);
+    sqlite3IdListDelete(pUsing);
+    sqlite3SelectDelete(pSubquery);
+    return p;
+  }
+  pItem = &p->a[p->nSrc-1];
+  if( pAlias && pAlias->n ){
+    pItem->zAlias = sqlite3NameFromToken(pAlias);
+  }
+  pItem->pSelect = pSubquery;
+  pItem->pOn = pOn;
+  pItem->pUsing = pUsing;
+  return p;
+}
+
+/*
+** When building up a FROM clause in the parser, the join operator
+** is initially attached to the left operand.  But the code generator
+** expects the join operator to be on the right operand.  This routine
+** Shifts all join operators from left to right for an entire FROM
+** clause.
+**
+** Example: Suppose the join is like this:
+**
+**           A natural cross join B
+**
+** The operator is "natural cross join".  The A and B operands are stored
+** in p->a[0] and p->a[1], respectively.  The parser initially stores the
+** operator with A.  This routine shifts that operator over to B.
+*/
+void sqlite3SrcListShiftJoinType(SrcList *p){
+  if( p && p->a ){
+    int i;
+    for(i=p->nSrc-1; i>0; i--){
+      p->a[i].jointype = p->a[i-1].jointype;
+    }
+    p->a[0].jointype = 0;
+  }
+}
+
 /*
 ** Begin a transaction
 */
index 68d17a701351c2d36b1b09b73fa3d16ce2904602..a8cbd2630cf6060f010dc167e90fd0825b52f42b 100644 (file)
@@ -237,11 +237,11 @@ static void computeJD(DateTime *p){
   X2 = 30.6001*(M+1);
   p->rJD = X1 + X2 + D + B - 1524.5;
   p->validJD = 1;
-  p->validYMD = 0;
   if( p->validHMS ){
     p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
     if( p->validTZ ){
       p->rJD -= p->tz*60/86400.0;
+      p->validYMD = 0;
       p->validHMS = 0;
       p->validTZ = 0;
     }
@@ -360,6 +360,7 @@ static void computeYMD(DateTime *p){
 static void computeHMS(DateTime *p){
   int Z, s;
   if( p->validHMS ) return;
+  computeJD(p);
   Z = p->rJD + 0.5;
   s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
   p->s = 0.001*s;
@@ -415,8 +416,7 @@ static double localtimeOffset(DateTime *p){
   computeJD(&x);
   t = (x.rJD-2440587.5)*86400.0 + 0.5;
   sqlite3OsEnterMutex();
-  pTm = php_localtime_r
-(&t, &tmbuf);
+  pTm = php_localtime_r(&t, &tmbuf);
   y.Y = pTm->tm_year + 1900;
   y.M = pTm->tm_mon + 1;
   y.D = pTm->tm_mday;
@@ -585,7 +585,7 @@ static int parseModifier(const char *zMod, DateTime *p){
         if( z[0]=='-' ) tx.rJD = -tx.rJD;
         computeJD(p);
         clearYMD_HMS_TZ(p);
-       p->rJD += tx.rJD;
+        p->rJD += tx.rJD;
         rc = 0;
         break;
       }
@@ -813,9 +813,9 @@ static void strftimeFunc(
       switch( zFmt[i] ){
         case 'd':  sprintf(&z[j],"%02d",x.D); j+=2; break;
         case 'f': {
-          int s = x.s;
-          int ms = (x.s - s)*1000.0;
-          sprintf(&z[j],"%02d.%03d",s,ms);
+          double s = x.s;
+          if( s>59.999 ) s = 59.999;
+          sqlite3_snprintf(7, &z[j],"%02.3f", s);
           j += strlen(&z[j]);
           break;
         }
@@ -828,7 +828,7 @@ static void strftimeFunc(
           y.M = 1;
           y.D = 1;
           computeJD(&y);
-          nDay = x.rJD - y.rJD;
+          nDay = x.rJD - y.rJD + 0.5;
           if( zFmt[i]=='W' ){
             int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
             wd = ((int)(x.rJD+0.5)) % 7;
@@ -848,7 +848,7 @@ static void strftimeFunc(
           j += strlen(&z[j]);
           break;
         }
-        case 'S':  sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
+        case 'S':  sprintf(&z[j],"%02d",(int)x.s); j+=2; break;
         case 'w':  z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
         case 'Y':  sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
         case '%':  z[j++] = '%'; break;
@@ -948,9 +948,21 @@ static void currentTimeFunc(
   }
 #endif
 
-  sqlite3OsEnterMutex();
-  strftime(zBuf, 20, zFormat, gmtime(&t));
-  sqlite3OsLeaveMutex();
+#ifdef HAVE_GMTIME_R
+  {
+    struct tm sNow;
+    gmtime_r(&t, &sNow);
+    strftime(zBuf, 20, zFormat, &sNow);
+  }
+#else
+  {
+    struct tm *pTm;
+    sqlite3OsEnterMutex();
+    pTm = gmtime(&t);
+    strftime(zBuf, 20, zFormat, pTm);
+    sqlite3OsLeaveMutex();
+  }
+#endif
 
   sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
 }
index e26aba5b3895fe8d92bc1cb434cba33a8973a842..22c267cf957def7561c8310ae66e6c43bd03ca64 100644 (file)
@@ -891,22 +891,23 @@ static int lookupName(
             pExpr->iColumn = j==pTab->iPKey ? -1 : j;
             pExpr->affinity = pTab->aCol[j].affinity;
             pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
-            if( pItem->jointype & JT_NATURAL ){
-              /* If this match occurred in the left table of a natural join,
-              ** then skip the right table to avoid a duplicate match */
-              pItem++;
-              i++;
-            }
-            if( (pUsing = pItem->pUsing)!=0 ){
-              /* If this match occurs on a column that is in the USING clause
-              ** of a join, skip the search of the right table of the join
-              ** to avoid a duplicate match there. */
-              int k;
-              for(k=0; k<pUsing->nId; k++){
-                if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
-                  pItem++;
-                  i++;
-                  break;
+            if( i<pSrcList->nSrc-1 ){
+              if( pItem[1].jointype & JT_NATURAL ){
+                /* If this match occurred in the left table of a natural join,
+                ** then skip the right table to avoid a duplicate match */
+                pItem++;
+                i++;
+              }else if( (pUsing = pItem[1].pUsing)!=0 ){
+                /* If this match occurs on a column that is in the USING clause
+                ** of a join, skip the search of the right table of the join
+                ** to avoid a duplicate match there. */
+                int k;
+                for(k=0; k<pUsing->nId; k++){
+                  if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
+                    pItem++;
+                    i++;
+                    break;
+                  }
                 }
               }
             }
@@ -1161,6 +1162,7 @@ static int nameResolverStep(void *pArg, Expr *pExpr){
       int wrong_num_args = 0;     /* True if wrong number of arguments */
       int is_agg = 0;             /* True if is an aggregate function */
       int i;
+      int auth;                   /* Authorization to use the function */
       int nId;                    /* Number of characters in function name */
       const char *zId;            /* The function name. */
       FuncDef *pDef;              /* Information about the function */
@@ -1179,6 +1181,20 @@ static int nameResolverStep(void *pArg, Expr *pExpr){
       }else{
         is_agg = pDef->xFunc==0;
       }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+      if( pDef ){
+        auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
+        if( auth!=SQLITE_OK ){
+          if( auth==SQLITE_DENY ){
+            sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
+                                    pDef->zName);
+            pNC->nErr++;
+          }
+          pExpr->op = TK_NULL;
+          return 1;
+        }
+      }
+#endif
       if( is_agg && !pNC->allowAgg ){
         sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
         pNC->nErr++;
@@ -2192,6 +2208,7 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){
   
 
   switch( pExpr->op ){
+    case TK_AGG_COLUMN:
     case TK_COLUMN: {
       /* Check to see if the column is in one of the tables in the FROM
       ** clause of the aggregate query */
index bf422f92c5b292336ef59bf2dcda0a1193f9ade4..c3444baa0e44c52479097012a0509017815d9d6e 100644 (file)
@@ -547,19 +547,6 @@ static void versionFunc(
   sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
 }
 
-/*
-** The MATCH() function is unimplemented.  If anybody tries to use it,
-** return an error.
-*/
-static void matchStub(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  static const char zErr[] = "MATCH is not implemented";
-  sqlite3_result_error(context, zErr, sizeof(zErr)-1);
-}
-
 
 /*
 ** EXPERIMENTAL - This is not an official function.  The interface may
@@ -654,14 +641,20 @@ static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv
   };
   assert( argc==1 );
   zIn = (u8*)sqlite3_value_text(argv[0]);
-  if( zIn==0 ) zIn = "";
+  if( zIn==0 ) zIn = (u8*)"";
   for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
   if( zIn[i] ){
+    u8 prevcode = iCode[zIn[i]&0x7f];
     zResult[0] = toupper(zIn[i]);
     for(j=1; j<4 && zIn[i]; i++){
       int code = iCode[zIn[i]&0x7f];
       if( code>0 ){
-        zResult[j++] = code + '0';
+        if( code!=prevcode ){
+          prevcode = code;
+          zResult[j++] = code + '0';
+        }
+      }else{
+        prevcode = 0;
       }
     }
     while( j<4 ){
@@ -1036,7 +1029,6 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     { "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 },
-    { "match",              2, 0, SQLITE_UTF8,    0, matchStub },
 #ifdef SQLITE_SOUNDEX
     { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
 #endif
@@ -1109,6 +1101,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     }
   }
   sqlite3RegisterDateTimeFunctions(db);
+  sqlite3_overload_function(db, "MATCH", 2);
 #ifdef SQLITE_SSE
   (void)sqlite3SseFunctions(db);
 #endif
index d4cf74a3d7ef6014f982c4135acb5756f28fec18..adcc37a4cbbf615497aa226e6a57056509bf0a08 100644 (file)
@@ -387,11 +387,9 @@ void sqlite3Insert(
     NameContext sNC;
     memset(&sNC, 0, sizeof(sNC));
     sNC.pParse = pParse;
-    assert( pList!=0 );
     srcTab = -1;
     useTempTable = 0;
-    assert( pList );
-    nColumn = pList->nExpr;
+    nColumn = pList ? pList->nExpr : 0;
     for(i=0; i<nColumn; i++){
       if( sqlite3ExprResolveNames(&sNC, pList->a[i].pExpr) ){
         goto insert_cleanup;
@@ -402,7 +400,7 @@ void sqlite3Insert(
   /* Make sure the number of columns in the source data matches the number
   ** of columns to be inserted into the table.
   */
-  if( pColumn==0 && nColumn!=pTab->nCol ){
+  if( pColumn==0 && nColumn && nColumn!=pTab->nCol ){
     sqlite3ErrorMsg(pParse, 
        "table %S has %d columns but %d values were supplied",
        pTabList, 0, pTab->nCol, nColumn);
@@ -455,7 +453,7 @@ void sqlite3Insert(
   ** key, the set the keyColumn variable to the primary key column index
   ** in the original table definition.
   */
-  if( pColumn==0 ){
+  if( pColumn==0 && nColumn>0 ){
     keyColumn = pTab->iPKey;
   }
 
@@ -618,12 +616,12 @@ void sqlite3Insert(
           if( pColumn->a[j].idx==i ) break;
         }
       }
-      if( pColumn && j>=pColumn->nId ){
+      if( nColumn==0 || (pColumn && j>=pColumn->nId) ){
         sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
       }else if( useTempTable ){
         sqlite3VdbeAddOp(v, OP_Column, srcTab, j); 
       }else if( pSelect ){
-        sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
+        sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
       }else{
         sqlite3ExprCode(pParse, pList->a[j].pExpr);
       }
index c75791e1bd91fcd7f00e3a7616a885c5ae1689c3..00c0f9eeffdcc35b2deda9fa9fb7aae6d0ac9397 100644 (file)
@@ -131,5 +131,6 @@ exec_out:
     *pzErrMsg = 0;
   }
 
+  assert( (rc&db->errMask)==rc );
   return rc;
 }
index 60ec053cfbec34b675b3712fdf4655869f74974c..6af99a6416ed8225173621c531a3b69cf750c341 100644 (file)
@@ -17,6 +17,7 @@
 #define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
 #include "sqlite3ext.h"
 #include "sqliteInt.h"
+#include "os.h"
 #include <string.h>
 #include <ctype.h>
 
 # define sqlite3_declare_vtab 0
 #endif
 
+#ifdef SQLITE_OMIT_SHARED_CACHE
+# define sqlite3_enable_shared_cache 0
+#endif
+
+#ifdef SQLITE_OMIT_TRACE
+# define sqlite3_profile       0
+# define sqlite3_trace         0
+#endif
+
+#ifdef SQLITE_OMIT_GET_TABLE
+# define sqlite3_free_table    0
+# define sqlite3_get_table     0
+#endif
+
 /*
 ** The following structure contains pointers to all SQLite API routines.
 ** A pointer to this structure is passed into extensions when they are
 ** also check to make sure that the pointer to the function is
 ** not NULL before calling it.
 */
-const sqlite3_api_routines sqlite3_api = {
+const sqlite3_api_routines sqlite3_apis = {
   sqlite3_aggregate_context,
   sqlite3_aggregate_count,
   sqlite3_bind_blob,
@@ -153,7 +168,7 @@ const sqlite3_api_routines sqlite3_api = {
   sqlite3_get_autocommit,
   sqlite3_get_auxdata,
   sqlite3_get_table,
-  sqlite3_global_recover,
+  0,     /* Was sqlite3_global_recover(), but that function is deprecated */
   sqlite3_interrupt,
   sqlite3_last_insert_rowid,
   sqlite3_libversion,
@@ -213,30 +228,9 @@ const sqlite3_api_routines sqlite3_api = {
   ** a library that is new enough to support that API.
   *************************************************************************
   */
+  sqlite3_overload_function,
 };
 
-/*
-** The windows implementation of shared-library loaders
-*/
-#if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__)
-# include <windows.h>
-# define SQLITE_LIBRARY_TYPE     HANDLE
-# define SQLITE_OPEN_LIBRARY(A)  LoadLibrary(A)
-# define SQLITE_FIND_SYMBOL(A,B) GetProcAddress(A,B)
-# define SQLITE_CLOSE_LIBRARY(A) FreeLibrary(A)
-#endif /* windows */
-
-/*
-** The unix implementation of shared-library loaders
-*/
-#if defined(HAVE_DLOPEN) && !defined(SQLITE_LIBRARY_TYPE)
-# include <dlfcn.h>
-# define SQLITE_LIBRARY_TYPE     void*
-# define SQLITE_OPEN_LIBRARY(A)  dlopen(A, RTLD_NOW | RTLD_GLOBAL)
-# define SQLITE_FIND_SYMBOL(A,B) dlsym(A,B)
-# define SQLITE_CLOSE_LIBRARY(A) dlclose(A)
-#endif
-
 /*
 ** Attempt to load an SQLite extension library contained in the file
 ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
@@ -255,11 +249,10 @@ int sqlite3_load_extension(
   const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
   char **pzErrMsg       /* Put error message here if not 0 */
 ){
-#ifdef SQLITE_LIBRARY_TYPE
-  SQLITE_LIBRARY_TYPE handle;
+  void *handle;
   int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   char *zErrmsg = 0;
-  SQLITE_LIBRARY_TYPE *aHandle;
+  void **aHandle;
 
   /* Ticket #1863.  To avoid a creating security problems for older
   ** applications that relink against newer versions of SQLite, the
@@ -278,7 +271,7 @@ int sqlite3_load_extension(
     zProc = "sqlite3_extension_init";
   }
 
-  handle = SQLITE_OPEN_LIBRARY(zFile);
+  handle = sqlite3OsDlopen(zFile);
   if( handle==0 ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile);
@@ -286,20 +279,20 @@ int sqlite3_load_extension(
     return SQLITE_ERROR;
   }
   xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
-                   SQLITE_FIND_SYMBOL(handle, zProc);
+                   sqlite3OsDlsym(handle, zProc);
   if( xInit==0 ){
     if( pzErrMsg ){
        *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
                                    zProc, zFile);
     }
-    SQLITE_CLOSE_LIBRARY(handle);
+    sqlite3OsDlclose(handle);
     return SQLITE_ERROR;
-  }else if( xInit(db, &zErrmsg, &sqlite3_api) ){
+  }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
     }
     sqlite3_free(zErrmsg);
-    SQLITE_CLOSE_LIBRARY(handle);
+    sqlite3OsDlclose(handle);
     return SQLITE_ERROR;
   }
 
@@ -315,14 +308,8 @@ int sqlite3_load_extension(
   sqliteFree(db->aExtension);
   db->aExtension = aHandle;
 
-  ((SQLITE_LIBRARY_TYPE*)db->aExtension)[db->nExtension-1] = handle;
+  db->aExtension[db->nExtension-1] = handle;
   return SQLITE_OK;
-#else
-  if( pzErrMsg ){
-    *pzErrMsg = sqlite3_mprintf("extension loading is disabled");
-  }
-  return SQLITE_ERROR;
-#endif
 }
 
 /*
@@ -330,13 +317,11 @@ int sqlite3_load_extension(
 ** to clean up loaded extensions
 */
 void sqlite3CloseExtensions(sqlite3 *db){
-#ifdef SQLITE_LIBRARY_TYPE
   int i;
   for(i=0; i<db->nExtension; i++){
-    SQLITE_CLOSE_LIBRARY(((SQLITE_LIBRARY_TYPE*)db->aExtension)[i]);
+    sqlite3OsDlclose(db->aExtension[i]);
   }
   sqliteFree(db->aExtension);
-#endif
 }
 
 /*
@@ -352,4 +337,86 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
   return SQLITE_OK;
 }
 
+/*
+** A list of automatically loaded extensions.
+**
+** This list is shared across threads, so be sure to hold the
+** mutex while accessing or changing it.
+*/
+static int nAutoExtension = 0;
+static void **aAutoExtension = 0;
+
+
+/*
+** Register a statically linked extension that is automatically
+** loaded by every new database connection.
+*/
+int sqlite3_auto_extension(void *xInit){
+  int i;
+  int rc = SQLITE_OK;
+  sqlite3OsEnterMutex();
+  for(i=0; i<nAutoExtension; i++){
+    if( aAutoExtension[i]==xInit ) break;
+  }
+  if( i==nAutoExtension ){
+    nAutoExtension++;
+    aAutoExtension = sqlite3Realloc( aAutoExtension,
+                                     nAutoExtension*sizeof(aAutoExtension[0]) );
+    if( aAutoExtension==0 ){
+      nAutoExtension = 0;
+      rc = SQLITE_NOMEM;
+    }else{
+      aAutoExtension[nAutoExtension-1] = xInit;
+    }
+  }
+  sqlite3OsLeaveMutex();
+  assert( (rc&0xff)==rc );
+  return rc;
+}
+
+/*
+** Reset the automatic extension loading mechanism.
+*/
+void sqlite3_reset_auto_extension(void){
+  sqlite3OsEnterMutex();
+  sqliteFree(aAutoExtension);
+  aAutoExtension = 0;
+  nAutoExtension = 0;
+  sqlite3OsLeaveMutex();
+}
+
+/*
+** Load all automatic extensions.
+*/
+int sqlite3AutoLoadExtensions(sqlite3 *db){
+  int i;
+  int go = 1;
+  int rc = SQLITE_OK;
+  int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
+
+  if( nAutoExtension==0 ){
+    /* Common case: early out without every having to acquire a mutex */
+    return SQLITE_OK;
+  }
+  for(i=0; go; i++){
+    char *zErrmsg = 0;
+    sqlite3OsEnterMutex();
+    if( i>=nAutoExtension ){
+      xInit = 0;
+      go = 0;
+    }else{
+      xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+              aAutoExtension[i];
+    }
+    sqlite3OsLeaveMutex();
+    if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
+      sqlite3Error(db, SQLITE_ERROR,
+            "automatic extension loading failed: %s", zErrmsg);
+      go = 0;
+      rc = SQLITE_ERROR;
+    }
+  }
+  return rc;
+}
+
 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
index eccf83be6960cc22d13697a3da9a24d9b8ca548a..c1f8f9ed6f593e5494f4f7b6138302cb2cd3bfeb 100644 (file)
@@ -223,7 +223,7 @@ void sqlite3RollbackAll(sqlite3 *db){
 */
 const char *sqlite3ErrStr(int rc){
   const char *z;
-  switch( rc ){
+  switch( rc & 0xff ){
     case SQLITE_ROW:
     case SQLITE_DONE:
     case SQLITE_OK:         z = "not an error";                          break;
@@ -541,6 +541,32 @@ int sqlite3_create_function16(
 }
 #endif
 
+
+/*
+** Declare that a function has been overloaded by a virtual table.
+**
+** If the function already exists as a regular global function, then
+** this routine is a no-op.  If the function does not exist, then create
+** a new one that always throws a run-time error.  
+**
+** When virtual tables intend to provide an overloaded function, they
+** should call this routine to make sure the global function exists.
+** A global function must exist in order for name resolution to work
+** properly.
+*/
+int sqlite3_overload_function(
+  sqlite3 *db,
+  const char *zName,
+  int nArg
+){
+  int nName = strlen(zName);
+  if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
+    sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
+                      0, sqlite3InvalidFunction, 0, 0);
+  }
+  return sqlite3ApiExit(db, SQLITE_OK);
+}
+
 #ifndef SQLITE_OMIT_TRACE
 /*
 ** Register a trace function.  The pArg from the previously registered trace
@@ -763,7 +789,7 @@ int sqlite3_errcode(sqlite3 *db){
   if( sqlite3SafetyCheck(db) ){
     return SQLITE_MISUSE;
   }
-  return db->errCode;
+  return db->errCode & db->errMask;
 }
 
 /*
@@ -841,6 +867,7 @@ static int openDatabase(
   /* Allocate the sqlite data structure */
   db = sqliteMalloc( sizeof(sqlite3) );
   if( db==0 ) goto opendb_out;
+  db->errMask = 0xff;
   db->priorNewRowid = 0;
   db->magic = SQLITE_MAGIC_BUSY;
   db->nDb = 2;
@@ -907,11 +934,30 @@ static int openDatabase(
   ** is accessed.
   */
   if( !sqlite3MallocFailed() ){
-    sqlite3RegisterBuiltinFunctions(db);
     sqlite3Error(db, SQLITE_OK, 0);
+    sqlite3RegisterBuiltinFunctions(db);
   }
   db->magic = SQLITE_MAGIC_OPEN;
 
+  /* Load automatic extensions - extensions that have been registered
+  ** using the sqlite3_automatic_extension() API.
+  */
+  (void)sqlite3AutoLoadExtensions(db);
+
+#ifdef SQLITE_ENABLE_FTS1
+  {
+    extern int sqlite3Fts1Init(sqlite3*);
+    sqlite3Fts1Init(db);
+  }
+#endif
+
+#ifdef SQLITE_ENABLE_FTS2
+  {
+    extern int sqlite3Fts2Init(sqlite3*);
+    sqlite3Fts2Init(db);
+  }
+#endif
+
 opendb_out:
   if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
     sqlite3_close(db);
@@ -999,6 +1045,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
   }else{
     rc = sqlite3VdbeReset((Vdbe*)pStmt);
     sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0);
+    assert( (rc & (sqlite3_db_handle(pStmt)->errMask))==rc );
   }
   return rc;
 }
@@ -1285,3 +1332,11 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
 int sqlite3_sleep(int ms){
   return sqlite3OsSleep(ms);
 }
+
+/*
+** Enable or disable the extended result codes.
+*/
+int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+  db->errMask = onoff ? 0xffffffff : 0xff;
+  return SQLITE_OK;
+}
index 734d1a5409eaa0ee2d5743e4e47043069445a7c5..aa562721ef4d72798ad680685c3e9414ebece38b 100644 (file)
 /* See the mkopcodec.awk script for details. */
 #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
 const char *const sqlite3OpcodeNames[] = { "?",
- /*   1 */ "MemLoad",
- /*   2 */ "Column",
- /*   3 */ "SetCookie",
- /*   4 */ "IfMemPos",
- /*   5 */ "MoveGt",
- /*   6 */ "AggFocus",
- /*   7 */ "RowKey",
- /*   8 */ "IdxRecno",
- /*   9 */ "AggNext",
- /*  10 */ "OpenWrite",
- /*  11 */ "If",
- /*  12 */ "PutStrKey",
- /*  13 */ "Pop",
- /*  14 */ "SortPut",
- /*  15 */ "AggContextPush",
- /*  16 */ "CollSeq",
- /*  17 */ "OpenRead",
- /*  18 */ "Expire",
- /*  19 */ "SortReset",
- /*  20 */ "AutoCommit",
- /*  21 */ "Sort",
- /*  22 */ "ListRewind",
- /*  23 */ "IntegrityCk",
- /*  24 */ "Function",
- /*  25 */ "Noop",
- /*  26 */ "Return",
- /*  27 */ "Variable",
- /*  28 */ "String",
- /*  29 */ "ParseSchema",
- /*  30 */ "PutIntKey",
- /*  31 */ "AggFunc",
- /*  32 */ "Close",
- /*  33 */ "ListWrite",
- /*  34 */ "CreateIndex",
- /*  35 */ "IsUnique",
- /*  36 */ "IdxIsNull",
- /*  37 */ "NotFound",
- /*  38 */ "MustBeInt",
- /*  39 */ "Halt",
- /*  40 */ "IdxLT",
- /*  41 */ "AddImm",
- /*  42 */ "Statement",
- /*  43 */ "RowData",
- /*  44 */ "MemMax",
- /*  45 */ "Push",
- /*  46 */ "KeyAsData",
- /*  47 */ "NotExists",
- /*  48 */ "OpenTemp",
- /*  49 */ "MemIncr",
- /*  50 */ "Gosub",
- /*  51 */ "AggSet",
- /*  52 */ "Integer",
- /*  53 */ "SortNext",
- /*  54 */ "Prev",
- /*  55 */ "CreateTable",
- /*  56 */ "Last",
- /*  57 */ "ResetCount",
- /*  58 */ "Callback",
- /*  59 */ "ContextPush",
- /*  60 */ "DropTrigger",
- /*  61 */ "DropIndex",
- /*  62 */ "FullKey",
- /*  63 */ "IdxGE",
- /*  64 */ "Or",
- /*  65 */ "And",
- /*  66 */ "Not",
- /*  67 */ "IdxDelete",
- /*  68 */ "Vacuum",
- /*  69 */ "MoveLe",
- /*  70 */ "IsNull",
- /*  71 */ "NotNull",
- /*  72 */ "Ne",
- /*  73 */ "Eq",
- /*  74 */ "Gt",
- /*  75 */ "Le",
- /*  76 */ "Lt",
- /*  77 */ "Ge",
- /*  78 */ "IfNot",
- /*  79 */ "BitAnd",
- /*  80 */ "BitOr",
- /*  81 */ "ShiftLeft",
- /*  82 */ "ShiftRight",
- /*  83 */ "Add",
- /*  84 */ "Subtract",
- /*  85 */ "Multiply",
- /*  86 */ "Divide",
- /*  87 */ "Remainder",
- /*  88 */ "Concat",
- /*  89 */ "Negative",
- /*  90 */ "DropTable",
- /*  91 */ "BitNot",
- /*  92 */ "String8",
- /*  93 */ "MakeRecord",
- /*  94 */ "Delete",
- /*  95 */ "AggContextPop",
- /*  96 */ "ListRead",
- /*  97 */ "ListReset",
- /*  98 */ "Dup",
- /*  99 */ "Goto",
- /* 100 */ "Clear",
- /* 101 */ "IdxGT",
- /* 102 */ "MoveLt",
- /* 103 */ "VerifyCookie",
- /* 104 */ "Pull",
- /* 105 */ "SetNumColumns",
- /* 106 */ "AbsValue",
- /* 107 */ "Transaction",
- /* 108 */ "AggGet",
- /* 109 */ "ContextPop",
- /* 110 */ "Next",
- /* 111 */ "AggInit",
- /* 112 */ "Distinct",
- /* 113 */ "NewRecno",
- /* 114 */ "AggReset",
- /* 115 */ "Destroy",
- /* 116 */ "ReadCookie",
- /* 117 */ "ForceInt",
- /* 118 */ "Recno",
- /* 119 */ "OpenPseudo",
- /* 120 */ "Blob",
- /* 121 */ "MemStore",
- /* 122 */ "Rewind",
- /* 123 */ "MoveGe",
- /* 124 */ "IdxPut",
- /* 125 */ "Found",
- /* 126 */ "NullRow",
- /* 127 */ "NotUsed_127",
- /* 128 */ "NotUsed_128",
- /* 129 */ "NotUsed_129",
- /* 130 */ "Real",
- /* 131 */ "HexBlob",
+ /*   1 */ "NotExists",
+ /*   2 */ "Dup",
+ /*   3 */ "MoveLt",
+ /*   4 */ "VCreate",
+ /*   5 */ "DropTrigger",
+ /*   6 */ "OpenPseudo",
+ /*   7 */ "MemInt",
+ /*   8 */ "IntegrityCk",
+ /*   9 */ "RowKey",
+ /*  10 */ "LoadAnalysis",
+ /*  11 */ "IdxGT",
+ /*  12 */ "Last",
+ /*  13 */ "MemLoad",
+ /*  14 */ "SetCookie",
+ /*  15 */ "Sequence",
+ /*  16 */ "Not",
+ /*  17 */ "Pull",
+ /*  18 */ "VUpdate",
+ /*  19 */ "VColumn",
+ /*  20 */ "DropTable",
+ /*  21 */ "MemStore",
+ /*  22 */ "ContextPush",
+ /*  23 */ "Rowid",
+ /*  24 */ "VFilter",
+ /*  25 */ "NullRow",
+ /*  26 */ "Noop",
+ /*  27 */ "VRowid",
+ /*  28 */ "ParseSchema",
+ /*  29 */ "Statement",
+ /*  30 */ "CollSeq",
+ /*  31 */ "ContextPop",
+ /*  32 */ "MemIncr",
+ /*  33 */ "MoveGe",
+ /*  34 */ "If",
+ /*  35 */ "IfNot",
+ /*  36 */ "Destroy",
+ /*  37 */ "Distinct",
+ /*  38 */ "CreateIndex",
+ /*  39 */ "SetNumColumns",
+ /*  40 */ "ResetCount",
+ /*  41 */ "MakeIdxRec",
+ /*  42 */ "Goto",
+ /*  43 */ "IdxDelete",
+ /*  44 */ "MemMove",
+ /*  45 */ "Found",
+ /*  46 */ "MoveGt",
+ /*  47 */ "IfMemZero",
+ /*  48 */ "MustBeInt",
+ /*  49 */ "Prev",
+ /*  50 */ "MemNull",
+ /*  51 */ "AutoCommit",
+ /*  52 */ "String",
+ /*  53 */ "FifoWrite",
+ /*  54 */ "Return",
+ /*  55 */ "Callback",
+ /*  56 */ "AddImm",
+ /*  57 */ "Function",
+ /*  58 */ "NewRowid",
+ /*  59 */ "Blob",
+ /*  60 */ "Next",
+ /*  61 */ "Or",
+ /*  62 */ "And",
+ /*  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",
+ /*  85 */ "Negative",
+ /*  86 */ "DropIndex",
+ /*  87 */ "BitNot",
+ /*  88 */ "String8",
+ /*  89 */ "IdxInsert",
+ /*  90 */ "FifoRead",
+ /*  91 */ "Column",
+ /*  92 */ "Int64",
+ /*  93 */ "Gosub",
+ /*  94 */ "IfMemNeg",
+ /*  95 */ "RowData",
+ /*  96 */ "MemMax",
+ /*  97 */ "Close",
+ /*  98 */ "VerifyCookie",
+ /*  99 */ "IfMemPos",
+ /* 100 */ "Null",
+ /* 101 */ "Integer",
+ /* 102 */ "Transaction",
+ /* 103 */ "IdxLT",
+ /* 104 */ "Delete",
+ /* 105 */ "Rewind",
+ /* 106 */ "Push",
+ /* 107 */ "RealAffinity",
+ /* 108 */ "Clear",
+ /* 109 */ "AggStep",
+ /* 110 */ "Explain",
+ /* 111 */ "Vacuum",
+ /* 112 */ "VDestroy",
+ /* 113 */ "IsUnique",
+ /* 114 */ "VOpen",
+ /* 115 */ "AggFinal",
+ /* 116 */ "OpenWrite",
+ /* 117 */ "VNext",
+ /* 118 */ "AbsValue",
+ /* 119 */ "Sort",
+ /* 120 */ "NotFound",
+ /* 121 */ "MoveLe",
+ /* 122 */ "MakeRecord",
+ /* 123 */ "Variable",
+ /* 124 */ "CreateTable",
+ /* 125 */ "Insert",
+ /* 126 */ "Real",
+ /* 127 */ "HexBlob",
+ /* 128 */ "IdxGE",
+ /* 129 */ "OpenRead",
+ /* 130 */ "IdxRowid",
+ /* 131 */ "VBegin",
+ /* 132 */ "TableLock",
+ /* 133 */ "OpenEphemeral",
+ /* 134 */ "Pop",
+ /* 135 */ "NotUsed_135",
+ /* 136 */ "NotUsed_136",
+ /* 137 */ "NotUsed_137",
+ /* 138 */ "NotUsed_138",
+ /* 139 */ "ToText",
+ /* 140 */ "ToBlob",
+ /* 141 */ "ToNumeric",
+ /* 142 */ "ToInt",
+ /* 143 */ "ToReal",
 };
 #endif
index c113f8f1c1ad279c55786f948f382447a8ed9632..80598e2a6fbce58f2f7aa728a09b30f1fab094c6 100644 (file)
 /* Automatically generated.  Do not edit */
 /* See the mkopcodeh.awk script for details */
-#define OP_MemLoad                              1
-#define OP_VNext                                2
-#define OP_HexBlob                            127   /* same as TK_BLOB     */
-#define OP_Column                               3
-#define OP_SetCookie                            4
-#define OP_IfMemPos                             5
-#define OP_Real                               126   /* same as TK_FLOAT    */
-#define OP_Sequence                             6
-#define OP_MoveGt                               7
-#define OP_Ge                                  73   /* same as TK_GE       */
-#define OP_RowKey                               8
-#define OP_Eq                                  69   /* same as TK_EQ       */
-#define OP_OpenWrite                            9
+#define OP_NotExists                            1
+#define OP_Dup                                  2
+#define OP_MoveLt                               3
+#define OP_Multiply                            81   /* same as TK_STAR     */
+#define OP_VCreate                              4
+#define OP_BitAnd                              75   /* same as TK_BITAND   */
+#define OP_DropTrigger                          5
+#define OP_OpenPseudo                           6
+#define OP_MemInt                               7
+#define OP_IntegrityCk                          8
+#define OP_RowKey                               9
+#define OP_LoadAnalysis                        10
+#define OP_IdxGT                               11
+#define OP_Last                                12
+#define OP_Subtract                            80   /* same as TK_MINUS    */
+#define OP_MemLoad                             13
+#define OP_Remainder                           83   /* same as TK_REM      */
+#define OP_SetCookie                           14
+#define OP_Sequence                            15
+#define OP_Pull                                17
+#define OP_VUpdate                             18
+#define OP_VColumn                             19
+#define OP_DropTable                           20
+#define OP_MemStore                            21
+#define OP_ContextPush                         22
 #define OP_NotNull                             67   /* same as TK_NOTNULL  */
-#define OP_If                                  10
-#define OP_ToInt                              142   /* same as TK_TO_INT   */
+#define OP_Rowid                               23
+#define OP_Real                               126   /* same as TK_FLOAT    */
 #define OP_String8                             88   /* same as TK_STRING   */
-#define OP_Pop                                 11
-#define OP_VRowid                              12
-#define OP_CollSeq                             13
-#define OP_OpenRead                            14
-#define OP_Expire                              15
-#define OP_AutoCommit                          17
-#define OP_Gt                                  70   /* same as TK_GT       */
-#define OP_IntegrityCk                         18
-#define OP_Sort                                19
-#define OP_Function                            20
 #define OP_And                                 62   /* same as TK_AND      */
-#define OP_Subtract                            80   /* same as TK_MINUS    */
-#define OP_Noop                                21
-#define OP_Return                              22
-#define OP_Remainder                           83   /* same as TK_REM      */
-#define OP_NewRowid                            23
-#define OP_Multiply                            81   /* same as TK_STAR     */
-#define OP_IfMemNeg                            24
-#define OP_Variable                            25
-#define OP_String                              26
-#define OP_RealAffinity                        27
+#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_ParseSchema                         28
-#define OP_VOpen                               29
-#define OP_Close                               30
-#define OP_CreateIndex                         31
-#define OP_IsUnique                            32
-#define OP_IdxIsNull                           33
-#define OP_NotFound                            34
-#define OP_Int64                               35
-#define OP_MustBeInt                           36
-#define OP_Halt                                37
-#define OP_Rowid                               38
-#define OP_IdxLT                               39
-#define OP_AddImm                              40
-#define OP_Statement                           41
-#define OP_RowData                             42
-#define OP_MemMax                              43
-#define OP_Push                                44
-#define OP_Or                                  61   /* same as TK_OR       */
-#define OP_NotExists                           45
-#define OP_MemIncr                             46
-#define OP_Gosub                               47
-#define OP_Divide                              82   /* same as TK_SLASH    */
-#define OP_Integer                             48
+#define OP_Statement                           29
+#define OP_CollSeq                             30
+#define OP_ContextPop                          31
+#define OP_ToText                             139   /* 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_MemInt                              49
-#define OP_Prev                                50
+#define OP_If                                  34
+#define OP_IfNot                               35
+#define OP_ShiftRight                          78   /* 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_ResetCount                          40
+#define OP_MakeIdxRec                          41
+#define OP_Goto                                42
+#define OP_IdxDelete                           43
+#define OP_MemMove                             44
+#define OP_Found                               45
+#define OP_MoveGt                              46
+#define OP_IfMemZero                           47
+#define OP_MustBeInt                           48
+#define OP_Prev                                49
+#define OP_MemNull                             50
+#define OP_AutoCommit                          51
+#define OP_String                              52
+#define OP_FifoWrite                           53
+#define OP_ToInt                              142   /* 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_BitAnd                              75   /* same as TK_BITAND   */
-#define OP_VColumn                             51
-#define OP_CreateTable                         52
-#define OP_Last                                53
+#define OP_NewRowid                            58
+#define OP_Blob                                59
 #define OP_IsNull                              66   /* same as TK_ISNULL   */
-#define OP_IdxRowid                            54
-#define OP_MakeIdxRec                          55
-#define OP_ShiftRight                          78   /* same as TK_RSHIFT   */
-#define OP_ResetCount                          56
-#define OP_FifoWrite                           57
-#define OP_Callback                            58
-#define OP_ContextPush                         59
-#define OP_DropTrigger                         60
-#define OP_DropIndex                           63
-#define OP_IdxGE                               64
-#define OP_IdxDelete                           65
-#define OP_Vacuum                              74
-#define OP_MoveLe                              86
-#define OP_IfNot                               89
-#define OP_DropTable                           90
-#define OP_MakeRecord                          91
-#define OP_ToBlob                             140   /* same as TK_TO_BLOB  */
-#define OP_Delete                              92
-#define OP_AggFinal                            93
+#define OP_Next                                60
+#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                           86
+#define OP_IdxInsert                           89
 #define OP_ShiftLeft                           77   /* same as TK_LSHIFT   */
-#define OP_Dup                                 94
-#define OP_Goto                                95
-#define OP_TableLock                           96
-#define OP_FifoRead                            97
-#define OP_Clear                               98
-#define OP_IdxGT                               99
-#define OP_MoveLt                             100
-#define OP_Le                                  71   /* same as TK_LE       */
-#define OP_VerifyCookie                       101
-#define OP_AggStep                            102
-#define OP_Pull                               103
-#define OP_ToText                             139   /* same as TK_TO_TEXT  */
-#define OP_Not                                 16   /* same as TK_NOT      */
+#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_MemMax                              96
+#define OP_Close                               97
 #define OP_ToReal                             143   /* same as TK_TO_REAL  */
-#define OP_SetNumColumns                      104
-#define OP_AbsValue                           105
-#define OP_Transaction                        106
-#define OP_VFilter                            107
+#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_IdxLT                              103
+#define OP_Delete                             104
+#define OP_Rewind                             105
+#define OP_Push                               106
+#define OP_RealAffinity                       107
+#define OP_Clear                              108
+#define OP_AggStep                            109
+#define OP_Explain                            110
+#define OP_Vacuum                             111
+#define OP_VDestroy                           112
+#define OP_IsUnique                           113
+#define OP_VOpen                              114
+#define OP_AggFinal                           115
+#define OP_OpenWrite                          116
 #define OP_Negative                            85   /* same as TK_UMINUS   */
+#define OP_Le                                  71   /* 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_VDestroy                           108
-#define OP_ContextPop                         109
-#define OP_BitOr                               76   /* same as TK_BITOR    */
-#define OP_Next                               110
-#define OP_IdxInsert                          111
-#define OP_Distinct                           112
+#define OP_Variable                           123
+#define OP_CreateTable                        124
+#define OP_Insert                             125
+#define OP_IdxGE                              128
+#define OP_OpenRead                           129
+#define OP_IdxRowid                           130
+#define OP_ToBlob                             140   /* 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_Insert                             113
-#define OP_Destroy                            114
-#define OP_ReadCookie                         115
-#define OP_ForceInt                           116
-#define OP_LoadAnalysis                       117
-#define OP_Explain                            118
-#define OP_IfMemZero                          119
-#define OP_OpenPseudo                         120
-#define OP_OpenEphemeral                      121
-#define OP_Null                               122
-#define OP_Blob                               123
-#define OP_Add                                 79   /* same as TK_PLUS     */
-#define OP_MemStore                           124
-#define OP_Rewind                             125
-#define OP_MoveGe                             128
-#define OP_VBegin                             129
-#define OP_VUpdate                            130
-#define OP_BitNot                              87   /* same as TK_BITNOT   */
-#define OP_VCreate                            131
-#define OP_MemMove                            132
-#define OP_MemNull                            133
-#define OP_Found                              134
-#define OP_NullRow                            135
+#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
 ** set.  See the opcodeNoPush() function in vdbeaux.c  */
-#define NOPUSH_MASK_0 0xeeb4
-#define NOPUSH_MASK_1 0x796b
-#define NOPUSH_MASK_2 0xfbb7
-#define NOPUSH_MASK_3 0xff24
-#define NOPUSH_MASK_4 0xffff
-#define NOPUSH_MASK_5 0xb6ef
-#define NOPUSH_MASK_6 0xfdfd
-#define NOPUSH_MASK_7 0x33b3
-#define NOPUSH_MASK_8 0xf8cf
+#define NOPUSH_MASK_0 0x5c7a
+#define NOPUSH_MASK_1 0xf777
+#define NOPUSH_MASK_2 0xedaf
+#define NOPUSH_MASK_3 0xf1eb
+#define NOPUSH_MASK_4 0xfffe
+#define NOPUSH_MASK_5 0x62ef
+#define NOPUSH_MASK_6 0xbfcf
+#define NOPUSH_MASK_7 0x23bf
+#define NOPUSH_MASK_8 0xf87b
 #define NOPUSH_MASK_9 0x0000
index 4433f5d0223a4db3ea42a82a8b83150c39fcaf24..0fe7b156ee917c7319efcf7ad83d11d56703b64f 100644 (file)
 ** prefix to reflect your program's name, so that if your program exits
 ** prematurely, old temporary files can be easily identified. This can be done
 ** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
+**
+** 2006-10-31:  The default prefix used to be "sqlite_".  But then
+** Mcafee started using SQLite in their anti-virus product and it
+** started putting files with the "sqlite" name in the c:/temp folder.
+** This annoyed many windows users.  Those users would then do a 
+** Google search for "sqlite", find the telephone numbers of the
+** developers and call to wake them up at night and complain.
+** For this reason, the default name prefix is changed to be "sqlite" 
+** spelled backwards.  So the temp files are still identified, but
+** anybody smart enough to figure out the code is also likely smart
+** enough to know that calling the developer will not help get rid
+** of the file.
 */
 #ifndef TEMP_FILE_PREFIX
-# define TEMP_FILE_PREFIX "sqlite_"
+# define TEMP_FILE_PREFIX "etilqs_"
 #endif
 
 /*
 #define sqlite3OsRealloc            sqlite3GenericRealloc
 #define sqlite3OsFree               sqlite3GenericFree
 #define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#define sqlite3OsDlopen             sqlite3UnixDlopen
+#define sqlite3OsDlsym              sqlite3UnixDlsym
+#define sqlite3OsDlclose            sqlite3UnixDlclose
 #endif
 #if OS_WIN
 #define sqlite3OsOpenReadWrite      sqlite3WinOpenReadWrite
 #define sqlite3OsRealloc            sqlite3GenericRealloc
 #define sqlite3OsFree               sqlite3GenericFree
 #define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#define sqlite3OsDlopen             sqlite3WinDlopen
+#define sqlite3OsDlsym              sqlite3WinDlsym
+#define sqlite3OsDlclose            sqlite3WinDlclose
 #endif
 #if OS_OS2
 #define sqlite3OsOpenReadWrite      sqlite3Os2OpenReadWrite
 #define sqlite3OsRealloc            sqlite3GenericRealloc
 #define sqlite3OsFree               sqlite3GenericFree
 #define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#define sqlite3OsDlopen             sqlite3Os2Dlopen
+#define sqlite3OsDlsym              sqlite3Os2Dlsym
+#define sqlite3OsDlclose            sqlite3Os2Dlclose
 #endif
 
 
@@ -337,6 +358,9 @@ void *sqlite3OsMalloc(int);
 void *sqlite3OsRealloc(void *, int);
 void sqlite3OsFree(void *);
 int sqlite3OsAllocationSize(void *);
+void *sqlite3OsDlopen(const char*);
+void *sqlite3OsDlsym(void*, const char*);
+int sqlite3OsDlclose(void*);
 
 /*
 ** If the SQLITE_ENABLE_REDEF_IO macro is defined, then the OS-layer
@@ -381,16 +405,26 @@ struct sqlite3OsVtbl {
   void *(*xRealloc)(void *, int);
   void (*xFree)(void *);
   int (*xAllocationSize)(void *);
+
+  void *(*xDlopen)(const char*);
+  void *(*xDlsym)(void*, const char*);
+  int (*xDlclose)(void*);
 };
 
 /* Macro used to comment out routines that do not exists when there is
-** no disk I/O 
+** no disk I/O or extension loading
 */
 #ifdef SQLITE_OMIT_DISKIO
 # define IF_DISKIO(X)  0
 #else
 # define IF_DISKIO(X)  X
 #endif
+#ifdef SQLITE_OMIT_LOAD_EXTENSION
+# define IF_DLOPEN(X)  0
+#else
+# define IF_DLOPEN(X)  X
+#endif
+
 
 #ifdef _SQLITE_OS_C_
   /*
@@ -416,7 +450,10 @@ struct sqlite3OsVtbl {
     sqlite3OsMalloc,
     sqlite3OsRealloc,
     sqlite3OsFree,
-    sqlite3OsAllocationSize
+    sqlite3OsAllocationSize,
+    IF_DLOPEN( sqlite3OsDlopen ),
+    IF_DLOPEN( sqlite3OsDlsym ),
+    IF_DLOPEN( sqlite3OsDlclose ),
   };
 #else
   /*
index d65c352ddfc77768cf0eb2ffd59a812b272c9870..863e3cde2b727f851210d5d96c58fd8a734fdb29 100644 (file)
@@ -92,25 +92,25 @@ int sqlite3_io_error_hit = 0;
 int sqlite3_io_error_pending = 0;
 int sqlite3_diskfull_pending = 0;
 int sqlite3_diskfull = 0;
-#define SimulateIOError(A)  \
+#define SimulateIOError(CODE)  \
    if( sqlite3_io_error_pending ) \
-     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
+     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); CODE; }
 static void local_ioerr(){
   sqlite3_io_error_hit = 1;  /* Really just a place to set a breakpoint */
 }
-#define SimulateDiskfullError \
+#define SimulateDiskfullError(CODE) \
    if( sqlite3_diskfull_pending ){ \
      if( sqlite3_diskfull_pending == 1 ){ \
        local_ioerr(); \
        sqlite3_diskfull = 1; \
-       return SQLITE_FULL; \
+       CODE; \
      }else{ \
        sqlite3_diskfull_pending--; \
      } \
    }
 #else
 #define SimulateIOError(A)
-#define SimulateDiskfullError
+#define SimulateDiskfullError(A)
 #endif
 
 /*
index 5b58cb7aac273230773082c477b399fa5f5af18a..d7f05ac14bf36b176b2a1b9cae11114a1dbaf1fd 100644 (file)
@@ -16,6 +16,8 @@
 #include "os.h"
 #if OS_UNIX              /* This file is used on unix only */
 
+/* #define SQLITE_ENABLE_LOCKING_STYLE 0 */
+
 /*
 ** These #defines should enable >2GB file support on Posix if the
 ** underlying operating system supports it.  If the OS lacks
 #include <time.h>
 #include <sys/time.h>
 #include <errno.h>
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
 /*
 ** If we are to be thread-safe, include the pthreads header and define
@@ -75,6 +82,9 @@ struct unixFile {
   IoMethod const *pMethod;  /* Always the first entry */
   struct openCnt *pOpen;    /* Info about all open fd's on this inode */
   struct lockInfo *pLock;   /* Info about locks on this inode */
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+  void *lockingContext;     /* Locking style specific state */
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
   int h;                    /* The file descriptor */
   unsigned char locktype;   /* The type of lock held on this fd */
   unsigned char isOpen;     /* True if needs to be closed */
@@ -346,6 +356,32 @@ static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0,
 static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 
     sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0};
 
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+/*
+** The locking styles are associated with the different file locking
+** capabilities supported by different file systems.  
+**
+** POSIX locking style fully supports shared and exclusive byte-range locks 
+** ADP locking only supports exclusive byte-range locks
+** FLOCK only supports a single file-global exclusive lock
+** DOTLOCK isn't a true locking style, it refers to the use of a special
+**   file named the same as the database file with a '.lock' extension, this
+**   can be used on file systems that do not offer any reliable file locking
+** NO locking means that no locking will be attempted, this is only used for
+**   read-only file systems currently
+** UNSUPPORTED means that no locking will be attempted, this is only used for
+**   file systems that are known to be unsupported
+*/
+typedef enum {
+       posixLockingStyle = 0,       /* standard posix-advisory locks */
+       afpLockingStyle,             /* use afp locks */
+       flockLockingStyle,           /* use flock() */
+       dotlockLockingStyle,         /* use <file>.lock files */
+       noLockingStyle,              /* useful for read-only file system */
+       unsupportedLockingStyle      /* indicates unsupported file system */
+} sqlite3LockingStyle;
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
 #ifdef SQLITE_UNIX_THREADS
 /*
 ** This variable records whether or not threads can override each others
@@ -490,6 +526,8 @@ static void testThreadLockingBehavior(int fd_orig){
 */
 static void releaseLockInfo(struct lockInfo *pLock){
   assert( sqlite3OsInMutex(1) );
+  if (pLock == NULL)
+    return;
   pLock->nRef--;
   if( pLock->nRef==0 ){
     sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
@@ -502,6 +540,8 @@ static void releaseLockInfo(struct lockInfo *pLock){
 */
 static void releaseOpenCnt(struct openCnt *pOpen){
   assert( sqlite3OsInMutex(1) );
+  if (pOpen == NULL)
+    return;
   pOpen->nRef--;
   if( pOpen->nRef==0 ){
     sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
@@ -510,6 +550,77 @@ static void releaseOpenCnt(struct openCnt *pOpen){
   }
 }
 
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+/*
+** Tests a byte-range locking query to see if byte range locks are 
+** supported, if not we fall back to dotlockLockingStyle.
+*/
+static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath, 
+  int fd) {
+  /* test byte-range lock using fcntl */
+  struct flock lockInfo;
+  
+  lockInfo.l_len = 1;
+  lockInfo.l_start = 0;
+  lockInfo.l_whence = SEEK_SET;
+  lockInfo.l_type = F_RDLCK;
+  
+  if (fcntl(fd, F_GETLK, (int) &lockInfo) != -1) {
+    return posixLockingStyle;
+  } 
+  
+  /* testing for flock can give false positives.  So if if the above test
+  ** fails, then we fall back to using dot-lock style locking.
+  */  
+  return dotlockLockingStyle;
+}
+
+/* 
+** Examines the f_fstypename entry in the statfs structure as returned by 
+** stat() for the file system hosting the database file, assigns the 
+** appropriate locking style based on it's value.  These values and 
+** assignments are based on Darwin/OSX behavior and have not been tested on 
+** other systems.
+*/
+static sqlite3LockingStyle sqlite3DetectLockingStyle(const char *filePath, 
+  int fd) {
+
+#ifdef SQLITE_FIXED_LOCKING_STYLE
+  return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE;
+#else
+  struct statfs fsInfo;
+
+  if (statfs(filePath, &fsInfo) == -1)
+    return sqlite3TestLockingStyle(filePath, fd);
+  
+  if (fsInfo.f_flags & MNT_RDONLY)
+    return noLockingStyle;
+  
+  if( (!strcmp(fsInfo.f_fstypename, "hfs")) ||
+    (!strcmp(fsInfo.f_fstypename, "ufs")) )
+               return posixLockingStyle;
+  
+  if(!strcmp(fsInfo.f_fstypename, "afpfs"))
+    return afpLockingStyle;
+  
+  if(!strcmp(fsInfo.f_fstypename, "nfs")) 
+    return sqlite3TestLockingStyle(filePath, fd);
+  
+  if(!strcmp(fsInfo.f_fstypename, "smbfs"))
+    return flockLockingStyle;
+  
+  if(!strcmp(fsInfo.f_fstypename, "msdos"))
+    return dotlockLockingStyle;
+  
+  if(!strcmp(fsInfo.f_fstypename, "webdav"))
+    return unsupportedLockingStyle;
+  
+  return sqlite3TestLockingStyle(filePath, fd);  
+#endif // SQLITE_FIXED_LOCKING_STYLE
+}
+
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
 /*
 ** Given a file descriptor, locate lockInfo and openCnt structures that
 ** describes that file descriptor.  Create new ones if necessary.  The
@@ -651,12 +762,16 @@ static int transferOwnership(unixFile *pFile){
   }
   TRACE4("Transfer ownership of %d from %d to %d\n", pFile->h,pFile->tid,hSelf);
   pFile->tid = hSelf;
-  releaseLockInfo(pFile->pLock);
-  rc = findLockInfo(pFile->h, &pFile->pLock, 0);
-  TRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
-     locktypeName(pFile->locktype),
-     locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
-  return rc;
+  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,
+           locktypeName(pFile->locktype),
+           locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
+    return rc;
+  } else {
+    return SQLITE_OK;
+  }
 }
 #else
   /* On single-threaded builds, ownership transfer is a no-op */
@@ -679,7 +794,12 @@ int sqlite3UnixFileExists(const char *zFilename){
 }
 
 /* Forward declaration */
-static int allocateUnixFile(unixFile *pInit, OsFile **pId);
+static int allocateUnixFile(
+  int h,                    /* File descriptor of the open file */
+  OsFile **pId,             /* Write the real file descriptor here */
+  const char *zFilename,    /* Name of the file being opened */
+  int delFlag               /* If true, make sure the file deletes on close */
+);
 
 /*
 ** Attempt to open a file for both reading and writing.  If that
@@ -699,36 +819,27 @@ int sqlite3UnixOpenReadWrite(
   OsFile **pId,
   int *pReadonly
 ){
-  int rc;
-  unixFile f;
-
+  int h;
+  
   CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly);
   assert( 0==*pId );
-  f.h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
-                          SQLITE_DEFAULT_FILE_PERMISSIONS);
-  if( f.h<0 ){
+  h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
+                        SQLITE_DEFAULT_FILE_PERMISSIONS);
+  if( h<0 ){
 #ifdef EISDIR
     if( errno==EISDIR ){
       return SQLITE_CANTOPEN;
     }
 #endif
-    f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
-    if( f.h<0 ){
+    h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+    if( h<0 ){
       return SQLITE_CANTOPEN; 
     }
     *pReadonly = 1;
   }else{
     *pReadonly = 0;
   }
-  sqlite3OsEnterMutex();
-  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
-  sqlite3OsLeaveMutex();
-  if( rc ){
-    close(f.h);
-    return SQLITE_NOMEM;
-  }
-  TRACE3("OPEN    %-3d %s\n", f.h, zFilename);
-  return allocateUnixFile(&f, pId);
+  return allocateUnixFile(h, pId, zFilename, 0);
 }
 
 
@@ -747,30 +858,17 @@ int sqlite3UnixOpenReadWrite(
 ** On failure, return SQLITE_CANTOPEN.
 */
 int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
-  int rc;
-  unixFile f;
+  int h;
 
   CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag);
   assert( 0==*pId );
-  f.h = open(zFilename,
+  h = open(zFilename,
                 O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY,
                 SQLITE_DEFAULT_FILE_PERMISSIONS);
-  if( f.h<0 ){
+  if( h<0 ){
     return SQLITE_CANTOPEN;
   }
-  sqlite3OsEnterMutex();
-  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
-  sqlite3OsLeaveMutex();
-  if( rc ){
-    close(f.h);
-    unlink(zFilename);
-    return SQLITE_NOMEM;
-  }
-  if( delFlag ){
-    unlink(zFilename);
-  }
-  TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename);
-  return allocateUnixFile(&f, pId);
+  return allocateUnixFile(h, pId, zFilename, delFlag);
 }
 
 /*
@@ -781,24 +879,15 @@ int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
 ** On failure, return SQLITE_CANTOPEN.
 */
 int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){
-  int rc;
-  unixFile f;
-
+  int h;
+  
   CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0);
   assert( 0==*pId );
-  f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
-  if( f.h<0 ){
+  h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+  if( h<0 ){
     return SQLITE_CANTOPEN;
   }
-  sqlite3OsEnterMutex();
-  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
-  sqlite3OsLeaveMutex();
-  if( rc ){
-    close(f.h);
-    return SQLITE_NOMEM;
-  }
-  TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename);
-  return allocateUnixFile(&f, pId);
+  return allocateUnixFile(h, pId, zFilename, 0);
 }
 
 /*
@@ -810,6 +899,9 @@ int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){
 ** This routine is only meaningful for Unix.  It is a no-op under
 ** windows since windows does not support hard links.
 **
+** If FULL_FSYNC is enabled, this function is not longer useful, 
+** a FULL_FSYNC sync applies to all pending disk operations.
+**
 ** On success, a handle for a previously open file at *id is
 ** updated with the new directory file descriptor and SQLITE_OK is
 ** returned.
@@ -928,18 +1020,20 @@ static int seekAndRead(unixFile *id, void *pBuf, int cnt){
 static int unixRead(OsFile *id, void *pBuf, int amt){
   int got;
   assert( id );
-  SimulateIOError(SQLITE_IOERR);
   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);
-  /* if( got<0 ) got = 0; */
+  SimulateIOError( got = -1 );
   if( got==amt ){
     return SQLITE_OK;
+  }else if( got<0 ){
+    return SQLITE_IOERR_READ;
   }else{
-    return SQLITE_IOERR;
+    memset(&((char*)pBuf)[got], 0, amt-got);
+    return SQLITE_IOERR_SHORT_READ;
   }
 }
 
@@ -970,8 +1064,6 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
   int wrote = 0;
   assert( id );
   assert( amt>0 );
-  SimulateIOError(SQLITE_IOERR);
-  SimulateDiskfullError;
   TIMER_START;
   while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){
     amt -= wrote;
@@ -981,8 +1073,14 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
   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 ){
-    return SQLITE_FULL;
+    if( wrote<0 ){
+      return SQLITE_IOERR_WRITE;
+    }else{
+      return SQLITE_FULL;
+    }
   }
   return SQLITE_OK;
 }
@@ -994,7 +1092,7 @@ static int unixSeek(OsFile *id, i64 offset){
   assert( id );
   SEEK(offset/1024 + 1);
 #ifdef SQLITE_TEST
-  if( offset ) SimulateDiskfullError
+  if( offset ) SimulateDiskfullError(return SQLITE_FULL);
 #endif
   ((unixFile*)id)->offset = offset;
   return SQLITE_OK;
@@ -1062,19 +1160,13 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
 #if HAVE_FULLFSYNC
   if( fullSync ){
     rc = fcntl(fd, F_FULLFSYNC, 0);
-  }else{
-    rc = 1;
-  }
-  /* If the FULLSYNC failed, try to do a normal fsync() */
-  if( rc ) rc = fsync(fd);
-
-#else /* if !defined(F_FULLSYNC) */
+  }else
+#endif /* HAVE_FULLFSYNC */
   if( dataOnly ){
     rc = fdatasync(fd);
   }else{
     rc = fsync(fd);
   }
-#endif /* defined(F_FULLFSYNC) */
 #endif /* defined(SQLITE_NO_SYNC) */
 
   return rc;
@@ -1096,12 +1188,14 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
 ** will not roll back - possibly leading to database corruption.
 */
 static int unixSync(OsFile *id, int dataOnly){
+  int rc;
   unixFile *pFile = (unixFile*)id;
   assert( pFile );
-  SimulateIOError(SQLITE_IOERR);
   TRACE2("SYNC    %-3d\n", pFile->h);
-  if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){
-    return SQLITE_IOERR;
+  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,
@@ -1141,7 +1235,6 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
 #else
   int fd;
   int r;
-  SimulateIOError(SQLITE_IOERR);
   fd = open(zDirname, O_RDONLY|O_BINARY, 0);
   TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
   if( fd<0 ){
@@ -1149,7 +1242,12 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
   }
   r = fsync(fd);
   close(fd);
-  return ((r==0)?SQLITE_OK:SQLITE_IOERR);
+  SimulateIOError( r=1 );
+  if( r ){
+    return SQLITE_IOERR_DIR_FSYNC;
+  }else{
+    return SQLITE_OK;
+  }
 #endif
 }
 
@@ -1157,20 +1255,28 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
 ** Truncate an open file to a specified size
 */
 static int unixTruncate(OsFile *id, i64 nByte){
+  int rc;
   assert( id );
-  SimulateIOError(SQLITE_IOERR);
-  return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
+  rc = ftruncate(((unixFile*)id)->h, nByte);
+  SimulateIOError( rc=1 );
+  if( rc ){
+    return SQLITE_IOERR_TRUNCATE;
+  }else{
+    return SQLITE_OK;
+  }
 }
 
 /*
 ** Determine the current size of a file in bytes
 */
 static int unixFileSize(OsFile *id, i64 *pSize){
+  int rc;
   struct stat buf;
   assert( id );
-  SimulateIOError(SQLITE_IOERR);
-  if( fstat(((unixFile*)id)->h, &buf)!=0 ){
-    return SQLITE_IOERR;
+  rc = fstat(((unixFile*)id)->h, &buf);
+  SimulateIOError( rc=1 );
+  if( rc!=0 ){
+    return SQLITE_IOERR_FSTAT;
   }
   *pSize = buf.st_size;
   return SQLITE_OK;
@@ -1380,7 +1486,7 @@ static int unixLock(OsFile *id, int locktype){
     lock.l_len = 1L;
     lock.l_type = F_UNLCK;
     if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
-      rc = SQLITE_IOERR;  /* This should never happen */
+      rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
       goto end_lock;
     }
     if( s ){
@@ -1469,7 +1575,7 @@ static int unixUnlock(OsFile *id, int locktype){
       lock.l_len = SHARED_SIZE;
       if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
         /* This should never happen */
-        rc = SQLITE_IOERR;
+        rc = SQLITE_IOERR_RDLOCK;
       }
     }
     lock.l_type = F_UNLCK;
@@ -1479,7 +1585,7 @@ static int unixUnlock(OsFile *id, int locktype){
     if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
       pLock->locktype = SHARED_LOCK;
     }else{
-      rc = SQLITE_IOERR;  /* This should never happen */
+      rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
     }
   }
   if( locktype==NO_LOCK ){
@@ -1497,7 +1603,7 @@ static int unixUnlock(OsFile *id, int locktype){
       if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
         pLock->locktype = NO_LOCK;
       }else{
-        rc = SQLITE_IOERR;  /* This should never happen */
+        rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
       }
     }
 
@@ -1567,6 +1673,581 @@ static int unixClose(OsFile **pId){
   return SQLITE_OK;
 }
 
+
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+#pragma mark AFP Support
+
+/*
+ ** The afpLockingContext structure contains all afp lock specific state
+ */
+typedef struct afpLockingContext afpLockingContext;
+struct afpLockingContext {
+  unsigned long long sharedLockByte;
+  char *filePath;
+};
+
+struct ByteRangeLockPB2
+{
+  unsigned long long offset;        /* offset to first byte to lock */
+  unsigned long long length;        /* nbr of bytes to lock */
+  unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
+  unsigned char unLockFlag;         /* 1 = unlock, 0 = lock */
+  unsigned char startEndFlag;       /* 1=rel to end of fork, 0=rel to start */
+  int fd;                           /* file desc to assoc this lock with */
+};
+
+#define afpfsByteRangeLock2FSCTL       _IOWR('z', 23, struct ByteRangeLockPB2)
+
+/* return 0 on success, 1 on failure.  To match the behavior of the 
+  normal posix file locking (used in unixLock for example), we should 
+  provide 'richer' return codes - specifically to differentiate between
+  'file busy' and 'file system error' results */
+static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset, 
+                         unsigned long long length, int setLockFlag)
+{
+  struct ByteRangeLockPB2      pb;
+  int                     err;
+  
+  pb.unLockFlag = setLockFlag ? 0 : 1;
+  pb.startEndFlag = 0;
+  pb.offset = offset;
+  pb.length = length; 
+  pb.fd = fd;
+  TRACE5("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, 
+      strerror(errno));
+    return 1; // error
+  } else {
+    return 0;
+  }
+}
+
+/*
+ ** This routine checks if there is a RESERVED lock held on the specified
+ ** file by this or any other process. If such a lock is held, return
+ ** non-zero.  If the file is unlocked or holds only SHARED locks, then
+ ** return zero.
+ */
+static int afpUnixCheckReservedLock(OsFile *id){
+  int r = 0;
+  unixFile *pFile = (unixFile*)id;
+  
+  assert( pFile ); 
+  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+  
+  /* Check if a thread in this process holds such a lock */
+  if( pFile->locktype>SHARED_LOCK ){
+    r = 1;
+  }
+  
+  /* Otherwise see if some other process holds it.
+   */
+  if ( !r ) {
+    // lock the byte
+    int failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1);  
+    if (failed) {
+      /* if we failed to get the lock then someone else must have it */
+      r = 1;
+    } else {
+      /* if we succeeded in taking the reserved lock, unlock it to restore
+      ** the original state */
+      _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0);
+    }
+  }
+  TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
+  
+  return r;
+}
+
+/* AFP-style locking following the behavior of unixLock, see the unixLock 
+** function comments for details of lock management. */
+static int afpUnixLock(OsFile *id, int locktype)
+{
+  int rc = SQLITE_OK;
+  unixFile *pFile = (unixFile*)id;
+  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+  int gotPendingLock = 0;
+  
+  assert( pFile );
+  TRACE5("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,
+           locktypeName(locktype));
+    return SQLITE_OK;
+  }
+
+  /* Make sure the locking sequence is correct
+    */
+  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+  assert( locktype!=PENDING_LOCK );
+  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
+  
+  /* This mutex is needed because pFile->pLock is shared across threads
+    */
+  sqlite3OsEnterMutex();
+
+  /* Make sure the current thread owns the pFile.
+    */
+  rc = transferOwnership(pFile);
+  if( rc!=SQLITE_OK ){
+    sqlite3OsLeaveMutex();
+    return rc;
+  }
+    
+  /* A PENDING lock is needed before acquiring a SHARED lock and before
+    ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
+    ** be released.
+    */
+  if( locktype==SHARED_LOCK 
+      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
+      ){
+    int failed = _AFPFSSetLock(context->filePath, pFile->h, 
+      PENDING_BYTE, 1, 1);
+    if (failed) {
+      rc = SQLITE_BUSY;
+      goto afp_end_lock;
+    }
+  }
+  
+  /* If control gets to this point, then actually go ahead and make
+    ** operating system calls for the specified lock.
+    */
+  if( locktype==SHARED_LOCK ){
+    int lk, failed;
+    int tries = 0;
+    
+    /* Now get the read-lock */
+    /* note that the quality of the randomness doesn't matter that much */
+    lk = random(); 
+    context->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
+    failed = _AFPFSSetLock(context->filePath, pFile->h, 
+      SHARED_FIRST+context->sharedLockByte, 1, 1);
+    
+    /* Drop the temporary PENDING lock */
+    if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)) {
+      rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
+      goto afp_end_lock;
+    }
+    
+    if( failed ){
+      rc = SQLITE_BUSY;
+    } else {
+      pFile->locktype = SHARED_LOCK;
+    }
+  }else{
+    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
+    ** assumed that there is a SHARED or greater lock on the file
+    ** already.
+    */
+    int failed = 0;
+    assert( 0!=pFile->locktype );
+    if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) {
+        /* Acquire a RESERVED lock */
+        failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1);
+    }
+    if (!failed && locktype == EXCLUSIVE_LOCK) {
+      /* Acquire an EXCLUSIVE lock */
+        
+      /* Remove the shared lock before trying the range.  we'll need to 
+      ** reestablish the shared lock if we can't get the  afpUnixUnlock
+      */
+      if (!_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST +
+                         context->sharedLockByte, 1, 0)) {
+        /* now attemmpt to get the exclusive lock range */
+        failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST, 
+                               SHARED_SIZE, 1);
+        if (failed && _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST +
+                                    context->sharedLockByte, 1, 1)) {
+          rc = SQLITE_IOERR_RDLOCK; /* this should never happen */
+        }
+      } else {
+        /* */
+        rc = SQLITE_IOERR_UNLOCK; /* this should never happen */
+      }
+    }
+    if( failed && rc == SQLITE_OK){
+      rc = SQLITE_BUSY;
+    }
+  }
+  
+  if( rc==SQLITE_OK ){
+    pFile->locktype = locktype;
+  }else if( locktype==EXCLUSIVE_LOCK ){
+    pFile->locktype = PENDING_LOCK;
+  }
+  
+afp_end_lock:
+    sqlite3OsLeaveMutex();
+  TRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
+         rc==SQLITE_OK ? "ok" : "failed");
+  return rc;
+}
+
+/*
+ ** Lower the locking level on file descriptor pFile to locktype.  locktype
+ ** must be either NO_LOCK or SHARED_LOCK.
+ **
+ ** If the locking level of the file descriptor is already at or below
+ ** the requested locking level, this routine is a no-op.
+ */
+static int afpUnixUnlock(OsFile *id, int locktype) {
+  struct flock lock;
+  int rc = SQLITE_OK;
+  unixFile *pFile = (unixFile*)id;
+  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+
+  assert( pFile );
+  TRACE5("UNLOCK  %d %d was %d pid=%d\n", pFile->h, locktype,
+         pFile->locktype, getpid());
+  
+  assert( locktype<=SHARED_LOCK );
+  if( pFile->locktype<=locktype ){
+    return SQLITE_OK;
+  }
+  if( CHECK_THREADID(pFile) ){
+    return SQLITE_MISUSE;
+  }
+  sqlite3OsEnterMutex();
+  if( pFile->locktype>SHARED_LOCK ){
+    if( locktype==SHARED_LOCK ){
+      int failed = 0;
+
+      /* unlock the exclusive range - then re-establish the shared lock */
+      if (pFile->locktype==EXCLUSIVE_LOCK) {
+        failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST, 
+                                 SHARED_SIZE, 0);
+        if (!failed) {
+          /* successfully removed the exclusive lock */
+          if (_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST+
+                            context->sharedLockByte, 1, 1)) {
+            /* failed to re-establish our shared lock */
+            rc = SQLITE_IOERR_RDLOCK; /* This should never happen */
+          }
+        } else {
+          /* This should never happen - failed to unlock the exclusive range */
+          rc = SQLITE_IOERR_UNLOCK;
+        } 
+      }
+    }
+    if (rc == SQLITE_OK && pFile->locktype>=PENDING_LOCK) {
+      if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)){
+        /* failed to release the pending lock */
+        rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
+      }
+    } 
+    if (rc == SQLITE_OK && pFile->locktype>=RESERVED_LOCK) {
+      if (_AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0)) {
+        /* failed to release the reserved lock */
+        rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
+      }
+    } 
+  }
+  if( locktype==NO_LOCK ){
+    int failed = _AFPFSSetLock(context->filePath, pFile->h, 
+                               SHARED_FIRST + context->sharedLockByte, 1, 0);
+    if (failed) {
+      rc = SQLITE_IOERR_UNLOCK;  /* This should never happen */
+    }
+  }
+  if (rc == SQLITE_OK)
+    pFile->locktype = locktype;
+  sqlite3OsLeaveMutex();
+  return rc;
+}
+
+/*
+ ** Close a file & cleanup AFP specific locking context 
+ */
+static int afpUnixClose(OsFile **pId) {
+  unixFile *id = (unixFile*)*pId;
+  
+  if( !id ) return SQLITE_OK;
+  afpUnixUnlock(*pId, NO_LOCK);
+  /* free the AFP locking structure */
+  if (id->lockingContext != NULL) {
+    if (((afpLockingContext *)id->lockingContext)->filePath != NULL)
+      sqlite3ThreadSafeFree(((afpLockingContext*)id->lockingContext)->filePath);
+    sqlite3ThreadSafeFree(id->lockingContext);
+  }
+  
+  if( id->dirfd>=0 ) close(id->dirfd);
+  id->dirfd = -1;
+  close(id->h);
+  id->isOpen = 0;
+  TRACE2("CLOSE   %-3d\n", id->h);
+  OpenCounter(-1);
+  sqlite3ThreadSafeFree(id);
+  *pId = 0;
+  return SQLITE_OK;
+}
+
+
+#pragma mark flock() style locking
+
+/*
+ ** The flockLockingContext is not used
+ */
+typedef void flockLockingContext;
+
+static int flockUnixCheckReservedLock(OsFile *id) {
+  unixFile *pFile = (unixFile*)id;
+  
+  if (pFile->locktype == RESERVED_LOCK) {
+    return 1; // already have a reserved lock
+  } else {
+    // attempt to get the lock
+    int rc = flock(pFile->h, LOCK_EX | LOCK_NB);
+    if (!rc) {
+      // got the lock, unlock it
+      flock(pFile->h, LOCK_UN);
+      return 0;  // no one has it reserved
+    }
+    return 1; // someone else might have it reserved
+  }
+}
+
+static int flockUnixLock(OsFile *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  
+  // if we already have a lock, it is exclusive.  
+  // Just adjust level and punt on outta here.
+  if (pFile->locktype > NO_LOCK) {
+    pFile->locktype = locktype;
+    return SQLITE_OK;
+  }
+  
+  // grab an exclusive lock
+  int rc = flock(pFile->h, LOCK_EX | LOCK_NB);
+  if (rc) {
+    // didn't get, must be busy
+    return SQLITE_BUSY;
+  } else {
+    // got it, set the type and return ok
+    pFile->locktype = locktype;
+    return SQLITE_OK;
+  }
+}
+
+static int flockUnixUnlock(OsFile *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  
+  assert( locktype<=SHARED_LOCK );
+  
+  // no-op if possible
+  if( pFile->locktype==locktype ){
+    return SQLITE_OK;
+  }
+  
+  // shared can just be set because we always have an exclusive
+  if (locktype==SHARED_LOCK) {
+    pFile->locktype = locktype;
+    return SQLITE_OK;
+  }
+  
+  // no, really, unlock.
+  int rc = flock(pFile->h, LOCK_UN);
+  if (rc)
+    return SQLITE_IOERR_UNLOCK;
+  else {
+    pFile->locktype = NO_LOCK;
+    return SQLITE_OK;
+  }
+}
+
+/*
+ ** Close a file.
+ */
+static int flockUnixClose(OsFile **pId) {
+  unixFile *id = (unixFile*)*pId;
+  
+  if( !id ) return SQLITE_OK;
+  flockUnixUnlock(*pId, NO_LOCK);
+  
+  if( id->dirfd>=0 ) close(id->dirfd);
+  id->dirfd = -1;
+  sqlite3OsEnterMutex();
+  
+  close(id->h);  
+  sqlite3OsLeaveMutex();
+  id->isOpen = 0;
+  TRACE2("CLOSE   %-3d\n", id->h);
+  OpenCounter(-1);
+  sqlite3ThreadSafeFree(id);
+  *pId = 0;
+  return SQLITE_OK;
+}
+
+#pragma mark Old-School .lock file based locking
+
+/*
+ ** The dotlockLockingContext structure contains all dotlock (.lock) lock
+ ** specific state
+ */
+typedef struct dotlockLockingContext dotlockLockingContext;
+struct dotlockLockingContext {
+  char *lockPath;
+};
+
+
+static int dotlockUnixCheckReservedLock(OsFile *id) {
+  unixFile *pFile = (unixFile*)id;
+  dotlockLockingContext *context = 
+    (dotlockLockingContext *) pFile->lockingContext;
+  
+  if (pFile->locktype == RESERVED_LOCK) {
+    return 1; // already have a reserved lock
+  } else {
+    struct stat statBuf;
+    if (lstat(context->lockPath,&statBuf) == 0)
+      // file exists, someone else has the lock
+      return 1;
+    else
+      // file does not exist, we could have it if we want it
+      return 0;
+  }
+}
+
+static int dotlockUnixLock(OsFile *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  dotlockLockingContext *context = 
+    (dotlockLockingContext *) pFile->lockingContext;
+  
+  // if we already have a lock, it is exclusive.  
+  // Just adjust level and punt on outta here.
+  if (pFile->locktype > NO_LOCK) {
+    pFile->locktype = locktype;
+    
+    /* Always update the timestamp on the old file */
+    utimes(context->lockPath,NULL);
+    return SQLITE_OK;
+  }
+  
+  // check to see if lock file already exists
+  struct stat statBuf;
+  if (lstat(context->lockPath,&statBuf) == 0){
+    return SQLITE_BUSY; // it does, busy
+  }
+  
+  // grab an exclusive lock
+  int fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600);
+  if (fd < 0) {
+    // failed to open/create the file, someone else may have stolen the lock
+    return SQLITE_BUSY; 
+  }
+  close(fd);
+  
+  // got it, set the type and return ok
+  pFile->locktype = locktype;
+  return SQLITE_OK;
+}
+
+static int dotlockUnixUnlock(OsFile *id, int locktype) {
+  unixFile *pFile = (unixFile*)id;
+  dotlockLockingContext *context = 
+    (dotlockLockingContext *) pFile->lockingContext;
+  
+  assert( locktype<=SHARED_LOCK );
+  
+  // no-op if possible
+  if( pFile->locktype==locktype ){
+    return SQLITE_OK;
+  }
+  
+  // shared can just be set because we always have an exclusive
+  if (locktype==SHARED_LOCK) {
+    pFile->locktype = locktype;
+    return SQLITE_OK;
+  }
+  
+  // no, really, unlock.
+  unlink(context->lockPath);
+  pFile->locktype = NO_LOCK;
+  return SQLITE_OK;
+}
+
+/*
+ ** Close a file.
+ */
+static int dotlockUnixClose(OsFile **pId) {
+  unixFile *id = (unixFile*)*pId;
+  
+  if( !id ) return SQLITE_OK;
+  dotlockUnixUnlock(*pId, NO_LOCK);
+  /* free the dotlock locking structure */
+  if (id->lockingContext != NULL) {
+    if (((dotlockLockingContext *)id->lockingContext)->lockPath != NULL)
+      sqlite3ThreadSafeFree( ( (dotlockLockingContext *)
+        id->lockingContext)->lockPath);
+    sqlite3ThreadSafeFree(id->lockingContext);
+  }
+  
+  if( id->dirfd>=0 ) close(id->dirfd);
+  id->dirfd = -1;
+  sqlite3OsEnterMutex();
+  
+  close(id->h);
+  
+  sqlite3OsLeaveMutex();
+  id->isOpen = 0;
+  TRACE2("CLOSE   %-3d\n", id->h);
+  OpenCounter(-1);
+  sqlite3ThreadSafeFree(id);
+  *pId = 0;
+  return SQLITE_OK;
+}
+
+
+#pragma mark No locking
+
+/*
+ ** The nolockLockingContext is void
+ */
+typedef void nolockLockingContext;
+
+static int nolockUnixCheckReservedLock(OsFile *id) {
+  return 0;
+}
+
+static int nolockUnixLock(OsFile *id, int locktype) {
+  return SQLITE_OK;
+}
+
+static int nolockUnixUnlock(OsFile *id, int locktype) {
+  return SQLITE_OK;
+}
+
+/*
+ ** Close a file.
+ */
+static int nolockUnixClose(OsFile **pId) {
+  unixFile *id = (unixFile*)*pId;
+  
+  if( !id ) return SQLITE_OK;
+  if( id->dirfd>=0 ) close(id->dirfd);
+  id->dirfd = -1;
+  sqlite3OsEnterMutex();
+  
+  close(id->h);
+  
+  sqlite3OsLeaveMutex();
+  id->isOpen = 0;
+  TRACE2("CLOSE   %-3d\n", id->h);
+  OpenCounter(-1);
+  sqlite3ThreadSafeFree(id);
+  *pId = 0;
+  return SQLITE_OK;
+}
+
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
 /*
 ** Turn a relative pathname into a full pathname.  Return a pointer
 ** to the full pathname stored in space obtained from sqliteMalloc().
@@ -1660,36 +2341,239 @@ static const IoMethod sqlite3UnixIoMethod = {
   unixCheckReservedLock,
 };
 
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+/*
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with AFP style file locking.
+ */
+static const IoMethod sqlite3AFPLockingUnixIoMethod = {
+    afpUnixClose,
+    unixOpenDirectory,
+    unixRead,
+    unixWrite,
+    unixSeek,
+    unixTruncate,
+    unixSync,
+    unixSetFullSync,
+    unixFileHandle,
+    unixFileSize,
+    afpUnixLock,
+    afpUnixUnlock,
+    unixLockState,
+    afpUnixCheckReservedLock,
+};
+
 /*
-** Allocate memory for a unixFile.  Initialize the new unixFile
-** to the value given in pInit and return a pointer to the new
-** OsFile.  If we run out of memory, close the file and return NULL.
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with flock() style file locking.
+ */
+static const IoMethod sqlite3FlockLockingUnixIoMethod = {
+    flockUnixClose,
+    unixOpenDirectory,
+    unixRead,
+    unixWrite,
+    unixSeek,
+    unixTruncate,
+    unixSync,
+    unixSetFullSync,
+    unixFileHandle,
+    unixFileSize,
+    flockUnixLock,
+    flockUnixUnlock,
+    unixLockState,
+    flockUnixCheckReservedLock,
+};
+
+/*
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with dotlock style file locking.
+ */
+static const IoMethod sqlite3DotlockLockingUnixIoMethod = {
+    dotlockUnixClose,
+    unixOpenDirectory,
+    unixRead,
+    unixWrite,
+    unixSeek,
+    unixTruncate,
+    unixSync,
+    unixSetFullSync,
+    unixFileHandle,
+    unixFileSize,
+    dotlockUnixLock,
+    dotlockUnixUnlock,
+    unixLockState,
+    dotlockUnixCheckReservedLock,
+};
+
+/*
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with dotlock style file locking.
+ */
+static const IoMethod sqlite3NolockLockingUnixIoMethod = {
+  nolockUnixClose,
+  unixOpenDirectory,
+  unixRead,
+  unixWrite,
+  unixSeek,
+  unixTruncate,
+  unixSync,
+  unixSetFullSync,
+  unixFileHandle,
+  unixFileSize,
+  nolockUnixLock,
+  nolockUnixUnlock,
+  unixLockState,
+  nolockUnixCheckReservedLock,
+};
+
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
+/*
+** Allocate memory for a new unixFile and initialize that unixFile.
+** Write a pointer to the new unixFile into *pId.
+** If we run out of memory, close the file and return an error.
 */
-static int allocateUnixFile(unixFile *pInit, OsFile **pId){
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+/* 
+ ** When locking extensions are enabled, the filepath and locking style 
+ ** are needed to determine the unixFile pMethod to use for locking operations.
+ ** The locking-style specific lockingContext data structure is created 
+ ** and assigned here also.
+ */
+static int allocateUnixFile(
+  int h,                  /* Open file descriptor of file being opened */
+  OsFile **pId,           /* Write completed initialization here */
+  const char *zFilename,  /* Name of the file being opened */
+  int delFlag             /* Delete-on-or-before-close flag */
+){
+  sqlite3LockingStyle lockingStyle;
   unixFile *pNew;
-  pInit->dirfd = -1;
-  pInit->fullSync = 0;
-  pInit->locktype = 0;
-  pInit->offset = 0;
-  SET_THREADID(pInit);
+  unixFile f;
+  int rc;
+
+  lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
+  if ( lockingStyle == posixLockingStyle ) {
+    sqlite3OsEnterMutex();
+    rc = findLockInfo(h, &f.pLock, &f.pOpen);
+    sqlite3OsLeaveMutex();
+    if( rc ){
+      close(h);
+      unlink(zFilename);
+      return SQLITE_NOMEM;
+    }
+  } else {
+    //  pLock and pOpen are only used for posix advisory locking 
+    f.pLock = NULL;
+    f.pOpen = NULL;
+  }
+  if( delFlag ){
+    unlink(zFilename);
+  }
+  f.dirfd = -1;
+  f.fullSync = 0;
+  f.locktype = 0;
+  f.offset = 0;
+  f.h = h;
+  SET_THREADID(&f);
   pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) );
   if( pNew==0 ){
-    close(pInit->h);
+    close(h);
     sqlite3OsEnterMutex();
-    releaseLockInfo(pInit->pLock);
-    releaseOpenCnt(pInit->pOpen);
+    releaseLockInfo(f.pLock);
+    releaseOpenCnt(f.pOpen);
     sqlite3OsLeaveMutex();
     *pId = 0;
     return SQLITE_NOMEM;
   }else{
-    *pNew = *pInit;
-    pNew->pMethod = &sqlite3UnixIoMethod;
+    *pNew = f;
+    switch(lockingStyle) {
+      case afpLockingStyle:
+        /* afp locking uses the file path so it needs to be included in
+        ** the afpLockingContext */
+        pNew->pMethod = &sqlite3AFPLockingUnixIoMethod;
+        pNew->lockingContext = 
+          sqlite3ThreadSafeMalloc(sizeof(afpLockingContext));
+        ((afpLockingContext *)pNew->lockingContext)->filePath = 
+          sqlite3ThreadSafeMalloc(strlen(zFilename) + 1);
+        strcpy(((afpLockingContext *)pNew->lockingContext)->filePath, 
+               zFilename);
+        srandomdev();
+        break;
+      case flockLockingStyle:
+        /* flock locking doesn't need additional lockingContext information */
+        pNew->pMethod = &sqlite3FlockLockingUnixIoMethod;
+        break;
+      case dotlockLockingStyle:
+        /* dotlock locking uses the file path so it needs to be included in
+         ** the dotlockLockingContext */
+        pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod;
+        pNew->lockingContext = sqlite3ThreadSafeMalloc(
+          sizeof(dotlockLockingContext));
+        ((dotlockLockingContext *)pNew->lockingContext)->lockPath = 
+            sqlite3ThreadSafeMalloc(strlen(zFilename) + strlen(".lock") + 1);
+        sprintf(((dotlockLockingContext *)pNew->lockingContext)->lockPath, 
+                "%s.lock", zFilename);
+        break;
+      case posixLockingStyle:
+        /* posix locking doesn't need additional lockingContext information */
+        pNew->pMethod = &sqlite3UnixIoMethod;
+        break;
+      case noLockingStyle:
+      case unsupportedLockingStyle:
+      default: 
+        pNew->pMethod = &sqlite3NolockLockingUnixIoMethod;
+    }
     *pId = (OsFile*)pNew;
     OpenCounter(+1);
     return SQLITE_OK;
   }
 }
+#else /* SQLITE_ENABLE_LOCKING_STYLE */
+static int allocateUnixFile(
+  int h,                 /* Open file descriptor on file being opened */
+  OsFile **pId,          /* Write the resul unixFile structure here */
+  const char *zFilename, /* Name of the file being opened */
+  int delFlag            /* If true, delete the file on or before closing */
+){
+  unixFile *pNew;
+  unixFile f;
+  int rc;
 
+  sqlite3OsEnterMutex();
+  rc = findLockInfo(h, &f.pLock, &f.pOpen);
+  sqlite3OsLeaveMutex();
+  if( delFlag ){
+    unlink(zFilename);
+  }
+  if( rc ){
+    close(h);
+    return SQLITE_NOMEM;
+  }
+  TRACE3("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) );
+  if( pNew==0 ){
+    close(h);
+    sqlite3OsEnterMutex();
+    releaseLockInfo(f.pLock);
+    releaseOpenCnt(f.pOpen);
+    sqlite3OsLeaveMutex();
+    *pId = 0;
+    return SQLITE_NOMEM;
+  }else{
+    *pNew = f;
+    pNew->pMethod = &sqlite3UnixIoMethod;
+    *pId = (OsFile*)pNew;
+    OpenCounter(+1);
+    return SQLITE_OK;
+  }
+}
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
 #endif /* SQLITE_OMIT_DISKIO */
 /***************************************************************************
@@ -1698,6 +2582,23 @@ static int allocateUnixFile(unixFile *pInit, OsFile **pId){
 ****************************************************************************/
 
 
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+#include <dlfcn.h>
+void *sqlite3UnixDlopen(const char *zFilename){
+  return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
+}
+void *sqlite3UnixDlsym(void *pHandle, const char *zSymbol){
+  return dlsym(pHandle, zSymbol);
+}
+int sqlite3UnixDlclose(void *pHandle){
+  return dlclose(pHandle);
+}
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
 /*
 ** Get information to seed the random number generator.  The seed
 ** is written into the buffer zBuf[256].  The calling function must
index 6c167ab5b8dc782902646768fa51cdef09884a3b..2fcc245709f5a50f6c346fe988b1f288486e10e7 100644 (file)
@@ -40,6 +40,7 @@
 */
 #if defined(_WIN32_WCE)
 # define OS_WINCE 1
+# define AreFileApisANSI() 1
 #else
 # define OS_WINCE 0
 #endif
@@ -124,16 +125,14 @@ int sqlite3_os_type = 0;
 #endif /* OS_WINCE */
 
 /*
-** Convert a UTF-8 string to UTF-32.  Space to hold the returned string
-** is obtained from sqliteMalloc.
+** Convert a UTF-8 string to microsoft unicode (UTF-16?). 
+**
+** Space to hold the returned string is obtained from sqliteMalloc.
 */
 static WCHAR *utf8ToUnicode(const char *zFilename){
   int nChar;
   WCHAR *zWideFilename;
 
-  if( !isNT() ){
-    return 0;
-  }
   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
   zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
   if( zWideFilename==0 ){
@@ -148,7 +147,7 @@ static WCHAR *utf8ToUnicode(const char *zFilename){
 }
 
 /*
-** Convert UTF-32 to UTF-8.  Space to hold the returned string is
+** Convert microsoft unicode to UTF-8.  Space to hold the returned string is
 ** obtained from sqliteMalloc().
 */
 static char *unicodeToUtf8(const WCHAR *zWideFilename){
@@ -169,6 +168,91 @@ static char *unicodeToUtf8(const WCHAR *zWideFilename){
   return zFilename;
 }
 
+/*
+** Convert an ansi string to microsoft unicode, based on the
+** current codepage settings for file apis.
+** 
+** Space to hold the returned string is obtained
+** from sqliteMalloc.
+*/
+static WCHAR *mbcsToUnicode(const char *zFilename){
+  int nByte;
+  WCHAR *zMbcsFilename;
+  int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+  nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
+  zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) );
+  if( zMbcsFilename==0 ){
+    return 0;
+  }
+  nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
+  if( nByte==0 ){
+    sqliteFree(zMbcsFilename);
+    zMbcsFilename = 0;
+  }
+  return zMbcsFilename;
+}
+
+/*
+** Convert microsoft unicode to multibyte character string, based on the
+** user's Ansi codepage.
+**
+** Space to hold the returned string is obtained from
+** sqliteMalloc().
+*/
+static char *unicodeToMbcs(const WCHAR *zWideFilename){
+  int nByte;
+  char *zFilename;
+  int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+  nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
+  zFilename = sqliteMalloc( nByte );
+  if( zFilename==0 ){
+    return 0;
+  }
+  nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
+                              0, 0);
+  if( nByte == 0 ){
+    sqliteFree(zFilename);
+    zFilename = 0;
+  }
+  return zFilename;
+}
+
+/*
+** Convert multibyte character string to UTF-8.  Space to hold the
+** returned string is obtained from sqliteMalloc().
+*/
+static char *mbcsToUtf8(const char *zFilename){
+  char *zFilenameUtf8;
+  WCHAR *zTmpWide;
+
+  zTmpWide = mbcsToUnicode(zFilename);
+  if( zTmpWide==0 ){
+    return 0;
+  }
+  zFilenameUtf8 = unicodeToUtf8(zTmpWide);
+  sqliteFree(zTmpWide);
+  return zFilenameUtf8;
+}
+
+/*
+** Convert UTF-8 to multibyte character string.  Space to hold the 
+** returned string is obtained from sqliteMalloc().
+*/
+static char *utf8ToMbcs(const char *zFilename){
+  char *zFilenameMbcs;
+  WCHAR *zTmpWide;
+
+  zTmpWide = utf8ToUnicode(zFilename);
+  if( zTmpWide==0 ){
+    return 0;
+  }
+  zFilenameMbcs = unicodeToMbcs(zTmpWide);
+  sqliteFree(zTmpWide);
+  return zFilenameMbcs;
+}
+
 #if OS_WINCE
 /*************************************************************************
 ** This section contains code for WinCE only.
@@ -475,6 +559,23 @@ static BOOL winceLockFileEx(
 *****************************************************************************/
 #endif /* OS_WINCE */
 
+/*
+** Convert a UTF-8 filename into whatever form the underlying
+** operating system wants filenames in.  Space to hold the result
+** is obtained from sqliteMalloc and must be freed by the calling
+** function.
+*/
+static void *convertUtf8Filename(const char *zFilename){
+  void *zConverted = 0;
+  if( isNT() ){
+    zConverted = utf8ToUnicode(zFilename);
+  }else{
+    zConverted = utf8ToMbcs(zFilename);
+  }
+  /* caller will handle out of memory */
+  return zConverted;
+}
+
 /*
 ** Delete the named file.
 **
@@ -489,25 +590,30 @@ static BOOL winceLockFileEx(
 */
 #define MX_DELETION_ATTEMPTS 3
 int sqlite3WinDelete(const char *zFilename){
-  WCHAR *zWide = utf8ToUnicode(zFilename);
   int cnt = 0;
   int rc;
-  if( zWide ){
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
+  if( isNT() ){
     do{
-      rc = DeleteFileW(zWide);
-    }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
-    sqliteFree(zWide);
+      rc = DeleteFileW(zConverted);
+    }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff 
+            && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
   }else{
 #if OS_WINCE
     return SQLITE_NOMEM;
 #else
     do{
-      rc = DeleteFileA(zFilename);
-    }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
+      rc = DeleteFileA(zConverted);
+    }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
+            && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
 #endif
   }
+  sqliteFree(zConverted);
   TRACE2("DELETE \"%s\"\n", zFilename);
-  return rc==0 ? SQLITE_OK : SQLITE_IOERR;
+  return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
 }
 
 /*
@@ -515,17 +621,20 @@ int sqlite3WinDelete(const char *zFilename){
 */
 int sqlite3WinFileExists(const char *zFilename){
   int exists = 0;
-  WCHAR *zWide = utf8ToUnicode(zFilename);
-  if( zWide ){
-    exists = GetFileAttributesW(zWide) != 0xffffffff;
-    sqliteFree(zWide);
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
+  if( isNT() ){
+    exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff;
   }else{
 #if OS_WINCE
     return SQLITE_NOMEM;
 #else
-    exists = GetFileAttributesA(zFilename) != 0xffffffff;
+    exists = GetFileAttributesA((char*)zConverted) != 0xffffffff;
 #endif
   }
+  sqliteFree(zConverted);
   return exists;
 }
 
@@ -552,10 +661,14 @@ int sqlite3WinOpenReadWrite(
 ){
   winFile f;
   HANDLE h;
-  WCHAR *zWide = utf8ToUnicode(zFilename);
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
   assert( *pId==0 );
-  if( zWide ){
-    h = CreateFileW(zWide,
+
+  if( isNT() ){
+    h = CreateFileW((WCHAR*)zConverted,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
@@ -564,7 +677,7 @@ int sqlite3WinOpenReadWrite(
        NULL
     );
     if( h==INVALID_HANDLE_VALUE ){
-      h = CreateFileW(zWide,
+      h = CreateFileW((WCHAR*)zConverted,
          GENERIC_READ,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          NULL,
@@ -573,7 +686,7 @@ int sqlite3WinOpenReadWrite(
          NULL
       );
       if( h==INVALID_HANDLE_VALUE ){
-        sqliteFree(zWide);
+        sqliteFree(zConverted);
         return SQLITE_CANTOPEN;
       }
       *pReadonly = 1;
@@ -583,16 +696,15 @@ int sqlite3WinOpenReadWrite(
 #if OS_WINCE
     if (!winceCreateLock(zFilename, &f)){
       CloseHandle(h);
-      sqliteFree(zWide);
+      sqliteFree(zConverted);
       return SQLITE_CANTOPEN;
     }
 #endif
-    sqliteFree(zWide);
   }else{
 #if OS_WINCE
     return SQLITE_NOMEM;
 #else
-    h = CreateFileA(zFilename,
+    h = CreateFileA((char*)zConverted,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
@@ -601,7 +713,7 @@ int sqlite3WinOpenReadWrite(
        NULL
     );
     if( h==INVALID_HANDLE_VALUE ){
-      h = CreateFileA(zFilename,
+      h = CreateFileA((char*)zConverted,
          GENERIC_READ,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          NULL,
@@ -610,6 +722,7 @@ int sqlite3WinOpenReadWrite(
          NULL
       );
       if( h==INVALID_HANDLE_VALUE ){
+        sqliteFree(zConverted);
         return SQLITE_CANTOPEN;
       }
       *pReadonly = 1;
@@ -618,6 +731,9 @@ int sqlite3WinOpenReadWrite(
     }
 #endif /* OS_WINCE */
   }
+
+  sqliteFree(zConverted);
+
   f.h = h;
 #if OS_WINCE
   f.zDeleteOnClose = 0;
@@ -650,8 +766,11 @@ int sqlite3WinOpenReadWrite(
 int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
   winFile f;
   HANDLE h;
-  int fileflags;
-  WCHAR *zWide = utf8ToUnicode(zFilename);
+  DWORD fileflags;
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
   assert( *pId == 0 );
   fileflags = FILE_FLAG_RANDOM_ACCESS;
 #if !OS_WINCE
@@ -659,10 +778,10 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
     fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
   }
 #endif
-  if( zWide ){
+  if( isNT() ){
     int cnt = 0;
     do{
-      h = CreateFileW(zWide,
+      h = CreateFileW((WCHAR*)zConverted,
          GENERIC_READ | GENERIC_WRITE,
          0,
          NULL,
@@ -671,14 +790,13 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
          NULL
       );
     }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
-    sqliteFree(zWide);
   }else{
 #if OS_WINCE
     return SQLITE_NOMEM;
 #else
     int cnt = 0;
     do{
-      h = CreateFileA(zFilename,
+      h = CreateFileA((char*)zConverted,
         GENERIC_READ | GENERIC_WRITE,
         0,
         NULL,
@@ -689,14 +807,18 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
     }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
 #endif /* OS_WINCE */
   }
+#if OS_WINCE
+  if( delFlag && h!=INVALID_HANDLE_VALUE ){
+    f.zDeleteOnClose = zConverted;
+    zConverted = 0;
+  }
+  f.hMutex = NULL;
+#endif
+  sqliteFree(zConverted);
   if( h==INVALID_HANDLE_VALUE ){
     return SQLITE_CANTOPEN;
   }
   f.h = h;
-#if OS_WINCE
-  f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0;
-  f.hMutex = NULL;
-#endif
   TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
   return allocateWinFile(&f, pId);
 }
@@ -711,10 +833,13 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
 int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
   winFile f;
   HANDLE h;
-  WCHAR *zWide = utf8ToUnicode(zFilename);
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
   assert( *pId==0 );
-  if( zWide ){
-    h = CreateFileW(zWide,
+  if( isNT() ){
+    h = CreateFileW((WCHAR*)zConverted,
        GENERIC_READ,
        0,
        NULL,
@@ -722,12 +847,11 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
        NULL
     );
-    sqliteFree(zWide);
   }else{
 #if OS_WINCE
     return SQLITE_NOMEM;
 #else
-    h = CreateFileA(zFilename,
+    h = CreateFileA((char*)zConverted,
        GENERIC_READ,
        0,
        NULL,
@@ -737,6 +861,7 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
     );
 #endif
   }
+  sqliteFree(zConverted);
   if( h==INVALID_HANDLE_VALUE ){
     return SQLITE_CANTOPEN;
   }
@@ -802,9 +927,21 @@ int sqlite3WinTempFileName(char *zBuf){
       strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
       zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
       sqliteFree(zMulti);
+    }else{
+      return SQLITE_NOMEM;
     }
   }else{
-    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
+    char *zUtf8;
+    char zMbcsPath[SQLITE_TEMPNAME_SIZE];
+    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath);
+    zUtf8 = mbcsToUtf8(zMbcsPath);
+    if( zUtf8 ){
+      strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30);
+      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
+      sqliteFree(zUtf8);
+    }else{
+      return SQLITE_NOMEM;
+    }
   }
   for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
   zTempPath[i] = 0;
@@ -864,15 +1001,16 @@ static int winClose(OsFile **pId){
 static int winRead(OsFile *id, void *pBuf, int amt){
   DWORD got;
   assert( id!=0 );
-  SimulateIOError(SQLITE_IOERR);
+  SimulateIOError(return SQLITE_IOERR_READ);
   TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
   if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
-    got = 0;
+    return SQLITE_IOERR_READ;
   }
   if( got==(DWORD)amt ){
     return SQLITE_OK;
   }else{
-    return SQLITE_IOERR;
+    memset(&((char*)pBuf)[got], 0, amt-got);
+    return SQLITE_IOERR_SHORT_READ;
   }
 }
 
@@ -884,8 +1022,8 @@ static int winWrite(OsFile *id, const void *pBuf, int amt){
   int rc = 0;
   DWORD wrote;
   assert( id!=0 );
-  SimulateIOError(SQLITE_IOERR);
-  SimulateDiskfullError;
+  SimulateIOError(return SQLITE_IOERR_READ);
+  SimulateDiskfullError(return SQLITE_FULL);
   TRACE3("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
@@ -915,7 +1053,7 @@ static int winSeek(OsFile *id, i64 offset){
   DWORD rc;
   assert( id!=0 );
 #ifdef SQLITE_TEST
-  if( offset ) SimulateDiskfullError
+  if( offset ) SimulateDiskfullError(return SQLITE_FULL);
 #endif
   SEEK(offset/1024 + 1);
   rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
@@ -944,7 +1082,7 @@ static int winSync(OsFile *id, int dataOnly){
 ** than UNIX.
 */
 int sqlite3WinSyncDirectory(const char *zDirname){
-  SimulateIOError(SQLITE_IOERR);
+  SimulateIOError(return SQLITE_IOERR_READ);
   return SQLITE_OK;
 }
 
@@ -955,7 +1093,7 @@ static int winTruncate(OsFile *id, i64 nByte){
   LONG upperBits = nByte>>32;
   assert( id!=0 );
   TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
-  SimulateIOError(SQLITE_IOERR);
+  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
   SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
   SetEndOfFile(((winFile*)id)->h);
   return SQLITE_OK;
@@ -967,7 +1105,7 @@ static int winTruncate(OsFile *id, i64 nByte){
 static int winFileSize(OsFile *id, i64 *pSize){
   DWORD upperBits, lowerBits;
   assert( id!=0 );
-  SimulateIOError(SQLITE_IOERR);
+  SimulateIOError(return SQLITE_IOERR_FSTAT);
   lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
   *pSize = (((i64)upperBits)<<32) + lowerBits;
   return SQLITE_OK;
@@ -1022,20 +1160,24 @@ static int unlockReadLock(winFile *pFile){
 */
 int sqlite3WinIsDirWritable(char *zDirname){
   int fileAttr;
-  WCHAR *zWide;
+  void *zConverted;
   if( zDirname==0 ) return 0;
   if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
-  zWide = utf8ToUnicode(zDirname);
-  if( zWide ){
-    fileAttr = GetFileAttributesW(zWide);
-    sqliteFree(zWide);
+
+  zConverted = convertUtf8Filename(zDirname);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
+  if( isNT() ){
+    fileAttr = GetFileAttributesW((WCHAR*)zConverted);
   }else{
 #if OS_WINCE
     return 0;
 #else
-    fileAttr = GetFileAttributesA(zDirname);
+    fileAttr = GetFileAttributesA((char*)zConverted);
 #endif
   }
+  sqliteFree(zConverted);
   if( fileAttr == 0xffffffff ) return 0;
   if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
     return 0;
@@ -1224,7 +1366,7 @@ static int winUnlock(OsFile *id, int locktype){
     if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
       /* This should never happen.  We should always be able to
       ** reacquire the read lock */
-      rc = SQLITE_IOERR;
+      rc = SQLITE_IOERR_UNLOCK;
     }
   }
   if( type>=RESERVED_LOCK ){
@@ -1258,24 +1400,33 @@ char *sqlite3WinFullPathname(const char *zRelative){
   /* WinCE has no concept of a relative pathname, or so I am told. */
   zFull = sqliteStrDup(zRelative);
 #else
-  char *zNotUsed;
-  WCHAR *zWide;
   int nByte;
-  zWide = utf8ToUnicode(zRelative);
-  if( zWide ){
-    WCHAR *zTemp, *zNotUsedW;
-    nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
+  void *zConverted;
+  zConverted = convertUtf8Filename(zRelative);
+  if( isNT() ){
+    WCHAR *zTemp;
+    nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
     zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
-    if( zTemp==0 ) return 0;
-    GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
-    sqliteFree(zWide);
+    if( zTemp==0 ){
+      sqliteFree(zConverted);
+      return 0;
+    }
+    GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
+    sqliteFree(zConverted);
     zFull = unicodeToUtf8(zTemp);
     sqliteFree(zTemp);
   }else{
-    nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
-    zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
-    if( zFull==0 ) return 0;
-    GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
+    char *zTemp;
+    nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
+    zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
+    if( zTemp==0 ){
+      sqliteFree(zConverted);
+      return 0;
+    }
+    GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
+    sqliteFree(zConverted);
+    zFull = mbcsToUtf8(zTemp);
+    sqliteFree(zTemp);
   }
 #endif
   return zFull;
@@ -1357,6 +1508,45 @@ static int allocateWinFile(winFile *pInit, OsFile **pId){
 ** with other miscellanous aspects of the operating system interface
 ****************************************************************************/
 
+#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
+/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+void *sqlite3WinDlopen(const char *zFilename){
+  HANDLE h;
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return 0;
+  }
+  if( isNT() ){
+    h = LoadLibraryW((WCHAR*)zConverted);
+  }else{
+#if OS_WINCE
+    return 0;
+#else
+    h = LoadLibraryA((char*)zConverted);
+#endif
+  }
+  sqliteFree(zConverted);
+  return (void*)h;
+  
+}
+void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
+#if OS_WINCE
+  /* The GetProcAddressA() routine is only available on wince. */
+  return GetProcAddressA((HANDLE)pHandle, zSymbol);
+#else
+  /* All other windows platforms expect GetProcAddress() to take
+  ** an Ansi string regardless of the _UNICODE setting */
+  return GetProcAddress((HANDLE)pHandle, zSymbol);
+#endif
+}
+int sqlite3WinDlclose(void *pHandle){
+  return FreeLibrary((HANDLE)pHandle);
+}
+#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
+
 /*
 ** Get information to seed the random number generator.  The seed
 ** is written into the buffer zBuf[256].  The calling function must
index 7f4b6f952fe5a8df05cbbc7415b0db931fb94362..cb042cf3298f5b70ab25c206c8e8642b04c1468c 100644 (file)
@@ -31,6 +31,7 @@
 ** Macros for troubleshooting.  Normally turned off
 */
 #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)
@@ -231,7 +232,6 @@ struct Pager {
   u8 fullSync;                /* Do extra syncs of the journal for robustness */
   u8 full_fsync;              /* Use F_FULLFSYNC when available */
   u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
-  u8 errCode;                 /* One of several kinds of errors */
   u8 tempFile;                /* zFilename is a temporary file */
   u8 readOnly;                /* True for a read-only database */
   u8 needSync;                /* True if an fsync() is needed on the journal */
@@ -239,6 +239,7 @@ struct Pager {
   u8 alwaysRollback;          /* Disable dont_rollback() 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 */
+  int errCode;                /* One of several kinds of errors */
   int dbSize;                 /* Number of pages in the file */
   int origDbSize;             /* dbSize before the current change */
   int stmtSize;               /* Size of database (in pages) at stmt_begin() */
@@ -350,7 +351,9 @@ static const unsigned char aJournalMagic[] = {
 /*
 ** The default size of a disk sector
 */
-#define PAGER_SECTOR_SIZE 512
+#ifndef PAGER_SECTOR_SIZE
+# define PAGER_SECTOR_SIZE 512
+#endif
 
 /*
 ** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
@@ -376,8 +379,8 @@ static const unsigned char aJournalMagic[] = {
     static int cnt = 0;
     if( !pager3_refinfo_enable ) return;
     sqlite3DebugPrintf(
-       "REFCNT: %4d addr=%p nRef=%d\n",
-       p->pgno, PGHDR_TO_DATA(p), p->nRef
+       "REFCNT: %4d addr=%p nRef=%-3d total=%d\n",
+       p->pgno, PGHDR_TO_DATA(p), p->nRef, p->pPager->nRef
     );
     cnt++;   /* Something to set a breakpoint on */
   }
@@ -476,12 +479,13 @@ static u32 retrieve32bits(PgHdr *p, int offset){
 ** 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( 
-    rc==SQLITE_FULL ||
-    rc==SQLITE_IOERR ||
-    rc==SQLITE_CORRUPT ||
-    rc==SQLITE_PROTOCOL
+    rc2==SQLITE_FULL ||
+    rc2==SQLITE_IOERR ||
+    rc2==SQLITE_CORRUPT ||
+    rc2==SQLITE_PROTOCOL
   ){
     pPager->errCode = rc;
   }
@@ -846,6 +850,23 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
   return p;
 }
 
+/*
+** 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;
+  }
+  pPager->state = PAGER_UNLOCK;
+  assert( pPager->pAll==0 );
+}
+
+
 /*
 ** Unlock the database and clear the in-memory cache.  This routine
 ** sets the state of the pager back to what it was when it was first
@@ -870,11 +891,9 @@ static void pager_reset(Pager *pPager){
   if( pPager->state>=PAGER_RESERVED ){
     sqlite3pager_rollback(pPager);
   }
-  sqlite3OsUnlock(pPager->fd, NO_LOCK);
-  pPager->state = PAGER_UNLOCK;
-  pPager->dbSize = -1;
+  pager_unlock(pPager);
   pPager->nRef = 0;
-  assert( pPager->journalOpen==0 );
+  assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
 }
 
 /*
@@ -926,6 +945,7 @@ static int pager_unwritelock(Pager *pPager){
   pPager->setMaster = 0;
   pPager->needSync = 0;
   pPager->pFirstSynced = pPager->pFirst;
+  pPager->dbSize = -1;
   return rc;
 }
 
@@ -1340,6 +1360,10 @@ 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;
         }
       }
@@ -1416,6 +1440,7 @@ static int pager_stmt_playback(Pager *pPager){
   if( pPager->state>=PAGER_EXCLUSIVE ){
     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.
@@ -1793,14 +1818,19 @@ 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).
 */
-void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
+int sqlite3pager_read_fileheader(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);
-    sqlite3OsRead(pPager->fd, pDest, N);
     enable_simulated_io_errors();
+    rc = sqlite3OsRead(pPager->fd, pDest, N);
+    if( rc==SQLITE_IOERR_SHORT_READ ){
+      rc = SQLITE_OK;
+    }
   }
+  return rc;
 }
 
 /*
@@ -1814,12 +1844,13 @@ void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
 */
 int sqlite3pager_pagecount(Pager *pPager){
   i64 n;
+  int rc;
   assert( pPager!=0 );
   if( pPager->dbSize>=0 ){
     n = pPager->dbSize;
   } else {
-    if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){
-      pager_error(pPager, SQLITE_IOERR);
+    if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
+      pager_error(pPager, rc);
       return 0;
     }
     if( n>0 && n<pPager->pageSize ){
@@ -1959,9 +1990,15 @@ static void memoryTruncate(Pager *pPager){
 */
 static int pager_wait_on_lock(Pager *pPager, int locktype){
   int rc;
+
+  /* The OS lock values must be the same as the Pager lock values */
   assert( PAGER_SHARED==SHARED_LOCK );
   assert( PAGER_RESERVED==RESERVED_LOCK );
   assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
+
+  /* If the file is currently unlocked then the size must be unknown */
+  assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 || MEMDB );
+
   if( pPager->state>=locktype ){
     rc = SQLITE_OK;
   }else{
@@ -1980,6 +2017,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
 */
 int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
   int rc;
+  assert( pPager->state>=PAGER_SHARED || MEMDB );
   sqlite3pager_pagecount(pPager);
   if( pPager->errCode ){
     rc = pPager->errCode;
@@ -2026,7 +2064,6 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
 ** to the caller.
 */
 int sqlite3pager_close(Pager *pPager){
-  PgHdr *pPg, *pNext;
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to 
   ** malloc() must have already been made by this thread before it gets
@@ -2038,46 +2075,10 @@ int sqlite3pager_close(Pager *pPager){
   assert( pTsd && pTsd->nAlloc );
 #endif
 
-  switch( pPager->state ){
-    case PAGER_RESERVED:
-    case PAGER_SYNCED: 
-    case PAGER_EXCLUSIVE: {
-      /* We ignore any IO errors that occur during the rollback
-      ** operation. So disable IO error simulation so that testing
-      ** works more easily.
-      */
-      disable_simulated_io_errors();
-      sqlite3pager_rollback(pPager);
-      enable_simulated_io_errors();
-      if( !MEMDB ){
-        sqlite3OsUnlock(pPager->fd, NO_LOCK);
-      }
-      assert( pPager->errCode || pPager->journalOpen==0 );
-      break;
-    }
-    case PAGER_SHARED: {
-      if( !MEMDB ){
-        sqlite3OsUnlock(pPager->fd, NO_LOCK);
-      }
-      break;
-    }
-    default: {
-      /* Do nothing */
-      break;
-    }
-  }
-  for(pPg=pPager->pAll; pPg; pPg=pNext){
-#ifndef NDEBUG
-    if( MEMDB ){
-      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
-      assert( !pPg->alwaysRollback );
-      assert( !pHist->pOrig );
-      assert( !pHist->pStmt );
-    }
-#endif
-    pNext = pPg->pNextAll;
-    sqliteFree(pPg);
-  }
+  disable_simulated_io_errors();
+  pPager->errCode = 0;
+  pager_reset(pPager);
+  enable_simulated_io_errors();
   TRACE2("CLOSE %d\n", PAGERID(pPager));
   assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
   if( pPager->journalOpen ){
@@ -2578,7 +2579,7 @@ int sqlite3pager_release_memory(int nReq){
         ** The error will be returned to the user (or users, in the case 
         ** of a shared pager cache) of the pager for which the error occured.
         */
-        assert( rc==SQLITE_IOERR || rc==SQLITE_FULL );
+        assert( (rc&0xff)==SQLITE_IOERR || rc==SQLITE_FULL );
         assert( p->state>=PAGER_RESERVED );
         pager_error(p, rc);
       }
@@ -2659,8 +2660,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
        */
        rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
        if( rc!=SQLITE_OK ){
-         sqlite3OsUnlock(pPager->fd, NO_LOCK);
-         pPager->state = PAGER_UNLOCK;
+         pager_unlock(pPager);
          return pager_error(pPager, rc);
        }
        pPager->state = PAGER_EXCLUSIVE;
@@ -2675,8 +2675,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
        */
        rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
        if( rc!=SQLITE_OK ){
-         sqlite3OsUnlock(pPager->fd, NO_LOCK);
-         pPager->state = PAGER_UNLOCK;
+         pager_unlock(pPager);
          return SQLITE_BUSY;
        }
        pPager->journalOpen = 1;
@@ -2783,19 +2782,10 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
       }
       TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
       CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
-      if( rc!=SQLITE_OK ){
-        i64 fileSize;
-        int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
-        if( rc2!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){
-         /* An IO error occured in one of the the sqlite3OsSeek() or
-          ** sqlite3OsRead() calls above. */
-          pPg->pgno = 0;
-          sqlite3pager_unref(PGHDR_TO_DATA(pPg));
-          return rc;
-        }else{
-          clear_simulated_io_error();
-          memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
-        }
+      if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
+        pPg->pgno = 0;
+        sqlite3pager_unref(PGHDR_TO_DATA(pPg));
+        return rc;
       }else{
         TEST_INCR(pPager->nRead);
       }
@@ -2967,8 +2957,7 @@ failed_to_open_journal:
     */
     sqlite3OsDelete(pPager->zJournal);
   }else{
-    sqlite3OsUnlock(pPager->fd, NO_LOCK);
-    pPager->state = PAGER_UNLOCK;
+    pager_reset(pPager);
   }
   return rc;
 }
@@ -3227,6 +3216,7 @@ int sqlite3pager_write(void *pData){
 
   /* Update the database size and return.
   */
+  assert( pPager->state>=PAGER_SHARED );
   if( pPager->dbSize<(int)pPg->pgno ){
     pPager->dbSize = pPg->pgno;
     if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
@@ -3302,6 +3292,7 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
   assert( pPg!=0 );  /* We never call _dont_write unless the page is in mem */
   pPg->alwaysRollback = 1;
   if( pPg->dirty && !pPager->stmtInUse ){
+    assert( pPager->state>=PAGER_SHARED );
     if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
       /* If this pages is the last page in the file and the file has grown
       ** during the current transaction, then do NOT mark the page as clean.
@@ -3331,7 +3322,8 @@ void sqlite3pager_dont_rollback(void *pData){
   PgHdr *pPg = DATA_TO_PGHDR(pData);
   Pager *pPager = pPg->pPager;
 
-  if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return;
+  assert( pPager->state>=PAGER_RESERVED );
+  if( pPager->journalOpen==0 ) return;
   if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
   if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
     assert( pPager->aInJournal!=0 );
@@ -3399,14 +3391,12 @@ int sqlite3pager_commit(Pager *pPager){
     ** if there have been no changes to the database file. */
     assert( pPager->needSync==0 );
     rc = pager_unwritelock(pPager);
-    pPager->dbSize = -1;
     return rc;
   }
   assert( pPager->journalOpen );
   rc = sqlite3pager_sync(pPager, 0, 0);
   if( rc==SQLITE_OK ){
     rc = pager_unwritelock(pPager);
-    pPager->dbSize = -1;
   }
   return rc;
 }
@@ -3464,7 +3454,6 @@ int sqlite3pager_rollback(Pager *pPager){
 
   if( !pPager->dirtyCache || !pPager->journalOpen ){
     rc = pager_unwritelock(pPager);
-    pPager->dbSize = -1;
     return rc;
   }
 
@@ -3540,6 +3529,7 @@ int sqlite3pager_stmt_begin(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));
   if( MEMDB ){
index 555e52a0318e4423a47fc8a198280a9ebb94051e..7626ff6bbd73be16851113b1b9283698c036f779 100644 (file)
@@ -75,7 +75,7 @@ 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);
-void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
+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);
index 801bb7ca1a42ce6e735479d33d5c66a21a51034e..2de3fe2a96237f65d934d3bd23b05532a8b4acc9 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.
 */
@@ -93,36 +93,36 @@ struct AttachKey { int type;  Token key; };
 **                       defined, then do no error processing.
 */
 #define YYCODETYPE unsigned char
-#define YYNOCODE 248
+#define YYNOCODE 249
 #define YYACTIONTYPE unsigned short int
 #define YYWILDCARD 60
 #define sqlite3ParserTOKENTYPE Token
 typedef union {
   sqlite3ParserTOKENTYPE yy0;
-  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;
+  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;
 } YYMINORTYPE;
 #define YYSTACKDEPTH 100
 #define sqlite3ParserARG_SDECL Parse *pParse;
 #define sqlite3ParserARG_PDECL ,Parse *pParse
 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 581
-#define YYNRULE 309
+#define YYNSTATE 587
+#define YYNRULE 311
 #define YYERRORSYMBOL 139
-#define YYERRSYMDT yy495
+#define YYERRSYMDT yy497
 #define YYFALLBACK 1
 #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
 #define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
@@ -176,409 +176,411 @@ typedef union {
 **  yy_default[]       Default action for each state.
 */
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   287,   67,  291,   69,  150,  168,  206,  431,   61,   61,
- /*    10 */    61,   61,   66,   63,   63,   63,   63,   64,   64,   65,
- /*    20 */    65,   65,   66,  441,  322,  164,  444,  450,   68,   63,
- /*    30 */    63,   63,   63,   64,   64,   65,   65,   65,   66,   64,
- /*    40 */    64,   65,   65,   65,   66,   60,   58,  295,  454,  455,
- /*    50 */   451,  451,   62,   62,   61,   61,   61,   61,  513,   63,
- /*    60 */    63,   63,   63,   64,   64,   65,   65,   65,   66,  287,
- /*    70 */   318,   67,  431,   69,  150,   79,  160,  114,  224,  314,
- /*    80 */   229,  315,  172,  249,  891,  120,  580,  515,  518,    2,
- /*    90 */   250,  566,  422,   35,  223,  444,  450,  528,   20,   57,
- /*   100 */   384,  381,   63,   63,   63,   63,   64,   64,   65,   65,
- /*   110 */    65,   66,  287,  473,   60,   58,  295,  454,  455,  451,
- /*   120 */   451,   62,   62,   61,   61,   61,   61,  389,   63,   63,
- /*   130 */    63,   63,   64,   64,   65,   65,   65,   66,  444,  450,
- /*   140 */    91,  311,  385,  480,  236,  383,  269,  204,    2,   83,
- /*   150 */   581,  384,  381,  470,  196,  439,  209,   60,   58,  295,
- /*   160 */   454,  455,  451,  451,   62,   62,   61,   61,   61,   61,
- /*   170 */   170,   63,   63,   63,   63,   64,   64,   65,   65,   65,
- /*   180 */    66,  287,  486,  439,  209,  132,  109,  270,  423,  443,
- /*   190 */   402,  281,  390,  391,  441,  517,  164,  318,  507,   67,
- /*   200 */   526,   69,  150,  562,  423,  143,  516,  444,  450,  145,
- /*   210 */   146,  578,  882,  373,  882,  511,  171,  156,  514,  422,
- /*   220 */    40,  337,  426,   19,  287,  140,   60,   58,  295,  454,
- /*   230 */   455,  451,  451,   62,   62,   61,   61,   61,   61,  380,
- /*   240 */    63,   63,   63,   63,   64,   64,   65,   65,   65,   66,
- /*   250 */   444,  450,  575,  404,  405,  428,  428,  428,  329,  332,
- /*   260 */   240,  545,   67,  468,   69,  150,  271,  287,  291,   60,
- /*   270 */    58,  295,  454,  455,  451,  451,   62,   62,   61,   61,
- /*   280 */    61,   61,  124,   63,   63,   63,   63,   64,   64,   65,
- /*   290 */    65,   65,   66,  444,  450,  401,  510,  389,  290,  544,
- /*   300 */    65,   65,   65,   66,  507,  389,  542,  405,  443,  294,
- /*   310 */   434,  435,   60,   58,  295,  454,  455,  451,  451,   62,
- /*   320 */    62,   61,   61,   61,   61,  206,   63,   63,   63,   63,
- /*   330 */    64,   64,   65,   65,   65,   66,  519,  514,  366,  287,
- /*   340 */    75,  426,  148,  490,  224,  314,  229,  315,  172,  249,
- /*   350 */   367,  265,  264,    1,  574,  286,  250,  389,  416,  445,
- /*   360 */   446,  206,  390,  391,  177,  444,  450,  340,  343,  344,
- /*   370 */   390,  391,  208,  357,  428,  428,  428,  360,  168,  345,
- /*   380 */   431,  448,  449,   78,   60,   58,  295,  454,  455,  451,
- /*   390 */   451,   62,   62,   61,   61,   61,   61,  476,   63,   63,
- /*   400 */    63,   63,   64,   64,   65,   65,   65,   66,  287,  447,
- /*   410 */   177,  561,  493,  340,  343,  344,   21,  318,  518,  318,
- /*   420 */   431,  318,  390,  391,  318,  345,  475,  400,   20,  563,
- /*   430 */   564,  489,  151,  177,  444,  450,  340,  343,  344,  422,
- /*   440 */    34,  422,   34,  422,   34,  431,  422,   34,  345,  192,
- /*   450 */   237,  147,  527,   60,   58,  295,  454,  455,  451,  451,
- /*   460 */    62,   62,   61,   61,   61,   61,  423,   63,   63,   63,
- /*   470 */    63,   64,   64,   65,   65,   65,   66,  287,  230,  348,
- /*   480 */   408,  512,  298,  423,  334,  431,  318,  206,  318,  296,
- /*   490 */   318,  208,  409,  154,  465,    9,  465,  458,  464,  389,
- /*   500 */   374,  465,  173,  444,  450,  410,  173,  406,  422,   40,
- /*   510 */   422,   48,  422,   48,  321,  434,  435,  407,  324,  475,
- /*   520 */   457,  457,   60,   58,  295,  454,  455,  451,  451,   62,
- /*   530 */    62,   61,   61,   61,   61,  459,   63,   63,   63,   63,
- /*   540 */    64,   64,   65,   65,   65,   66,  287,  318,  499,  238,
- /*   550 */   253,  480,  389,  338,  408,  149,  421,  306,  289,  307,
- /*   560 */   420,  389,  289,  389,  390,  391,  409,  250,  500,  422,
- /*   570 */    27,  155,  444,  450,  431,  422,    3,  208,  539,  410,
- /*   580 */   335,  328,  578,  881,  324,  881,  457,  457,  484,  423,
- /*   590 */   242,   60,   58,  295,  454,  455,  451,  451,   62,   62,
- /*   600 */    61,   61,   61,   61,  255,   63,   63,   63,   63,   64,
- /*   610 */    64,   65,   65,   65,   66,  287,  368,  390,  391,  488,
- /*   620 */    90,  299,  324,  575,  457,  457,  390,  391,  390,  391,
- /*   630 */   318,  525,  494,  318,  392,  393,  394,  518,  524,  431,
- /*   640 */   241,  444,  450,  183,  477,  181,  571,   20,  324,  297,
- /*   650 */   457,  457,  422,   28,  541,  422,   23,  505,  287,  339,
- /*   660 */    60,   58,  295,  454,  455,  451,  451,   62,   62,   61,
- /*   670 */    61,   61,   61,  318,   63,   63,   63,   63,   64,   64,
- /*   680 */    65,   65,   65,   66,  444,  450,  421,  535,  354,  535,
- /*   690 */   420,  259,  300,  505,  816,  422,   32,   74,  505,   76,
- /*   700 */   188,  287,  505,   60,   58,  295,  454,  455,  451,  451,
- /*   710 */    62,   62,   61,   61,   61,   61,  318,   63,   63,   63,
- /*   720 */    63,   64,   64,   65,   65,   65,   66,  444,  450,  174,
- /*   730 */   175,  176,  377,  216,  423,  480,  248,  301,  422,   53,
- /*   740 */   505,  505,  259,  259,  287,  259,   60,   70,  295,  454,
- /*   750 */   455,  451,  451,   62,   62,   61,   61,   61,   61,  365,
- /*   760 */    63,   63,   63,   63,   64,   64,   65,   65,   65,   66,
- /*   770 */   444,  450,  247,  319,  244,  302,  304,  248,  167,  156,
- /*   780 */   361,  248,  379,  260,  552,  259,  554,  287,  259,  219,
- /*   790 */    58,  295,  454,  455,  451,  451,   62,   62,   61,   61,
- /*   800 */    61,   61,  318,   63,   63,   63,   63,   64,   64,   65,
- /*   810 */    65,   65,   66,  444,  450,  484,  432,  484,   22,  248,
- /*   820 */   248,  207,  388,  364,  422,   24,  555,  364,   54,  556,
- /*   830 */   309,  119,  437,  437,  295,  454,  455,  451,  451,   62,
- /*   840 */    62,   61,   61,   61,   61,  318,   63,   63,   63,   63,
- /*   850 */    64,   64,   65,   65,   65,   66,   71,  325,  318,    4,
- /*   860 */   318,  537,  318,  293,  259,  536,  259,  422,   51,  318,
- /*   870 */   161,  320,   71,  325,  318,    4,  355,  356,  305,  293,
- /*   880 */   422,   96,  422,   93,  422,   98,  225,  320,  327,  217,
- /*   890 */   115,  422,   99,  218,  190,  318,  422,  110,  226,  443,
- /*   900 */   318,  259,  318,  417,  327,  272,  427,  372,  318,    5,
- /*   910 */   418,  318,  413,  414,  330,  443,  318,  422,  111,   73,
- /*   920 */    72,  197,  422,   16,  422,   97,  152,   71,  316,  317,
- /*   930 */   422,   33,  426,  422,   94,   73,   72,  487,  422,   52,
- /*   940 */   318,  200,  274,   71,  316,  317,   71,  325,  426,    4,
- /*   950 */   318,  206,  318,  293,  318,  423,  463,  318,   12,  179,
- /*   960 */   423,  320,  422,  112,  615,  428,  428,  428,  429,  430,
- /*   970 */    11,  323,  422,  113,  422,   25,  422,   36,  327,  422,
- /*   980 */    37,  428,  428,  428,  429,  430,   11,  498,  497,  443,
- /*   990 */   158,   18,  318,  423,   81,  220,  221,  222,  101,  182,
- /*  1000 */   482,  318,  169,  318,  491,  318,   12,  318,  440,   73,
- /*  1010 */    72,  202,  466,  276,  422,   26,  474,   71,  316,  317,
- /*  1020 */   277,  318,  426,  422,   38,  422,   39,  422,   41,  422,
- /*  1030 */    42,  318,  199,  423,  544,  503,  252,  124,  124,  198,
- /*  1040 */   318,  479,  201,  422,   43,  318,  483,  452,  318,  246,
- /*  1050 */   347,  318,  124,  422,   29,  428,  428,  428,  429,  430,
- /*  1060 */    11,  495,  422,   30,  496,  576,  318,  422,   44,  501,
- /*  1070 */   422,   45,  318,  422,   46,  520,  318,  533,  534,  318,
- /*  1080 */   540,  318,  124,  502,  185,  371,  273,  264,  422,   47,
- /*  1090 */   254,  288,  256,  257,  422,   31,  206,  258,  422,   10,
- /*  1100 */   352,  422,   49,  422,   50,  577,  548,  549,  169,   88,
- /*  1110 */   559,  263,   88,  359,  362,  573,  363,  285,  266,  267,
- /*  1120 */   376,  268,  551,  560,  275,  375,  278,  279,  231,  570,
- /*  1130 */   227,  142,  398,  326,  469,  436,  438,  472,  494,  159,
- /*  1140 */   504,  547,  506,  558,  387,  395,  342,  396,  397,    8,
- /*  1150 */   312,  313,  292,  416,   81,  403,  333,  232,  411,   80,
- /*  1160 */   228,  331,  419,  415,   56,   77,  210,  412,  239,  166,
- /*  1170 */   467,  211,  470,  471,  121,   82,  102,  336,  349,  282,
- /*  1180 */   508,  424,  521,  522,  529,  523,  351,  180,  233,  509,
- /*  1190 */   234,  184,  235,  283,  531,  425,  353,   85,  186,  117,
- /*  1200 */   358,  128,  369,  370,  308,  567,  568,  243,  543,  481,
- /*  1210 */   245,  212,  485,  189,  386,  569,  572,  129,   95,  214,
- /*  1220 */   215,  399,  550,  116,  130,  205,   55,  616,  131,  617,
- /*  1230 */   162,  163,  433,  134,   59,  213,  442,  557,  137,  100,
- /*  1240 */   138,  139,  453,  456,  460,  153,  165,  461,  261,  462,
- /*  1250 */     6,  122,   13,   12,    7,  532,  478,  123,  157,  492,
- /*  1260 */   103,  341,   89,  251,  104,   84,  105,  346,  226,  178,
- /*  1270 */   350,  141,  530,  125,  303,  169,  262,  187,  106,  126,
- /*  1280 */   538,  284,  546,  127,  191,   14,  194,   92,   17,   86,
- /*  1290 */    87,  193,  195,  133,  108,  553,  135,  565,  136,   15,
- /*  1300 */   107,  203,  378,  280,  144,  382,  558,  118,  579,  558,
- /*  1310 */   558,  310,
+ /*     0 */   290,   68,  300,   70,  151,  169,  570,  420,   62,   62,
+ /*    10 */    62,   62,  205,   64,   64,   64,   64,   65,   65,   66,
+ /*    20 */    66,   66,   67,  477,  569,  568,  433,  439,   69,   64,
+ /*    30 */    64,   64,   64,   65,   65,   66,   66,   66,   67,   65,
+ /*    40 */    65,   66,   66,   66,   67,   61,   59,  296,  443,  444,
+ /*    50 */   440,  440,   63,   63,   62,   62,   62,   62,  582,   64,
+ /*    60 */    64,   64,   64,   65,   65,   66,   66,   66,   67,  290,
+ /*    70 */   570,  387,  420,  149,    2,   80,  161,  115,  240,  341,
+ /*    80 */   245,  342,  173,  249,  298,    1,  566,  207,  569,  393,
+ /*    90 */   250,  522,  899,  121,  586,  433,  439,    2,  583,   58,
+ /*   100 */   577,   21,   64,   64,   64,   64,   65,   65,   66,   66,
+ /*   110 */    66,   67,  290,  473,   61,   59,  296,  443,  444,  440,
+ /*   120 */   440,   63,   63,   62,   62,   62,   62,  393,   64,   64,
+ /*   130 */    64,   64,   65,   65,   66,   66,   66,   67,  433,  439,
+ /*   140 */    92,  178,   67,  473,  343,  346,  347,  388,  385,   56,
+ /*   150 */   379,  207,  236,  407,  394,  395,  348,   61,   59,  296,
+ /*   160 */   443,  444,  440,  440,   63,   63,   62,   62,   62,   62,
+ /*   170 */   171,   64,   64,   64,   64,   65,   65,   66,   66,   66,
+ /*   180 */    67,  290,  479,  428,  208,  522,  110,  490,  452,  432,
+ /*   190 */   406,  223,  394,  395,  532,   21,  408,  318,  517,   68,
+ /*   200 */   453,   70,  151,  567,  412,  150,  487,  433,  439,  146,
+ /*   210 */   147,  584,  890,  454,  890,  494,  172,  157,  488,  411,
+ /*   220 */    28,  337,  415,  261,  290,  495,   61,   59,  296,  443,
+ /*   230 */   444,  440,  440,   63,   63,   62,   62,   62,   62,  412,
+ /*   240 */    64,   64,   64,   64,   65,   65,   66,   66,   66,   67,
+ /*   250 */   433,  439,  581,  314,  389,  417,  417,  417,  549,  204,
+ /*   260 */    68,  460,   70,  151,  262,  261,  197,  290,  339,   61,
+ /*   270 */    59,  296,  443,  444,  440,  440,   63,   63,   62,   62,
+ /*   280 */    62,   62,  318,   64,   64,   64,   64,   65,   65,   66,
+ /*   290 */    66,   66,   67,  433,  439,  410,  548,  393,  284,  409,
+ /*   300 */   412,  430,  521,  165,  411,   41,  381,  473,  432,  295,
+ /*   310 */   423,  424,   61,   59,  296,  443,  444,  440,  440,   63,
+ /*   320 */    63,   62,   62,   62,   62,  376,   64,   64,   64,   64,
+ /*   330 */    65,   65,   66,   66,   66,   67,  477,  488,  300,  290,
+ /*   340 */    76,  415,  205,  483,  332,  234,  238,  370,  267,  266,
+ /*   350 */   489,   68,  384,   70,  151,  369,  393,  383,  205,  434,
+ /*   360 */   435,  367,  394,  395,  178,  433,  439,  343,  346,  347,
+ /*   370 */   529,  504,  572,  207,  417,  417,  417,  528,  169,  348,
+ /*   380 */   420,  437,  438,   79,   61,   59,  296,  443,  444,  440,
+ /*   390 */   440,   63,   63,   62,   62,   62,   62,  358,   64,   64,
+ /*   400 */    64,   64,   65,   65,   66,   66,   66,   67,  290,  436,
+ /*   410 */   428,  208,  486,  115,  240,  341,  245,  342,  173,  249,
+ /*   420 */   318,  394,  395,  530,  318,  393,  250,  217,  318,  509,
+ /*   430 */   405,  520,  152,  224,  433,  439,  321,  423,  424,  517,
+ /*   440 */   492,  493,  411,   35,  231,  420,  411,   35,  469,  510,
+ /*   450 */   411,   35,  477,   61,   59,  296,  443,  444,  440,  440,
+ /*   460 */    63,   63,   62,   62,   62,   62,  412,   64,   64,   64,
+ /*   470 */    64,   65,   65,   66,   66,   66,   67,  290,  522,  178,
+ /*   480 */   351,  503,  343,  346,  347,  299,  318,  404,   21,  297,
+ /*   490 */   394,  395,  318,  334,  348,  482,  318,  457,  318,  393,
+ /*   500 */   207,  457,  302,  433,  439,  457,   22,  174,  411,   36,
+ /*   510 */   420,  148,  531,  308,  411,   35,  523,  470,  411,   41,
+ /*   520 */   411,   49,   61,   59,  296,  443,  444,  440,  440,   63,
+ /*   530 */    63,   62,   62,   62,   62,  318,   64,   64,   64,   64,
+ /*   540 */    65,   65,   66,   66,   66,   67,  290,  447,  338,  452,
+ /*   550 */   253,   66,   66,   66,   67,  428,  448,  411,   49,  232,
+ /*   560 */   230,  453,   10,  292,  394,  395,  393,  309,  250,  456,
+ /*   570 */   411,    3,  433,  439,  454,  420,  328,   20,  543,  141,
+ /*   580 */   584,  889,  324,  889,  446,  446,  393,  430,  322,  165,
+ /*   590 */   393,   61,   59,  296,  443,  444,  440,  440,   63,   63,
+ /*   600 */    62,   62,   62,   62,  310,   64,   64,   64,   64,   65,
+ /*   610 */    65,   66,   66,   66,   67,  290,  371,  318,  271,  541,
+ /*   620 */    91,  581,  293,  540,  466,  318,  206,  318,  587,  388,
+ /*   630 */   385,  394,  395,   55,  324,  359,  446,  446,  329,  411,
+ /*   640 */    29,  433,  439,  324,  481,  446,  446,  411,   24,  411,
+ /*   650 */    33,  394,  395,  515,  545,  394,  395,  274,  290,  272,
+ /*   660 */    61,   59,  296,  443,  444,  440,  440,   63,   63,   62,
+ /*   670 */    62,   62,   62,  318,   64,   64,   64,   64,   65,   65,
+ /*   680 */    66,   66,   66,   67,  433,  439,  546,  493,  303,  396,
+ /*   690 */   397,  398,  580,  289,  823,  411,   54,  360,  515,  515,
+ /*   700 */   189,  290,  363,   61,   59,  296,  443,  444,  440,  440,
+ /*   710 */    63,   63,   62,   62,   62,   62,  144,   64,   64,   64,
+ /*   720 */    64,   65,   65,   66,   66,   66,   67,  433,  439,  539,
+ /*   730 */   357,  539,  248,  216,  412,  468,  168,  157,  273,  515,
+ /*   740 */   515,  515,  312,  120,  290,  198,   61,   71,  296,  443,
+ /*   750 */   444,  440,  440,   63,   63,   62,   62,   62,   62,  368,
+ /*   760 */    64,   64,   64,   64,   65,   65,   66,   66,   66,   67,
+ /*   770 */   433,  439,  426,  426,  304,  305,  307,  248,  247,  412,
+ /*   780 */   324,  364,  446,  446,  175,  176,  177,  290,  261,  261,
+ /*   790 */    59,  296,  443,  444,  440,  440,   63,   63,   62,   62,
+ /*   800 */    62,   62,  155,   64,   64,   64,   64,   65,   65,   66,
+ /*   810 */    66,   66,   67,  433,  439,  462,  156,  125,  248,  248,
+ /*   820 */   248,  420,  463,  367,  261,  255,  335,  193,  468,  556,
+ /*   830 */   558,   75,  162,   77,  296,  443,  444,  440,  440,   63,
+ /*   840 */    63,   62,   62,   62,   62,  318,   64,   64,   64,   64,
+ /*   850 */    65,   65,   66,   66,   66,   67,   72,  325,  318,    4,
+ /*   860 */   318,  412,  318,  294,  259,  559,  257,  411,   25,  318,
+ /*   870 */   219,  320,   72,  325,  318,    4,  153,  235,  180,  294,
+ /*   880 */   411,   52,  411,   97,  411,   94,  420,  320,  327,  218,
+ /*   890 */   410,  411,   99,  501,  409,  318,  411,  100,  319,  432,
+ /*   900 */   318,  261,  318,  174,  327,  392,  191,  183,  318,  116,
+ /*   910 */   412,  318,  412,  416,  261,  432,  318,  411,  111,   74,
+ /*   920 */    73,  429,  411,  112,  411,   17,  621,   72,  316,  317,
+ /*   930 */   411,   98,  415,  411,   34,   74,   73,  480,  411,   95,
+ /*   940 */   318,  412,  560,   72,  316,  317,   72,  325,  415,    4,
+ /*   950 */   318,  205,  318,  294,  318,  275,    5,  318,  261,  292,
+ /*   960 */   323,  320,  411,   53,  330,  417,  417,  417,  418,  419,
+ /*   970 */    12,  378,  411,  113,  411,  114,  411,   26,  327,  411,
+ /*   980 */    37,  417,  417,  417,  418,  419,   12,  508,  507,  432,
+ /*   990 */   159,  205,  318,  458,  261,  220,  221,  222,  102,  375,
+ /*  1000 */   421,  318,   23,  318,  377,  318,   82,  318,  506,   74,
+ /*  1010 */    73,  202,  467,  279,  411,   38,  472,   72,  316,  317,
+ /*  1020 */   280,  318,  415,  411,   27,  411,   39,  411,   40,  411,
+ /*  1030 */    42,  318,  200,  476,  548,  277,  441,  246,  505,  199,
+ /*  1040 */   318,  511,  201,  411,   43,  318,  512,  455,  318,   13,
+ /*  1050 */   475,  318,  170,  411,   44,  417,  417,  417,  418,  419,
+ /*  1060 */    12,  524,  411,   30,  498,  499,  318,  411,   31,   19,
+ /*  1070 */   411,   45,  318,  411,   46,  484,  318,   13,  241,  318,
+ /*  1080 */   513,  318,  125,  318,  254,  374,  276,  266,  411,   47,
+ /*  1090 */   242,  291,  537,  538,  411,   48,  205,  256,  411,   32,
+ /*  1100 */   258,  411,   11,  411,   50,  411,   51,  252,  350,  125,
+ /*  1110 */   125,  544,  552,  125,  170,  553,  563,   89,   89,    9,
+ /*  1120 */   380,  260,  579,  265,  288,  355,  186,  362,  402,  365,
+ /*  1130 */   366,  268,  269,  143,  225,  270,  555,  565,  278,  281,
+ /*  1140 */   282,  576,  425,  326,  427,  461,  504,  465,  551,  243,
+ /*  1150 */   514,  562,  160,  391,  399,  400,  401,    8,  315,  413,
+ /*  1160 */    82,  226,  333,  227,   81,  331,   57,  516,  228,  345,
+ /*  1170 */    78,  209,  167,  459,  233,  210,  407,  464,  122,   83,
+ /*  1180 */   336,  340,  211,  491,  496,  301,  244,  501,  103,  500,
+ /*  1190 */   497,  502,  285,  518,  229,  525,  414,  286,  519,  352,
+ /*  1200 */   526,  527,  533,  237,  181,  474,  239,  354,  478,  185,
+ /*  1210 */   182,  356,  214,  184,   86,  535,  215,  187,  118,  361,
+ /*  1220 */   547,  190,  129,  372,  373,  130,  554,  311,  131,  561,
+ /*  1230 */   132,  573,  135,   96,  133,  578,  390,  139,  574,  575,
+ /*  1240 */   263,  403,  138,  213,  101,  622,  623,  163,   60,  536,
+ /*  1250 */   164,  422,  431,  442,  449,  445,  140,  154,  166,  450,
+ /*  1260 */   451,    6,   90,   14,   13,  471,    7,  123,  158,  124,
+ /*  1270 */   485,   93,  212,   84,  344,  104,  117,  251,  105,   85,
+ /*  1280 */   106,  179,  242,  353,  142,   18,  534,  126,  306,  349,
+ /*  1290 */   170,  127,  109,  264,  188,  107,  542,  287,  550,  128,
+ /*  1300 */   192,   15,   87,   88,  194,  195,  557,  119,  196,  136,
+ /*  1310 */   137,  134,   16,  564,  571,  108,  313,  203,  145,  283,
+ /*  1320 */   382,  386,  900,  585,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     0 */    16,  218,   16,  220,  221,   21,  111,   23,   70,   71,
- /*    10 */    72,   73,   84,   75,   76,   77,   78,   79,   80,   81,
- /*    20 */    82,   83,   84,  162,  163,  164,   42,   43,   74,   75,
+ /*     0 */    16,  218,   16,  220,  221,   21,  148,   23,   70,   71,
+ /*    10 */    72,   73,  111,   75,   76,   77,   78,   79,   80,   81,
+ /*    20 */    82,   83,   84,  148,  166,  167,   42,   43,   74,   75,
  /*    30 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   79,
  /*    40 */    80,   81,   82,   83,   84,   61,   62,   63,   64,   65,
- /*    50 */    66,   67,   68,   69,   70,   71,   72,   73,  170,   75,
+ /*    50 */    66,   67,   68,   69,   70,   71,   72,   73,   20,   75,
  /*    60 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   16,
- /*    70 */   148,  218,   88,  220,  221,   22,   90,   91,   92,   93,
- /*    80 */    94,   95,   96,   97,  140,  141,  142,  170,  148,  145,
- /*    90 */   104,  238,  170,  171,  154,   42,   43,  157,  158,   46,
- /*   100 */     1,    2,   75,   76,   77,   78,   79,   80,   81,   82,
- /*   110 */    83,   84,   16,   22,   61,   62,   63,   64,   65,   66,
+ /*    70 */   148,  142,   88,   22,  145,   22,   90,   91,   92,   93,
+ /*    80 */    94,   95,   96,   97,  209,   19,  228,  229,  166,   23,
+ /*    90 */   104,  148,  140,  141,  142,   42,   43,  145,   60,   46,
+ /*   100 */   157,  158,   75,   76,   77,   78,   79,   80,   81,   82,
+ /*   110 */    83,   84,   16,  162,   61,   62,   63,   64,   65,   66,
  /*   120 */    67,   68,   69,   70,   71,   72,   73,   23,   75,   76,
  /*   130 */    77,   78,   79,   80,   81,   82,   83,   84,   42,   43,
- /*   140 */    44,  143,  144,  162,  222,  142,   14,  149,  145,   19,
- /*   150 */     0,    1,    2,   23,  156,   79,   80,   61,   62,   63,
+ /*   140 */    44,   90,   84,  162,   93,   94,   95,    1,    2,   19,
+ /*   150 */   228,  229,  201,   23,   88,   89,  105,   61,   62,   63,
  /*   160 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
  /*   170 */   156,   75,   76,   77,   78,   79,   80,   81,   82,   83,
- /*   180 */    84,   16,  201,   79,   80,   53,   21,   55,  190,   59,
- /*   190 */   169,  159,   88,   89,  162,  163,  164,  148,  177,  218,
- /*   200 */   182,  220,  221,   99,  190,  114,  161,   42,   43,   79,
- /*   210 */    80,   19,   20,  215,   22,  170,  202,  203,   88,  170,
- /*   220 */   171,  207,   92,   19,   16,   21,   61,   62,   63,   64,
- /*   230 */    65,   66,   67,   68,   69,   70,   71,   72,   73,  241,
+ /*   180 */    84,   16,  201,   79,   80,  148,   21,  161,   12,   59,
+ /*   190 */   169,  154,   88,   89,  157,  158,  170,  148,  177,  218,
+ /*   200 */    24,  220,  221,   99,  190,  156,  170,   42,   43,   79,
+ /*   210 */    80,   19,   20,   37,   22,   39,  202,  203,   88,  170,
+ /*   220 */   171,  207,   92,  148,   16,   49,   61,   62,   63,   64,
+ /*   230 */    65,   66,   67,   68,   69,   70,   71,   72,   73,  190,
  /*   240 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
- /*   250 */    42,   43,   60,  186,  187,  125,  126,  127,  187,  210,
- /*   260 */   211,   11,  218,  219,  220,  221,  134,   16,   16,   61,
+ /*   250 */    42,   43,   60,  143,  144,  125,  126,  127,   11,  149,
+ /*   260 */   218,  219,  220,  221,  189,  148,  156,   16,   81,   61,
  /*   270 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
- /*   280 */    72,   73,   22,   75,   76,   77,   78,   79,   80,   81,
- /*   290 */    82,   83,   84,   42,   43,  168,  169,   23,  151,   49,
- /*   300 */    81,   82,   83,   84,  177,   23,  186,  187,   59,  165,
+ /*   280 */    72,   73,  148,   75,   76,   77,   78,   79,   80,   81,
+ /*   290 */    82,   83,   84,   42,   43,  108,   49,   23,  159,  112,
+ /*   300 */   190,  162,  163,  164,  170,  171,  189,  162,   59,  165,
  /*   310 */   166,  167,   61,   62,   63,   64,   65,   66,   67,   68,
- /*   320 */    69,   70,   71,   72,   73,  111,   75,   76,   77,   78,
- /*   330 */    79,   80,   81,   82,   83,   84,  182,   88,  124,   16,
- /*   340 */   132,   92,   22,   20,   92,   93,   94,   95,   96,   97,
- /*   350 */   100,  101,  102,   19,  244,  245,  104,   23,   98,   42,
- /*   360 */    43,  111,   88,   89,   90,   42,   43,   93,   94,   95,
- /*   370 */    88,   89,  228,  226,  125,  126,  127,  230,   21,  105,
+ /*   320 */    69,   70,   71,   72,   73,  215,   75,   76,   77,   78,
+ /*   330 */    79,   80,   81,   82,   83,   84,  148,   88,   16,   16,
+ /*   340 */   132,   92,  111,   20,  210,  211,  201,  100,  101,  102,
+ /*   350 */   170,  218,  242,  220,  221,  124,   23,  240,  111,   42,
+ /*   360 */    43,  148,   88,   89,   90,   42,   43,   93,   94,   95,
+ /*   370 */   177,  178,  239,  229,  125,  126,  127,  184,   21,  105,
  /*   380 */    23,   64,   65,  132,   61,   62,   63,   64,   65,   66,
- /*   390 */    67,   68,   69,   70,   71,   72,   73,  115,   75,   76,
+ /*   390 */    67,   68,   69,   70,   71,   72,   73,  209,   75,   76,
  /*   400 */    77,   78,   79,   80,   81,   82,   83,   84,   16,   92,
- /*   410 */    90,  148,   20,   93,   94,   95,   19,  148,  148,  148,
- /*   420 */    23,  148,   88,   89,  148,  105,   22,  157,  158,  166,
- /*   430 */   167,   20,  156,   90,   42,   43,   93,   94,   95,  170,
- /*   440 */   171,  170,  171,  170,  171,   88,  170,  171,  105,  156,
- /*   450 */   148,  181,  182,   61,   62,   63,   64,   65,   66,   67,
+ /*   410 */    79,   80,   20,   91,   92,   93,   94,   95,   96,   97,
+ /*   420 */   148,   88,   89,  182,  148,   23,  104,  214,  148,   30,
+ /*   430 */   168,  169,  156,  191,   42,   43,  165,  166,  167,  177,
+ /*   440 */   186,  187,  170,  171,  148,   88,  170,  171,  115,   50,
+ /*   450 */   170,  171,  148,   61,   62,   63,   64,   65,   66,   67,
  /*   460 */    68,   69,   70,   71,   72,   73,  190,   75,   76,   77,
- /*   470 */    78,   79,   80,   81,   82,   83,   84,   16,  191,   16,
- /*   480 */    12,   20,  213,  190,  213,   88,  148,  111,  148,  213,
- /*   490 */   148,  228,   24,   89,  225,   19,  225,   20,  225,   23,
- /*   500 */   124,  225,   43,   42,   43,   37,   43,   39,  170,  171,
- /*   510 */   170,  171,  170,  171,  165,  166,  167,   49,  107,  115,
- /*   520 */   109,  110,   61,   62,   63,   64,   65,   66,   67,   68,
- /*   530 */    69,   70,   71,   72,   73,   20,   75,   76,   77,   78,
- /*   540 */    79,   80,   81,   82,   83,   84,   16,  148,   30,  211,
- /*   550 */    20,  162,   23,  148,   12,  156,  108,  217,   99,  217,
- /*   560 */   112,   23,   99,   23,   88,   89,   24,  104,   50,  170,
- /*   570 */   171,  148,   42,   43,   23,  170,  171,  228,   18,   37,
- /*   580 */   148,   39,   19,   20,  107,   22,  109,  110,  148,  190,
- /*   590 */   201,   61,   62,   63,   64,   65,   66,   67,   68,   69,
- /*   600 */    70,   71,   72,   73,   14,   75,   76,   77,   78,   79,
- /*   610 */    80,   81,   82,   83,   84,   16,   56,   88,   89,   81,
- /*   620 */    21,  103,  107,   60,  109,  110,   88,   89,   88,   89,
- /*   630 */   148,  177,  178,  148,    7,    8,    9,  148,  184,   88,
- /*   640 */   148,   42,   43,   53,  115,   55,  157,  158,  107,  209,
- /*   650 */   109,  110,  170,  171,   94,  170,  171,  148,   16,   81,
+ /*   470 */    78,   79,   80,   81,   82,   83,   84,   16,  148,   90,
+ /*   480 */    16,   20,   93,   94,   95,  213,  148,  157,  158,  213,
+ /*   490 */    88,   89,  148,  213,  105,   20,  148,  225,  148,   23,
+ /*   500 */   229,  225,  103,   42,   43,  225,   19,   43,  170,  171,
+ /*   510 */    23,  181,  182,  209,  170,  171,  182,  115,  170,  171,
+ /*   520 */   170,  171,   61,   62,   63,   64,   65,   66,   67,   68,
+ /*   530 */    69,   70,   71,   72,   73,  148,   75,   76,   77,   78,
+ /*   540 */    79,   80,   81,   82,   83,   84,   16,   20,  148,   12,
+ /*   550 */    20,   81,   82,   83,   84,   79,   20,  170,  171,  211,
+ /*   560 */   222,   24,   19,   99,   88,   89,   23,  217,  104,  225,
+ /*   570 */   170,  171,   42,   43,   37,   88,   39,   19,   18,   21,
+ /*   580 */    19,   20,  107,   22,  109,  110,   23,  162,  163,  164,
+ /*   590 */    23,   61,   62,   63,   64,   65,   66,   67,   68,   69,
+ /*   600 */    70,   71,   72,   73,  217,   75,   76,   77,   78,   79,
+ /*   610 */    80,   81,   82,   83,   84,   16,   56,  148,   14,   25,
+ /*   620 */    21,   60,  151,   29,   22,  148,  193,  148,    0,    1,
+ /*   630 */     2,   88,   89,  200,  107,   41,  109,  110,  187,  170,
+ /*   640 */   171,   42,   43,  107,   81,  109,  110,  170,  171,  170,
+ /*   650 */   171,   88,   89,  148,   94,   88,   89,   53,   16,   55,
  /*   660 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
  /*   670 */    71,   72,   73,  148,   75,   76,   77,   78,   79,   80,
- /*   680 */    81,   82,   83,   84,   42,   43,  108,  100,  101,  102,
- /*   690 */   112,  148,  183,  148,  134,  170,  171,  131,  148,  133,
- /*   700 */   156,   16,  148,   61,   62,   63,   64,   65,   66,   67,
- /*   710 */    68,   69,   70,   71,   72,   73,  148,   75,   76,   77,
+ /*   680 */    81,   82,   83,   84,   42,   43,  186,  187,  183,    7,
+ /*   690 */     8,    9,  245,  246,  134,  170,  171,  226,  148,  148,
+ /*   700 */   156,   16,  231,   61,   62,   63,   64,   65,   66,   67,
+ /*   710 */    68,   69,   70,   71,   72,   73,  114,   75,   76,   77,
  /*   720 */    78,   79,   80,   81,   82,   83,   84,   42,   43,  100,
- /*   730 */   101,  102,  189,  183,  190,  162,  227,  183,  170,  171,
- /*   740 */   148,  148,  148,  148,   16,  148,   61,   62,   63,   64,
+ /*   730 */   101,  102,  227,  183,  190,   22,  202,  203,  134,  148,
+ /*   740 */   148,  148,  243,  244,   16,  156,   61,   62,   63,   64,
  /*   750 */    65,   66,   67,   68,   69,   70,   71,   72,   73,  215,
  /*   760 */    75,   76,   77,   78,   79,   80,   81,   82,   83,   84,
- /*   770 */    42,   43,  227,  148,  201,  183,  183,  227,  202,  203,
- /*   780 */   236,  227,  239,  189,  189,  148,  189,   16,  148,  146,
+ /*   770 */    42,   43,  125,  126,  183,  183,  183,  227,  227,  190,
+ /*   780 */   107,  237,  109,  110,  100,  101,  102,   16,  148,  148,
  /*   790 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
- /*   800 */    72,   73,  148,   75,   76,   77,   78,   79,   80,   81,
- /*   810 */    82,   83,   84,   42,   43,  148,   20,  148,   22,  227,
- /*   820 */   227,  193,  148,  148,  170,  171,  189,  148,  200,  189,
- /*   830 */   242,  243,  125,  126,   63,   64,   65,   66,   67,   68,
+ /*   800 */    72,   73,   89,   75,   76,   77,   78,   79,   80,   81,
+ /*   810 */    82,   83,   84,   42,   43,   27,  148,   22,  227,  227,
+ /*   820 */   227,   23,   34,  148,  148,   14,  148,  156,  115,  189,
+ /*   830 */   189,  131,   19,  133,   63,   64,   65,   66,   67,   68,
  /*   840 */    69,   70,   71,   72,   73,  148,   75,   76,   77,   78,
  /*   850 */    79,   80,   81,   82,   83,   84,   16,   17,  148,   19,
- /*   860 */   148,   25,  148,   23,  148,   29,  148,  170,  171,  148,
- /*   870 */    19,   31,   16,   17,  148,   19,  209,   41,  209,   23,
- /*   880 */   170,  171,  170,  171,  170,  171,   92,   31,   48,  214,
- /*   890 */   148,  170,  171,  214,   22,  148,  170,  171,  104,   59,
- /*   900 */   148,  148,  148,   27,   48,  189,  148,  189,  148,  192,
- /*   910 */    34,  148,    7,    8,  148,   59,  148,  170,  171,   79,
- /*   920 */    80,  156,  170,  171,  170,  171,  156,   87,   88,   89,
+ /*   860 */   148,  190,  148,   23,   53,  189,   55,  170,  171,  148,
+ /*   870 */   146,   31,   16,   17,  148,   19,  156,  148,  156,   23,
+ /*   880 */   170,  171,  170,  171,  170,  171,   88,   31,   48,  214,
+ /*   890 */   108,  170,  171,   98,  112,  148,  170,  171,  148,   59,
+ /*   900 */   148,  148,  148,   43,   48,  148,   22,  156,  148,  148,
+ /*   910 */   190,  148,  190,  148,  148,   59,  148,  170,  171,   79,
+ /*   920 */    80,  162,  170,  171,  170,  171,  113,   87,   88,   89,
  /*   930 */   170,  171,   92,  170,  171,   79,   80,   81,  170,  171,
- /*   940 */   148,   19,  189,   87,   88,   89,   16,   17,   92,   19,
- /*   950 */   148,  111,  148,   23,  148,  190,   20,  148,   22,  156,
- /*   960 */   190,   31,  170,  171,  113,  125,  126,  127,  128,  129,
- /*   970 */   130,   16,  170,  171,  170,  171,  170,  171,   48,  170,
+ /*   940 */   148,  190,  189,   87,   88,   89,   16,   17,   92,   19,
+ /*   950 */   148,  111,  148,   23,  148,  189,  192,  148,  148,   99,
+ /*   960 */    16,   31,  170,  171,  148,  125,  126,  127,  128,  129,
+ /*   970 */   130,   91,  170,  171,  170,  171,  170,  171,   48,  170,
  /*   980 */   171,  125,  126,  127,  128,  129,  130,   91,   92,   59,
- /*   990 */     5,   69,  148,  190,  122,   10,   11,   12,   13,  156,
- /*  1000 */    20,  148,   22,  148,   20,  148,   22,  148,  162,   79,
- /*  1010 */    80,   26,  148,   28,  170,  171,  204,   87,   88,   89,
+ /*   990 */     5,  111,  148,  148,  148,   10,   11,   12,   13,  189,
+ /*  1000 */    20,  148,   22,  148,  124,  148,  122,  148,  179,   79,
+ /*  1010 */    80,   26,  204,   28,  170,  171,  148,   87,   88,   89,
  /*  1020 */    35,  148,   92,  170,  171,  170,  171,  170,  171,  170,
- /*  1030 */   171,  148,   47,  190,   49,   20,   20,   22,   22,   54,
- /*  1040 */   148,  148,   57,  170,  171,  148,  148,   92,  148,  148,
+ /*  1030 */   171,  148,   47,  148,   49,  189,   92,  148,  148,   54,
+ /*  1040 */   148,  179,   57,  170,  171,  148,  179,   20,  148,   22,
  /*  1050 */    20,  148,   22,  170,  171,  125,  126,  127,  128,  129,
- /*  1060 */   130,  148,  170,  171,  179,   20,  148,  170,  171,  179,
- /*  1070 */   170,  171,  148,  170,  171,  148,  148,   51,   52,  148,
- /*  1080 */    20,  148,   22,  179,  232,  100,  101,  102,  170,  171,
- /*  1090 */   148,  106,  148,  148,  170,  171,  111,  148,  170,  171,
- /*  1100 */   233,  170,  171,  170,  171,   60,   20,   20,   22,   22,
- /*  1110 */    20,  148,   22,  148,  148,   20,  148,   22,  148,  148,
- /*  1120 */   135,  148,  148,  148,  148,  148,  148,  148,  194,  148,
- /*  1130 */   173,  192,  150,  224,  173,  229,  229,  173,  178,    6,
- /*  1140 */   173,  195,  173,  195,  147,  147,  174,  147,  147,   22,
- /*  1150 */   155,   99,   40,   98,  122,  172,  119,  195,  172,  120,
- /*  1160 */   172,  117,  172,  174,  121,  131,  223,  180,   97,  113,
- /*  1170 */   153,  212,   23,  161,  153,   99,   19,  116,   15,  175,
- /*  1180 */   161,  190,  172,  172,  153,  172,  153,  152,  196,  180,
- /*  1190 */   197,  153,  198,  175,  153,  199,   38,  131,  152,   61,
- /*  1200 */   153,   19,  153,   15,  153,   33,  153,  205,  185,  206,
- /*  1210 */   205,  212,  206,  185,    1,  153,  138,  188,  160,  212,
- /*  1220 */   212,   20,  195,   32,  188,   44,   19,  113,  188,  113,
- /*  1230 */   113,  113,   20,  185,   19,  176,   20,  195,  216,  176,
- /*  1240 */   216,   19,   92,  108,   11,   19,   22,   20,  234,   20,
- /*  1250 */   118,   19,   22,   22,  118,  235,  115,   20,  113,   20,
- /*  1260 */    19,   44,  237,   20,   19,   19,   19,   44,  104,   96,
- /*  1270 */    16,   21,   17,   99,   36,   22,  134,   99,   19,   45,
- /*  1280 */    45,    5,    1,  103,  123,   19,   14,  237,  231,   69,
- /*  1290 */    69,  114,  116,  114,  240,   17,  103,   20,  123,   19,
- /*  1300 */    14,  136,   58,  137,   19,    3,  247,  243,    4,  247,
- /*  1310 */   247,  246,
+ /*  1060 */   130,  148,  170,  171,    7,    8,  148,  170,  171,   19,
+ /*  1070 */   170,  171,  148,  170,  171,   20,  148,   22,   92,  148,
+ /*  1080 */    20,  148,   22,  148,  148,  100,  101,  102,  170,  171,
+ /*  1090 */   104,  106,   51,   52,  170,  171,  111,  148,  170,  171,
+ /*  1100 */   148,  170,  171,  170,  171,  170,  171,   20,   20,   22,
+ /*  1110 */    22,   20,   20,   22,   22,   20,   20,   22,   22,   69,
+ /*  1120 */   135,  148,   20,  148,   22,  234,  233,  148,  150,  148,
+ /*  1130 */   148,  148,  148,  192,  194,  148,  148,  148,  148,  148,
+ /*  1140 */   148,  148,  230,  224,  230,  173,  178,  173,  195,  173,
+ /*  1150 */   173,  195,    6,  147,  147,  147,  147,   22,  155,  190,
+ /*  1160 */   122,  195,  119,  196,  120,  117,  121,  173,  197,  174,
+ /*  1170 */   131,  223,  113,  153,   97,  212,   23,  161,  153,   99,
+ /*  1180 */   116,   99,  212,  172,  172,   40,  172,   98,   19,  174,
+ /*  1190 */   180,  172,  175,  161,  198,  172,  199,  175,  180,   15,
+ /*  1200 */   172,  172,  153,  205,  152,  206,  205,  153,  206,  153,
+ /*  1210 */   152,   38,  212,  152,  131,  153,  212,  152,   61,  153,
+ /*  1220 */   185,  185,   19,  153,   15,  188,  195,  153,  188,  195,
+ /*  1230 */   188,   33,  185,  160,  188,  138,    1,  216,  153,  153,
+ /*  1240 */   235,   20,  216,  176,  176,  113,  113,  113,   19,  236,
+ /*  1250 */   113,   20,   20,   92,   11,  108,   19,   19,   22,   20,
+ /*  1260 */    20,  118,  238,   22,   22,  115,  118,   19,  113,   20,
+ /*  1270 */    20,  238,   44,   19,   44,   19,   32,   20,   19,   19,
+ /*  1280 */    19,   96,  104,   16,   21,  232,   17,   99,   36,   44,
+ /*  1290 */    22,   45,  241,  134,   99,   19,   45,    5,    1,  103,
+ /*  1300 */   123,   19,   69,   69,  114,   14,   17,  244,  116,  103,
+ /*  1310 */   123,  114,   19,  124,   20,   14,  247,  136,   19,  137,
+ /*  1320 */    58,    3,  248,    4,
 };
-#define YY_SHIFT_USE_DFLT (-106)
-#define YY_SHIFT_MAX 382
+#define YY_SHIFT_USE_DFLT (-100)
+#define YY_SHIFT_MAX 386
 static const short yy_shift_ofst[] = {
- /*     0 */    99,  840,  985,  -16,  840,  930,  930,  930,  274, -105,
- /*    10 */    96,  930,  930,  930,  930,  930,  -46,  250,  104,  540,
- /*    20 */   551,   76,   76,   53,  165,  208,  251,  323,  392,  461,
- /*    30 */   530,  599,  642,  685,  642,  642,  642,  642,  642,  642,
+ /*     0 */   146,  840,  985,  -16,  840,  930,  930,  930,  274,  104,
+ /*    10 */   -99,   96,  930,  930,  930,  930,  930,  -46,  247,  476,
+ /*    20 */   567,  798,  331,  331,   53,  165,  208,  251,  323,  392,
+ /*    30 */   461,  530,  599,  642,  685,  642,  642,  642,  642,  642,
  /*    40 */   642,  642,  642,  642,  642,  642,  642,  642,  642,  642,
- /*    50 */   642,  728,  771,  771,  856,  930,  930,  930,  930,  930,
+ /*    50 */   642,  642,  728,  771,  771,  856,  930,  930,  930,  930,
  /*    60 */   930,  930,  930,  930,  930,  930,  930,  930,  930,  930,
  /*    70 */   930,  930,  930,  930,  930,  930,  930,  930,  930,  930,
  /*    80 */   930,  930,  930,  930,  930,  930,  930,  930,  930,  930,
- /*    90 */   930,  930,  930,  -62,  -62,  -14,   27,   27,  -40,  219,
- /*   100 */   463,  560,  540,  540,  540,  540,  540,  540,  540,  551,
- /*   110 */   -72, -106, -106, -106,  130,  252,  468,  468,  192,  563,
- /*   120 */   150,  357,  540,  357,  540,  540,  540,  540,  540,  540,
- /*   130 */   540,  540,  540,  540,  540,  540,  540,  214,  376, -105,
- /*   140 */  -105, -105, -106, -106, -106,  249,  249,  320,  343,  411,
- /*   150 */   334,  477,  515,  542,  282,  529,  476,  538,  627,  540,
- /*   160 */   540,  578,  540,  540,  397,  540,  540,  404,  540,  540,
- /*   170 */   541,  404,  540,  540,  518,  518,  518,  540,  540,  541,
- /*   180 */   540,  540,  541,  540,  836,  587,  540,  540,  541,  540,
- /*   190 */   540,  540,  541,  540,  540,  540,  541,  541,  540,  540,
- /*   200 */   540,  540,  540,  540,  204,  876,  448,   91,  707,  707,
- /*   210 */   566,  876,  876,  459,  876,  876,  260,  872,  872, 1133,
- /*   220 */  1133, 1133, 1133, 1127, 1052, 1052, 1112, 1052, 1055, 1052,
- /*   230 */  -105, 1032, 1037, 1039, 1044, 1043, 1034, 1056, 1071, 1149,
- /*   240 */  1071, 1056, 1076, 1061, 1076, 1061, 1157, 1071, 1071, 1149,
- /*   250 */  1112, 1052, 1052, 1052, 1157, 1163, 1056, 1056, 1056, 1056,
- /*   260 */  1158, 1066, 1163, 1056, 1138, 1138, 1182, 1032, 1056, 1188,
- /*   270 */  1188, 1188, 1032, 1138, 1182, 1056, 1172, 1172, 1056, 1056,
- /*   280 */  1078, -106, -106, -106, -106, -106, -106,  317,  132,  629,
- /*   290 */   590,  794,  905,  851,  796,  955,  936,  980,  984,  896,
- /*   300 */  1015, 1016, 1030, 1026, 1060, 1086, 1087, 1090,  922, 1095,
- /*   310 */  1045, 1213, 1201, 1191, 1181, 1207, 1114, 1116, 1117, 1118,
- /*   320 */  1215, 1212, 1216, 1150, 1135, 1222, 1233, 1226, 1227, 1224,
- /*   330 */  1229, 1132, 1230, 1136, 1231, 1141, 1232, 1237, 1145, 1239,
- /*   340 */  1217, 1241, 1243, 1245, 1246, 1223, 1247, 1173, 1164, 1254,
- /*   350 */  1255, 1250, 1174, 1238, 1234, 1253, 1235, 1142, 1178, 1259,
- /*   360 */  1276, 1281, 1180, 1220, 1221, 1161, 1266, 1177, 1272, 1176,
- /*   370 */  1278, 1179, 1193, 1175, 1280, 1277, 1286, 1244, 1165, 1166,
- /*   380 */  1285, 1302, 1304,
+ /*    90 */   930,  930,  930,  930,  -62,  -62,  -14,   27,   27,  -40,
+ /*   100 */   470,  464,  560,  567,  567,  567,  567,  567,  567,  567,
+ /*   110 */   798,   58, -100, -100, -100,  130,  322,  176,  176,  192,
+ /*   120 */   561,  628,  357,  567,  357,  567,  567,  567,  567,  567,
+ /*   130 */   567,  567,  567,  567,  567,  567,  567,  567,  880,  231,
+ /*   140 */   -99,  -99,  -99, -100, -100, -100,  249,  249,   51,  389,
+ /*   150 */   475,   66,  527,  536,  537,  333,  402,  543,  563,  682,
+ /*   160 */   567,  567,  187,  567,  567,  487,  567,  567,  713,  567,
+ /*   170 */   567,  673,  713,  567,  567,  399,  399,  399,  567,  567,
+ /*   180 */   673,  567,  567,  673,  567,  594,  629,  567,  567,  673,
+ /*   190 */   567,  567,  567,  673,  567,  567,  567,  673,  673,  567,
+ /*   200 */   567,  567,  567,  567,  558,  782,  602,  647,  647,  700,
+ /*   210 */   788,  788,  788,  860,  788,  788,  795,  884,  884, 1146,
+ /*   220 */  1146, 1146, 1146, 1135,  -99, 1038, 1043, 1044, 1048, 1045,
+ /*   230 */  1039, 1059, 1077, 1153, 1077, 1059, 1080, 1064, 1080, 1064,
+ /*   240 */  1082, 1082, 1145, 1082, 1089, 1082, 1169, 1077, 1077, 1153,
+ /*   250 */  1145, 1082, 1082, 1082, 1169, 1184, 1059, 1184, 1059, 1184,
+ /*   260 */  1059, 1059, 1173, 1083, 1184, 1059, 1157, 1157, 1203, 1038,
+ /*   270 */  1059, 1209, 1209, 1209, 1209, 1038, 1157, 1203, 1059, 1198,
+ /*   280 */  1198, 1059, 1059, 1097, -100, -100, -100, -100, -100, -100,
+ /*   290 */   317,  604,  684,  811,  813,  980,  944, 1027, 1030, 1055,
+ /*   300 */   986, 1057,  896, 1060, 1087, 1088, 1041, 1091, 1092, 1095,
+ /*   310 */  1096, 1050, 1102,   38, 1235, 1221, 1132, 1133, 1134, 1137,
+ /*   320 */  1229, 1231, 1232, 1161, 1147, 1237, 1243, 1238, 1239, 1236,
+ /*   330 */  1240, 1143, 1241, 1148, 1242, 1150, 1248, 1249, 1155, 1250,
+ /*   340 */  1244, 1228, 1254, 1230, 1256, 1257, 1259, 1260, 1245, 1261,
+ /*   350 */  1185, 1178, 1267, 1269, 1263, 1188, 1252, 1246, 1268, 1251,
+ /*   360 */  1159, 1195, 1276, 1292, 1297, 1196, 1233, 1234, 1177, 1282,
+ /*   370 */  1190, 1291, 1192, 1289, 1197, 1206, 1187, 1293, 1189, 1294,
+ /*   380 */  1301, 1262, 1181, 1182, 1299, 1318, 1319,
 };
 #define YY_REDUCE_USE_DFLT (-218)
-#define YY_REDUCE_MAX 286
+#define YY_REDUCE_MAX 289
 static const short yy_reduce_ofst[] = {
- /*     0 */   -56,  276,   -2,  -19,  399,  269,   49,  271,  270,   14,
- /*    10 */  -147,  -78,  273,  338,  340,  342,   44,  544,  263,  -60,
- /*    20 */    32,  144,  349, -217, -217, -217, -217, -217, -217, -217,
+ /*     0 */   -48,  276,  110,  -19,   49,  272,  134,  280,  330, -142,
+ /*    10 */    14,  133,  338,  344,  348,  350,  387,   42,  544,  -78,
+ /*    20 */    37,  139,  144,  271, -217, -217, -217, -217, -217, -217,
  /*    30 */  -217, -217, -217, -217, -217, -217, -217, -217, -217, -217,
  /*    40 */  -217, -217, -217, -217, -217, -217, -217, -217, -217, -217,
- /*    50 */  -217, -217, -217, -217,  405,  482,  485,  525,  568,  654,
+ /*    50 */  -217, -217, -217, -217, -217,  400,  469,  477,  479,  525,
  /*    60 */   697,  710,  712,  714,  721,  726,  747,  752,  754,  760,
  /*    70 */   763,  768,  792,  802,  804,  806,  809,  844,  853,  855,
  /*    80 */   857,  859,  873,  883,  892,  897,  900,  903,  918,  924,
- /*    90 */   928,  931,  933, -217, -217,  127, -217, -217, -217, -217,
- /*   100 */   454,  147,  509,  550,  554,  592,  593,  543,  489, -139,
- /*   110 */  -217, -217, -217, -217,   45,   21,   67,  120,  110,  110,
- /*   120 */     3,  389,  440,  573,  545,  594,  667,  675,  669,  595,
- /*   130 */   597,  637,  640,  716,  718,  679,  753,  293,  765,  770,
- /*   140 */   803,  843,  628,  576,  588, -112,  -83,   18,  154,  287,
- /*   150 */   302,  287,  287,   71,  423,  432,  492,  625,  643,  674,
- /*   160 */   742,  717,  625,  758,  846,  766,  864,  812,  893,  898,
- /*   170 */   287,  812,  901,  913,  885,  890,  904,  927,  942,  287,
- /*   180 */   944,  945,  287,  949,  852,  867,  963,  965,  287,  966,
- /*   190 */   968,  970,  287,  971,  973,  974,  287,  287,  975,  976,
- /*   200 */   977,  978,  979,  981,  982,  957,  939,  934,  906,  907,
- /*   210 */   909,  961,  964,  960,  967,  969,  972,  946,  948,  997,
- /*   220 */   998, 1000, 1001,  995,  983,  986,  987,  988,  989,  990,
- /*   230 */   991,  962,  992,  993,  994,  996,  943, 1017,  959, 1012,
- /*   240 */   999, 1021, 1002, 1003, 1005, 1006, 1004, 1007, 1008, 1019,
- /*   250 */  1009, 1010, 1011, 1013, 1018, 1035, 1031, 1033, 1038, 1041,
- /*   260 */  1014, 1020, 1046, 1047, 1023, 1028, 1022, 1027, 1049, 1029,
- /*   270 */  1036, 1040, 1042, 1048, 1024, 1051, 1025, 1050, 1053, 1062,
- /*   280 */  1054, 1058, 1059, 1063, 1057, 1064, 1065,
+ /*    90 */   928,  931,  933,  935, -217, -217,  262, -217, -217, -217,
+ /*   100 */  -217,  193,  471,  505,  550,  591,  592,  593,  117,  -57,
+ /*   110 */   425, -217, -217, -217, -217,   26,   21,  254,  500,  447,
+ /*   120 */   447,  -71,  -49, -125,  145,  551,   75,  188,  213,  304,
+ /*   130 */   640,  641,  676,  753,  766,  810,  675,  846,  589,  671,
+ /*   140 */   720,  722,  751,  433,  534,  499,   36,  180,  241,  334,
+ /*   150 */   242,  296,  242,  242,  451,  668,  678,  729,  750,  724,
+ /*   160 */   757,  761,  764,  750,  765,  759,  816,  845,  808,  868,
+ /*   170 */   885,  242,  808,  889,  890,  829,  862,  867,  913,  936,
+ /*   180 */   242,  949,  952,  242,  973,  893,  891,  975,  979,  242,
+ /*   190 */   981,  982,  983,  242,  984,  987,  988,  242,  242,  989,
+ /*   200 */   990,  991,  992,  993,  978,  941,  940,  912,  914,  919,
+ /*   210 */   972,  974,  976,  968,  977,  994,  995,  953,  956, 1006,
+ /*   220 */  1007, 1008, 1009, 1003,  969,  966,  967,  971,  996,  997,
+ /*   230 */   948, 1020,  963, 1016,  970, 1025,  998,  999, 1001, 1002,
+ /*   240 */  1011, 1012, 1010, 1014, 1015, 1019, 1017, 1000, 1004, 1032,
+ /*   250 */  1018, 1023, 1028, 1029, 1022, 1052, 1049, 1058, 1054, 1061,
+ /*   260 */  1056, 1062, 1005, 1013, 1065, 1066, 1035, 1036, 1021, 1031,
+ /*   270 */  1070, 1037, 1040, 1042, 1046, 1034, 1047, 1026, 1074, 1024,
+ /*   280 */  1033, 1085, 1086, 1051, 1073, 1067, 1068, 1053, 1063, 1069,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   587,  813,  890,  702,  890,  813,  890,  813,  890,  706,
- /*    10 */   864,  809,  813,  890,  890,  890,  784,  890,  835,  890,
- /*    20 */   618,  835,  835,  737,  890,  890,  890,  890,  890,  890,
- /*    30 */   890,  890,  738,  890,  812,  808,  804,  806,  805,  739,
- /*    40 */   726,  735,  742,  718,  849,  744,  745,  750,  751,  865,
- /*    50 */   868,  772,  790,  771,  890,  890,  890,  890,  890,  890,
- /*    60 */   890,  890,  890,  890,  890,  890,  890,  890,  890,  890,
- /*    70 */   890,  890,  890,  890,  890,  890,  890,  890,  890,  890,
- /*    80 */   890,  890,  890,  890,  890,  890,  890,  890,  890,  890,
- /*    90 */   890,  890,  890,  774,  795,  611,  773,  783,  775,  776,
- /*   100 */   671,  606,  890,  890,  890,  890,  890,  890,  890,  890,
- /*   110 */   777,  778,  791,  792,  890,  890,  890,  890,  890,  890,
- /*   120 */   587,  702,  890,  702,  890,  890,  890,  890,  890,  890,
- /*   130 */   890,  890,  890,  890,  890,  890,  890,  890,  890,  890,
- /*   140 */   890,  890,  696,  706,  883,  890,  890,  662,  890,  890,
- /*   150 */   890,  890,  890,  890,  890,  890,  890,  890,  594,  592,
- /*   160 */   890,  694,  890,  890,  620,  890,  890,  704,  890,  890,
- /*   170 */   709,  710,  890,  890,  890,  890,  890,  890,  890,  608,
- /*   180 */   890,  890,  683,  890,  841,  890,  890,  890,  856,  890,
- /*   190 */   890,  890,  854,  890,  890,  890,  685,  747,  823,  890,
- /*   200 */   890,  869,  871,  890,  890,  729,  694,  703,  890,  890,
- /*   210 */   807,  729,  729,  641,  729,  729,  644,  741,  741,  591,
- /*   220 */   591,  591,  591,  661,  673,  673,  658,  673,  644,  673,
- /*   230 */   890,  741,  732,  734,  722,  736,  890,  711,  730,  890,
- /*   240 */   730,  711,  719,  721,  719,  721,  817,  730,  730,  890,
- /*   250 */   658,  673,  673,  673,  817,  603,  711,  711,  711,  711,
- /*   260 */   845,  848,  603,  711,  675,  675,  752,  741,  711,  682,
- /*   270 */   682,  682,  741,  675,  752,  711,  867,  867,  711,  711,
- /*   280 */   876,  628,  646,  646,  851,  883,  888,  890,  890,  890,
- /*   290 */   890,  890,  890,  759,  890,  890,  890,  890,  890,  890,
- /*   300 */   890,  890,  890,  890,  890,  890,  890,  890,  830,  890,
- /*   310 */   890,  890,  890,  890,  890,  890,  764,  760,  890,  761,
- /*   320 */   890,  890,  890,  890,  688,  890,  890,  890,  890,  890,
- /*   330 */   890,  890,  723,  890,  733,  890,  890,  890,  890,  890,
- /*   340 */   890,  890,  890,  890,  890,  890,  890,  890,  890,  890,
- /*   350 */   890,  890,  890,  890,  843,  844,  890,  890,  890,  890,
- /*   360 */   890,  890,  890,  890,  890,  890,  890,  890,  890,  890,
- /*   370 */   890,  890,  890,  890,  890,  890,  890,  875,  890,  890,
- /*   380 */   878,  588,  890,  582,  585,  584,  586,  590,  593,  615,
- /*   390 */   616,  617,  595,  596,  597,  598,  599,  600,  601,  607,
- /*   400 */   609,  627,  629,  636,  674,  677,  678,  679,  859,  860,
- /*   410 */   861,  637,  656,  659,  660,  638,  645,  727,  728,  639,
- /*   420 */   692,  693,  756,  686,  687,  691,  758,  762,  763,  765,
- /*   430 */   766,  614,  621,  622,  625,  626,  831,  833,  832,  834,
- /*   440 */   624,  623,  767,  770,  779,  780,  782,  788,  794,  797,
- /*   450 */   781,  786,  787,  789,  793,  796,  689,  690,  800,  802,
- /*   460 */   803,  857,  858,  798,  810,  811,  712,  801,  785,  724,
- /*   470 */   613,  731,  725,  695,  705,  714,  715,  716,  717,  700,
- /*   480 */   701,  707,  720,  754,  755,  708,  697,  698,  699,  799,
- /*   490 */   757,  768,  769,  640,  647,  648,  649,  652,  653,  654,
- /*   500 */   655,  650,  651,  818,  819,  821,  820,  642,  643,  657,
- /*   510 */   630,  631,  632,  633,  764,  634,  635,  619,  612,  663,
- /*   520 */   666,  667,  668,  669,  670,  672,  664,  665,  610,  602,
- /*   530 */   604,  713,  837,  846,  847,  842,  838,  839,  840,  605,
- /*   540 */   814,  815,  676,  748,  749,  836,  850,  852,  753,  853,
- /*   550 */   855,  880,  680,  681,  684,  822,  862,  740,  743,  746,
- /*   560 */   824,  825,  826,  827,  828,  829,  863,  866,  870,  872,
- /*   570 */   873,  874,  877,  879,  884,  885,  886,  889,  887,  589,
- /*   580 */   583,
+ /*     0 */   593,  820,  898,  708,  898,  820,  898,  820,  898,  843,
+ /*    10 */   712,  872,  816,  820,  898,  898,  898,  791,  898,  843,
+ /*    20 */   898,  624,  843,  843,  743,  898,  898,  898,  898,  898,
+ /*    30 */   898,  898,  898,  744,  898,  819,  815,  811,  813,  812,
+ /*    40 */   745,  732,  741,  748,  724,  857,  750,  751,  757,  758,
+ /*    50 */   873,  876,  779,  797,  778,  898,  898,  898,  898,  898,
+ /*    60 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*    70 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*    80 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*    90 */   898,  898,  898,  898,  781,  802,  617,  780,  790,  782,
+ /*   100 */   783,  677,  612,  898,  898,  898,  898,  898,  898,  898,
+ /*   110 */   898,  784,  785,  798,  799,  898,  898,  898,  898,  898,
+ /*   120 */   898,  593,  708,  898,  708,  898,  898,  898,  898,  898,
+ /*   130 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*   140 */   898,  898,  898,  702,  712,  891,  898,  898,  668,  898,
+ /*   150 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  600,
+ /*   160 */   598,  898,  700,  898,  898,  626,  898,  898,  710,  898,
+ /*   170 */   898,  715,  716,  898,  898,  898,  898,  898,  898,  898,
+ /*   180 */   614,  898,  898,  689,  898,  849,  898,  898,  898,  864,
+ /*   190 */   898,  898,  898,  862,  898,  898,  898,  691,  753,  830,
+ /*   200 */   898,  877,  879,  898,  898,  700,  709,  898,  898,  814,
+ /*   210 */   735,  735,  735,  647,  735,  735,  650,  747,  747,  597,
+ /*   220 */   597,  597,  597,  667,  898,  747,  738,  740,  728,  742,
+ /*   230 */   898,  717,  736,  898,  736,  717,  725,  727,  725,  727,
+ /*   240 */   679,  679,  664,  679,  650,  679,  824,  736,  736,  898,
+ /*   250 */   664,  679,  679,  679,  824,  609,  717,  609,  717,  609,
+ /*   260 */   717,  717,  853,  856,  609,  717,  681,  681,  759,  747,
+ /*   270 */   717,  688,  688,  688,  688,  747,  681,  759,  717,  875,
+ /*   280 */   875,  717,  717,  884,  634,  652,  652,  859,  891,  896,
+ /*   290 */   898,  898,  898,  898,  766,  898,  898,  898,  898,  898,
+ /*   300 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*   310 */   898,  836,  898,  898,  898,  898,  771,  767,  898,  768,
+ /*   320 */   898,  898,  898,  898,  694,  898,  898,  898,  898,  898,
+ /*   330 */   898,  898,  729,  898,  739,  898,  898,  898,  898,  898,
+ /*   340 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*   350 */   898,  898,  898,  898,  898,  898,  898,  851,  852,  898,
+ /*   360 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*   370 */   898,  898,  898,  898,  898,  898,  898,  898,  898,  898,
+ /*   380 */   898,  883,  898,  898,  886,  594,  898,  588,  591,  590,
+ /*   390 */   592,  596,  599,  621,  622,  623,  601,  602,  603,  604,
+ /*   400 */   605,  606,  607,  613,  615,  633,  635,  619,  637,  698,
+ /*   410 */   699,  763,  692,  693,  697,  765,  769,  770,  772,  773,
+ /*   420 */   620,  627,  628,  631,  632,  839,  841,  840,  842,  630,
+ /*   430 */   629,  774,  777,  786,  787,  789,  795,  801,  804,  788,
+ /*   440 */   793,  794,  796,  800,  803,  695,  696,  807,  809,  810,
+ /*   450 */   865,  866,  867,  868,  869,  805,  817,  818,  718,  808,
+ /*   460 */   792,  730,  733,  734,  737,  731,  701,  711,  720,  721,
+ /*   470 */   722,  723,  706,  707,  713,  726,  761,  762,  714,  703,
+ /*   480 */   704,  705,  806,  764,  775,  776,  638,  639,  771,  640,
+ /*   490 */   641,  642,  680,  683,  684,  685,  643,  662,  665,  666,
+ /*   500 */   644,  651,  645,  646,  653,  654,  655,  658,  659,  660,
+ /*   510 */   661,  656,  657,  825,  826,  828,  827,  648,  649,  663,
+ /*   520 */   636,  625,  618,  669,  672,  673,  674,  675,  676,  678,
+ /*   530 */   670,  671,  616,  608,  610,  719,  845,  854,  855,  850,
+ /*   540 */   846,  847,  848,  611,  821,  822,  682,  755,  756,  844,
+ /*   550 */   858,  860,  760,  861,  863,  888,  686,  687,  690,  829,
+ /*   560 */   870,  746,  749,  752,  754,  831,  832,  833,  834,  837,
+ /*   570 */   838,  835,  871,  874,  878,  880,  881,  882,  885,  887,
+ /*   580 */   892,  893,  894,  897,  895,  595,  589,
 };
 #define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
 
@@ -860,11 +862,11 @@ static const char *const yyTokenName[] = {
   "inscollist_opt",  "itemlist",      "likeop",        "escape",      
   "between_op",    "in_op",         "case_operand",  "case_exprlist",
   "case_else",     "expritem",      "uniqueflag",    "idxitem",     
-  "plus_opt",      "number",        "trigger_decl",  "trigger_cmd_list",
-  "trigger_time",  "trigger_event",  "foreach_clause",  "when_clause", 
-  "trigger_cmd",   "database_kw_opt",  "key_opt",       "add_column_fullname",
-  "kwcolumn_opt",  "create_vtab",   "vtabarglist",   "vtabarg",     
-  "vtabargtoken",  "lp",            "anylist",     
+  "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 */
 
@@ -922,11 +924,11 @@ static const char *const yyRuleName[] = {
  /*  47 */ "carglist ::=",
  /*  48 */ "carg ::= CONSTRAINT nm ccons",
  /*  49 */ "carg ::= ccons",
- /*  50 */ "carg ::= DEFAULT term",
- /*  51 */ "carg ::= DEFAULT LP expr RP",
- /*  52 */ "carg ::= DEFAULT PLUS term",
- /*  53 */ "carg ::= DEFAULT MINUS term",
- /*  54 */ "carg ::= DEFAULT id",
+ /*  50 */ "ccons ::= DEFAULT term",
+ /*  51 */ "ccons ::= DEFAULT LP expr RP",
+ /*  52 */ "ccons ::= DEFAULT PLUS term",
+ /*  53 */ "ccons ::= DEFAULT MINUS term",
+ /*  54 */ "ccons ::= DEFAULT id",
  /*  55 */ "ccons ::= NULL onconf",
  /*  56 */ "ccons ::= NOT NULL onconf",
  /*  57 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
@@ -974,7 +976,7 @@ static const char *const yyRuleName[] = {
  /*  99 */ "cmd ::= DROP TABLE ifexists fullname",
  /* 100 */ "ifexists ::= IF EXISTS",
  /* 101 */ "ifexists ::=",
- /* 102 */ "cmd ::= CREATE temp VIEW nm dbnm AS select",
+ /* 102 */ "cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select",
  /* 103 */ "cmd ::= DROP VIEW ifexists fullname",
  /* 104 */ "cmd ::= select",
  /* 105 */ "select ::= oneselect",
@@ -1039,148 +1041,150 @@ static const char *const yyRuleName[] = {
  /* 164 */ "setlist ::= nm EQ expr",
  /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
  /* 166 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 167 */ "insert_cmd ::= INSERT orconf",
- /* 168 */ "insert_cmd ::= REPLACE",
- /* 169 */ "itemlist ::= itemlist COMMA expr",
- /* 170 */ "itemlist ::= expr",
- /* 171 */ "inscollist_opt ::=",
- /* 172 */ "inscollist_opt ::= LP inscollist RP",
- /* 173 */ "inscollist ::= inscollist COMMA nm",
- /* 174 */ "inscollist ::= nm",
- /* 175 */ "expr ::= term",
- /* 176 */ "expr ::= LP expr RP",
- /* 177 */ "term ::= NULL",
- /* 178 */ "expr ::= ID",
- /* 179 */ "expr ::= JOIN_KW",
- /* 180 */ "expr ::= nm DOT nm",
- /* 181 */ "expr ::= nm DOT nm DOT nm",
- /* 182 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 183 */ "term ::= STRING",
- /* 184 */ "expr ::= REGISTER",
- /* 185 */ "expr ::= VARIABLE",
- /* 186 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 187 */ "expr ::= ID LP distinct exprlist RP",
- /* 188 */ "expr ::= ID LP STAR RP",
- /* 189 */ "term ::= CTIME_KW",
- /* 190 */ "expr ::= expr AND expr",
- /* 191 */ "expr ::= expr OR expr",
- /* 192 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 193 */ "expr ::= expr EQ|NE expr",
- /* 194 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 195 */ "expr ::= expr PLUS|MINUS expr",
- /* 196 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 197 */ "expr ::= expr CONCAT expr",
- /* 198 */ "likeop ::= LIKE_KW",
- /* 199 */ "likeop ::= NOT LIKE_KW",
- /* 200 */ "likeop ::= MATCH",
- /* 201 */ "likeop ::= NOT MATCH",
- /* 202 */ "escape ::= ESCAPE expr",
- /* 203 */ "escape ::=",
- /* 204 */ "expr ::= expr likeop expr escape",
- /* 205 */ "expr ::= expr ISNULL|NOTNULL",
- /* 206 */ "expr ::= expr IS NULL",
- /* 207 */ "expr ::= expr NOT NULL",
- /* 208 */ "expr ::= expr IS NOT NULL",
- /* 209 */ "expr ::= NOT|BITNOT expr",
- /* 210 */ "expr ::= MINUS expr",
- /* 211 */ "expr ::= PLUS expr",
- /* 212 */ "between_op ::= BETWEEN",
- /* 213 */ "between_op ::= NOT BETWEEN",
- /* 214 */ "expr ::= expr between_op expr AND expr",
- /* 215 */ "in_op ::= IN",
- /* 216 */ "in_op ::= NOT IN",
- /* 217 */ "expr ::= expr in_op LP exprlist RP",
- /* 218 */ "expr ::= LP select RP",
- /* 219 */ "expr ::= expr in_op LP select RP",
- /* 220 */ "expr ::= expr in_op nm dbnm",
- /* 221 */ "expr ::= EXISTS LP select RP",
- /* 222 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 223 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 224 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 225 */ "case_else ::= ELSE expr",
- /* 226 */ "case_else ::=",
- /* 227 */ "case_operand ::= expr",
- /* 228 */ "case_operand ::=",
- /* 229 */ "exprlist ::= exprlist COMMA expritem",
- /* 230 */ "exprlist ::= expritem",
- /* 231 */ "expritem ::= expr",
- /* 232 */ "expritem ::=",
- /* 233 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
- /* 234 */ "uniqueflag ::= UNIQUE",
- /* 235 */ "uniqueflag ::=",
- /* 236 */ "idxlist_opt ::=",
- /* 237 */ "idxlist_opt ::= LP idxlist RP",
- /* 238 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
- /* 239 */ "idxlist ::= idxitem collate sortorder",
- /* 240 */ "idxitem ::= nm",
- /* 241 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 242 */ "cmd ::= VACUUM",
- /* 243 */ "cmd ::= VACUUM nm",
- /* 244 */ "cmd ::= PRAGMA nm dbnm EQ nm",
- /* 245 */ "cmd ::= PRAGMA nm dbnm EQ ON",
- /* 246 */ "cmd ::= PRAGMA nm dbnm EQ plus_num",
+ /* 167 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+ /* 168 */ "insert_cmd ::= INSERT orconf",
+ /* 169 */ "insert_cmd ::= REPLACE",
+ /* 170 */ "itemlist ::= itemlist COMMA expr",
+ /* 171 */ "itemlist ::= expr",
+ /* 172 */ "inscollist_opt ::=",
+ /* 173 */ "inscollist_opt ::= LP inscollist RP",
+ /* 174 */ "inscollist ::= inscollist COMMA nm",
+ /* 175 */ "inscollist ::= nm",
+ /* 176 */ "expr ::= term",
+ /* 177 */ "expr ::= LP expr RP",
+ /* 178 */ "term ::= NULL",
+ /* 179 */ "expr ::= ID",
+ /* 180 */ "expr ::= JOIN_KW",
+ /* 181 */ "expr ::= nm DOT nm",
+ /* 182 */ "expr ::= nm DOT nm DOT nm",
+ /* 183 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 184 */ "term ::= STRING",
+ /* 185 */ "expr ::= REGISTER",
+ /* 186 */ "expr ::= VARIABLE",
+ /* 187 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 188 */ "expr ::= ID LP distinct exprlist RP",
+ /* 189 */ "expr ::= ID LP STAR RP",
+ /* 190 */ "term ::= CTIME_KW",
+ /* 191 */ "expr ::= expr AND expr",
+ /* 192 */ "expr ::= expr OR expr",
+ /* 193 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 194 */ "expr ::= expr EQ|NE expr",
+ /* 195 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 196 */ "expr ::= expr PLUS|MINUS expr",
+ /* 197 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 198 */ "expr ::= expr CONCAT expr",
+ /* 199 */ "likeop ::= LIKE_KW",
+ /* 200 */ "likeop ::= NOT LIKE_KW",
+ /* 201 */ "likeop ::= MATCH",
+ /* 202 */ "likeop ::= NOT MATCH",
+ /* 203 */ "escape ::= ESCAPE expr",
+ /* 204 */ "escape ::=",
+ /* 205 */ "expr ::= expr likeop expr escape",
+ /* 206 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 207 */ "expr ::= expr IS NULL",
+ /* 208 */ "expr ::= expr NOT NULL",
+ /* 209 */ "expr ::= expr IS NOT NULL",
+ /* 210 */ "expr ::= NOT|BITNOT expr",
+ /* 211 */ "expr ::= MINUS expr",
+ /* 212 */ "expr ::= PLUS expr",
+ /* 213 */ "between_op ::= BETWEEN",
+ /* 214 */ "between_op ::= NOT BETWEEN",
+ /* 215 */ "expr ::= expr between_op expr AND expr",
+ /* 216 */ "in_op ::= IN",
+ /* 217 */ "in_op ::= NOT IN",
+ /* 218 */ "expr ::= expr in_op LP exprlist RP",
+ /* 219 */ "expr ::= LP select RP",
+ /* 220 */ "expr ::= expr in_op LP select RP",
+ /* 221 */ "expr ::= expr in_op nm dbnm",
+ /* 222 */ "expr ::= EXISTS LP select RP",
+ /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 225 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 226 */ "case_else ::= ELSE expr",
+ /* 227 */ "case_else ::=",
+ /* 228 */ "case_operand ::= expr",
+ /* 229 */ "case_operand ::=",
+ /* 230 */ "exprlist ::= exprlist COMMA expritem",
+ /* 231 */ "exprlist ::= expritem",
+ /* 232 */ "expritem ::= expr",
+ /* 233 */ "expritem ::=",
+ /* 234 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
+ /* 235 */ "uniqueflag ::= UNIQUE",
+ /* 236 */ "uniqueflag ::=",
+ /* 237 */ "idxlist_opt ::=",
+ /* 238 */ "idxlist_opt ::= LP idxlist RP",
+ /* 239 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
+ /* 240 */ "idxlist ::= idxitem collate sortorder",
+ /* 241 */ "idxitem ::= nm",
+ /* 242 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 243 */ "cmd ::= VACUUM",
+ /* 244 */ "cmd ::= VACUUM nm",
+ /* 245 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 246 */ "cmd ::= PRAGMA nm dbnm EQ ON",
  /* 247 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 248 */ "cmd ::= PRAGMA nm dbnm LP nm RP",
+ /* 248 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
  /* 249 */ "cmd ::= PRAGMA nm dbnm",
- /* 250 */ "plus_num ::= plus_opt number",
- /* 251 */ "minus_num ::= MINUS number",
- /* 252 */ "number ::= INTEGER|FLOAT",
- /* 253 */ "plus_opt ::= PLUS",
- /* 254 */ "plus_opt ::=",
- /* 255 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
- /* 256 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 257 */ "trigger_time ::= BEFORE",
- /* 258 */ "trigger_time ::= AFTER",
- /* 259 */ "trigger_time ::= INSTEAD OF",
- /* 260 */ "trigger_time ::=",
- /* 261 */ "trigger_event ::= DELETE|INSERT",
- /* 262 */ "trigger_event ::= UPDATE",
- /* 263 */ "trigger_event ::= UPDATE OF inscollist",
- /* 264 */ "foreach_clause ::=",
- /* 265 */ "foreach_clause ::= FOR EACH ROW",
- /* 266 */ "foreach_clause ::= FOR EACH STATEMENT",
- /* 267 */ "when_clause ::=",
- /* 268 */ "when_clause ::= WHEN expr",
- /* 269 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 270 */ "trigger_cmd_list ::=",
- /* 271 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
- /* 272 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
- /* 273 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
- /* 274 */ "trigger_cmd ::= DELETE FROM nm where_opt",
- /* 275 */ "trigger_cmd ::= select",
- /* 276 */ "expr ::= RAISE LP IGNORE RP",
- /* 277 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 278 */ "raisetype ::= ROLLBACK",
- /* 279 */ "raisetype ::= ABORT",
- /* 280 */ "raisetype ::= FAIL",
- /* 281 */ "cmd ::= DROP TRIGGER fullname",
- /* 282 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 283 */ "key_opt ::=",
- /* 284 */ "key_opt ::= KEY expr",
- /* 285 */ "database_kw_opt ::= DATABASE",
- /* 286 */ "database_kw_opt ::=",
- /* 287 */ "cmd ::= DETACH database_kw_opt expr",
- /* 288 */ "cmd ::= REINDEX",
- /* 289 */ "cmd ::= REINDEX nm dbnm",
- /* 290 */ "cmd ::= ANALYZE",
- /* 291 */ "cmd ::= ANALYZE nm dbnm",
- /* 292 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 293 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 294 */ "add_column_fullname ::= fullname",
- /* 295 */ "kwcolumn_opt ::=",
- /* 296 */ "kwcolumn_opt ::= COLUMNKW",
- /* 297 */ "cmd ::= create_vtab",
- /* 298 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 299 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
- /* 300 */ "vtabarglist ::= vtabarg",
- /* 301 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 302 */ "vtabarg ::=",
- /* 303 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 304 */ "vtabargtoken ::= ANY",
- /* 305 */ "vtabargtoken ::= lp anylist RP",
- /* 306 */ "lp ::= LP",
- /* 307 */ "anylist ::=",
- /* 308 */ "anylist ::= anylist ANY",
+ /* 250 */ "nmnum ::= plus_num",
+ /* 251 */ "nmnum ::= nm",
+ /* 252 */ "plus_num ::= plus_opt number",
+ /* 253 */ "minus_num ::= MINUS number",
+ /* 254 */ "number ::= INTEGER|FLOAT",
+ /* 255 */ "plus_opt ::= PLUS",
+ /* 256 */ "plus_opt ::=",
+ /* 257 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
+ /* 258 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 259 */ "trigger_time ::= BEFORE",
+ /* 260 */ "trigger_time ::= AFTER",
+ /* 261 */ "trigger_time ::= INSTEAD OF",
+ /* 262 */ "trigger_time ::=",
+ /* 263 */ "trigger_event ::= DELETE|INSERT",
+ /* 264 */ "trigger_event ::= UPDATE",
+ /* 265 */ "trigger_event ::= UPDATE OF inscollist",
+ /* 266 */ "foreach_clause ::=",
+ /* 267 */ "foreach_clause ::= FOR EACH ROW",
+ /* 268 */ "foreach_clause ::= FOR EACH STATEMENT",
+ /* 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 */ "key_opt ::=",
+ /* 286 */ "key_opt ::= KEY expr",
+ /* 287 */ "database_kw_opt ::= DATABASE",
+ /* 288 */ "database_kw_opt ::=",
+ /* 289 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 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 */
 
@@ -1241,9 +1245,9 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
     case 156:
     case 190:
     case 207:
-#line 374 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3SelectDelete((yypminor->yy219));}
-#line 1248 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 374 "parse.y"
+{sqlite3SelectDelete((yypminor->yy43));}
+#line 1252 "parse.c"
       break;
     case 170:
     case 171:
@@ -1255,10 +1259,10 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
     case 222:
     case 224:
     case 225:
-    case 235:
-#line 631 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3ExprDelete((yypminor->yy172));}
-#line 1263 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 236:
+#line 618 "parse.y"
+{sqlite3ExprDelete((yypminor->yy450));}
+#line 1267 "parse.c"
       break;
     case 175:
     case 183:
@@ -1271,48 +1275,48 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
     case 214:
     case 217:
     case 223:
-#line 865 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3ExprListDelete((yypminor->yy174));}
-#line 1278 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 855 "parse.y"
+{sqlite3ExprListDelete((yypminor->yy242));}
+#line 1282 "parse.c"
       break;
     case 189:
     case 194:
     case 202:
     case 203:
-#line 502 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3SrcListDelete((yypminor->yy373));}
-#line 1286 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 487 "parse.y"
+{sqlite3SrcListDelete((yypminor->yy419));}
+#line 1290 "parse.c"
       break;
     case 199:
-#line 563 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 548 "parse.y"
 {
-  sqlite3ExprDelete((yypminor->yy234).pLimit);
-  sqlite3ExprDelete((yypminor->yy234).pOffset);
+  sqlite3ExprDelete((yypminor->yy84).pLimit);
+  sqlite3ExprDelete((yypminor->yy84).pOffset);
 }
-#line 1294 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1298 "parse.c"
       break;
     case 206:
     case 209:
     case 216:
-#line 519 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3IdListDelete((yypminor->yy432));}
-#line 1301 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 504 "parse.y"
+{sqlite3IdListDelete((yypminor->yy352));}
+#line 1305 "parse.c"
       break;
-    case 231:
-    case 236:
-#line 959 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DeleteTriggerStep((yypminor->yy243));}
-#line 1307 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 232:
+    case 237:
+#line 952 "parse.y"
+{sqlite3DeleteTriggerStep((yypminor->yy75));}
+#line 1311 "parse.c"
       break;
-    case 233:
-#line 943 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3IdListDelete((yypminor->yy370).b);}
-#line 1312 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 234:
+#line 936 "parse.y"
+{sqlite3IdListDelete((yypminor->yy354).b);}
+#line 1316 "parse.c"
       break;
-    case 238:
-#line 1027 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3ExprDelete((yypminor->yy386));}
-#line 1317 "ext/pdo_sqlite/sqlite/src/parse.c"
+    case 239:
+#line 1020 "parse.y"
+{sqlite3ExprDelete((yypminor->yy158));}
+#line 1321 "parse.c"
       break;
     default:  break;   /* If no destructor action specified: do nothing */
   }
@@ -1476,11 +1480,11 @@ static void yy_shift(
      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"
+#line 44 "parse.y"
 
   sqlite3ErrorMsg(pParse, "parser stack overflow");
   pParse->parseError = 1;
-#line 1486 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1490 "parse.c"
      sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
      return;
   }
@@ -1557,11 +1561,11 @@ static const struct {
   { 160, 0 },
   { 168, 3 },
   { 168, 1 },
-  { 168, 2 },
-  { 168, 4 },
-  { 168, 3 },
-  { 168, 3 },
-  { 168, 2 },
+  { 169, 2 },
+  { 169, 4 },
+  { 169, 3 },
+  { 169, 3 },
+  { 169, 2 },
   { 169, 2 },
   { 169, 3 },
   { 169, 5 },
@@ -1609,7 +1613,7 @@ static const struct {
   { 144, 4 },
   { 188, 2 },
   { 188, 0 },
-  { 144, 7 },
+  { 144, 8 },
   { 144, 4 },
   { 144, 1 },
   { 156, 1 },
@@ -1674,6 +1678,7 @@ static const struct {
   { 214, 3 },
   { 144, 8 },
   { 144, 5 },
+  { 144, 6 },
   { 215, 2 },
   { 215, 1 },
   { 217, 3 },
@@ -1754,46 +1759,47 @@ static const struct {
   { 144, 5 },
   { 144, 5 },
   { 144, 5 },
-  { 144, 5 },
   { 144, 6 },
   { 144, 3 },
+  { 228, 1 },
+  { 228, 1 },
   { 166, 2 },
   { 167, 2 },
+  { 230, 1 },
   { 229, 1 },
-  { 228, 1 },
-  { 228, 0 },
+  { 229, 0 },
   { 144, 5 },
-  { 230, 10 },
-  { 232, 1 },
-  { 232, 1 },
-  { 232, 2 },
-  { 232, 0 },
+  { 231, 11 },
   { 233, 1 },
   { 233, 1 },
-  { 233, 3 },
-  { 234, 0 },
-  { 234, 3 },
+  { 233, 2 },
+  { 233, 0 },
+  { 234, 1 },
+  { 234, 1 },
   { 234, 3 },
   { 235, 0 },
-  { 235, 2 },
-  { 231, 3 },
-  { 231, 0 },
-  { 236, 6 },
-  { 236, 8 },
-  { 236, 5 },
-  { 236, 4 },
-  { 236, 1 },
+  { 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, 3 },
+  { 144, 4 },
   { 144, 6 },
+  { 239, 0 },
+  { 239, 2 },
+  { 238, 1 },
   { 238, 0 },
-  { 238, 2 },
-  { 237, 1 },
-  { 237, 0 },
   { 144, 3 },
   { 144, 1 },
   { 144, 3 },
@@ -1801,21 +1807,21 @@ static const struct {
   { 144, 3 },
   { 144, 6 },
   { 144, 6 },
-  { 239, 1 },
-  { 240, 0 },
   { 240, 1 },
+  { 241, 0 },
+  { 241, 1 },
   { 144, 1 },
   { 144, 4 },
-  { 241, 7 },
-  { 242, 1 },
-  { 242, 3 },
-  { 243, 0 },
-  { 243, 2 },
-  { 244, 1 },
-  { 244, 3 },
+  { 242, 7 },
+  { 243, 1 },
+  { 243, 3 },
+  { 244, 0 },
+  { 244, 2 },
   { 245, 1 },
-  { 246, 0 },
-  { 246, 2 },
+  { 245, 3 },
+  { 246, 1 },
+  { 247, 0 },
+  { 247, 2 },
 };
 
 static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -1843,7 +1849,6 @@ static void yy_reduce(
   }
 #endif /* NDEBUG */
 
-#ifndef NDEBUG
   /* Silence complaints from purify about yygotominor being uninitialized
   ** in some cases when it is copied into the stack after the following
   ** switch.  yygotominor is uninitialized when a rule reduces that does
@@ -1851,9 +1856,15 @@ static void yy_reduce(
   ** value of the nonterminal uninitialized is utterly harmless as long
   ** as the value is never used.  So really the only thing this code
   ** accomplishes is to quieten purify.  
+  **
+  ** 2007-01-16:  The wireshark project (www.wireshark.org) reports that
+  ** without this code, their parser segfaults.  I'm not sure what there
+  ** parser is doing to make this happen.  This is the second bug report
+  ** from wireshark this week.  Clearly they are stressing Lemon in ways
+  ** that it has not been previously stressed...  (SQLite ticket #2172)
   */
   memset(&yygotominor, 0, sizeof(yygotominor));
-#endif
+
 
   switch( yyruleno ){
   /* Beginning here are the reduction cases.  A typical example
@@ -1865,61 +1876,61 @@ static void yy_reduce(
   **     break;
   */
       case 3:
-#line 100 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 100 "parse.y"
 { sqlite3FinishCoding(pParse); }
-#line 1873 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1884 "parse.c"
         break;
       case 6:
-#line 103 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 103 "parse.y"
 { sqlite3BeginParse(pParse, 0); }
-#line 1878 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1889 "parse.c"
         break;
       case 7:
-#line 105 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 105 "parse.y"
 { sqlite3BeginParse(pParse, 1); }
-#line 1883 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1894 "parse.c"
         break;
       case 8:
-#line 106 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 106 "parse.y"
 { sqlite3BeginParse(pParse, 2); }
-#line 1888 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1899 "parse.c"
         break;
       case 9:
-#line 112 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy46);}
-#line 1893 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 112 "parse.y"
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy316);}
+#line 1904 "parse.c"
         break;
       case 13:
-#line 117 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = TK_DEFERRED;}
-#line 1898 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 117 "parse.y"
+{yygotominor.yy316 = TK_DEFERRED;}
+#line 1909 "parse.c"
         break;
       case 14:
       case 15:
       case 16:
       case 107:
       case 109:
-#line 118 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = yymsp[0].major;}
-#line 1907 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 118 "parse.y"
+{yygotominor.yy316 = yymsp[0].major;}
+#line 1918 "parse.c"
         break;
       case 17:
       case 18:
-#line 121 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 121 "parse.y"
 {sqlite3CommitTransaction(pParse);}
-#line 1913 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1924 "parse.c"
         break;
       case 19:
-#line 123 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 123 "parse.y"
 {sqlite3RollbackTransaction(pParse);}
-#line 1918 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1929 "parse.c"
         break;
       case 21:
-#line 128 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 128 "parse.y"
 {
-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,yymsp[-4].minor.yy46,0,0,yymsp[-2].minor.yy46);
+   sqlite3StartTable(pParse,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178,yymsp[-4].minor.yy316,0,0,yymsp[-2].minor.yy316);
 }
-#line 1925 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1936 "parse.c"
         break;
       case 22:
       case 25:
@@ -1930,11 +1941,11 @@ static void yy_reduce(
       case 101:
       case 112:
       case 113:
-      case 212:
-      case 215:
-#line 132 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = 0;}
-#line 1940 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 213:
+      case 216:
+#line 132 "parse.y"
+{yygotominor.yy316 = 0;}
+#line 1951 "parse.c"
         break;
       case 23:
       case 24:
@@ -1942,57 +1953,57 @@ static void yy_reduce(
       case 78:
       case 100:
       case 111:
-      case 213:
-      case 216:
-#line 133 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = 1;}
-#line 1952 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 214:
+      case 217:
+#line 133 "parse.y"
+{yygotominor.yy316 = 1;}
+#line 1963 "parse.c"
         break;
       case 26:
-#line 139 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 139 "parse.y"
 {
-  sqlite3EndTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy0,0);
+  sqlite3EndTable(pParse,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy0,0);
 }
-#line 1959 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1970 "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.yy219);
-  sqlite3SelectDelete(yymsp[0].minor.yy219);
+  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy43);
+  sqlite3SelectDelete(yymsp[0].minor.yy43);
 }
-#line 1967 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1978 "parse.c"
         break;
       case 30:
-#line 154 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 154 "parse.y"
 {
-  yygotominor.yy410.z = yymsp[-2].minor.yy410.z;
-  yygotominor.yy410.n = (pParse->sLastToken.z-yymsp[-2].minor.yy410.z) + pParse->sLastToken.n;
+  yygotominor.yy178.z = yymsp[-2].minor.yy178.z;
+  yygotominor.yy178.n = (pParse->sLastToken.z-yymsp[-2].minor.yy178.z) + pParse->sLastToken.n;
 }
-#line 1975 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1986 "parse.c"
         break;
       case 31:
-#line 158 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 158 "parse.y"
 {
-  sqlite3AddColumn(pParse,&yymsp[0].minor.yy410);
-  yygotominor.yy410 = yymsp[0].minor.yy410;
+  sqlite3AddColumn(pParse,&yymsp[0].minor.yy178);
+  yygotominor.yy178 = yymsp[0].minor.yy178;
 }
-#line 1983 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1994 "parse.c"
         break;
       case 32:
       case 33:
       case 34:
       case 35:
       case 36:
-      case 252:
-#line 168 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy410 = yymsp[0].minor.yy0;}
-#line 1993 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 254:
+#line 168 "parse.y"
+{yygotominor.yy178 = yymsp[0].minor.yy0;}
+#line 2004 "parse.c"
         break;
       case 38:
-#line 228 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy410);}
-#line 1998 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 228 "parse.y"
+{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy178);}
+#line 2009 "parse.c"
         break;
       case 39:
       case 42:
@@ -2000,155 +2011,157 @@ static void yy_reduce(
       case 120:
       case 131:
       case 150:
-      case 240:
+      case 241:
       case 250:
       case 251:
-#line 229 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy410 = yymsp[0].minor.yy410;}
-#line 2011 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 252:
+      case 253:
+#line 229 "parse.y"
+{yygotominor.yy178 = yymsp[0].minor.yy178;}
+#line 2024 "parse.c"
         break;
       case 40:
-#line 230 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 230 "parse.y"
 {
-  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;
+  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;
 }
-#line 2019 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2032 "parse.c"
         break;
       case 41:
-#line 234 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 234 "parse.y"
 {
-  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;
+  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;
 }
-#line 2027 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2040 "parse.c"
         break;
       case 43:
-#line 240 "ext/pdo_sqlite/sqlite/src/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 2032 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 240 "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 2045 "parse.c"
         break;
       case 44:
-#line 242 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = atoi((char*)yymsp[0].minor.yy410.z); }
-#line 2037 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 242 "parse.y"
+{ yygotominor.yy316 = atoi((char*)yymsp[0].minor.yy178.z); }
+#line 2050 "parse.c"
         break;
       case 45:
-#line 243 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = -atoi((char*)yymsp[0].minor.yy410.z); }
-#line 2042 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 243 "parse.y"
+{ yygotominor.yy316 = -atoi((char*)yymsp[0].minor.yy178.z); }
+#line 2055 "parse.c"
         break;
       case 50:
       case 52:
-#line 252 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy172);}
-#line 2048 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 252 "parse.y"
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy450);}
+#line 2061 "parse.c"
         break;
       case 51:
-#line 253 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy172);}
-#line 2053 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 253 "parse.y"
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy450);}
+#line 2066 "parse.c"
         break;
       case 53:
-#line 255 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 255 "parse.y"
 {
-  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
+  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy450, 0, 0);
   sqlite3AddDefaultValue(pParse,p);
 }
-#line 2061 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2074 "parse.c"
         break;
       case 54:
-#line 259 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 259 "parse.y"
 {
-  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy410);
+  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy178);
   sqlite3AddDefaultValue(pParse,p);
 }
-#line 2069 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2082 "parse.c"
         break;
       case 56:
-#line 268 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy46);}
-#line 2074 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 268 "parse.y"
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy316);}
+#line 2087 "parse.c"
         break;
       case 57:
-#line 270 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy46,yymsp[0].minor.yy46,yymsp[-2].minor.yy46);}
-#line 2079 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 270 "parse.y"
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy316,yymsp[0].minor.yy316,yymsp[-2].minor.yy316);}
+#line 2092 "parse.c"
         break;
       case 58:
-#line 271 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy46,0,0,0,0);}
-#line 2084 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 271 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy316,0,0,0,0);}
+#line 2097 "parse.c"
         break;
       case 59:
-#line 272 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy172);}
-#line 2089 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 272 "parse.y"
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy450);}
+#line 2102 "parse.c"
         break;
       case 60:
-#line 274 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy410,yymsp[-1].minor.yy174,yymsp[0].minor.yy46);}
-#line 2094 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 274 "parse.y"
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy178,yymsp[-1].minor.yy242,yymsp[0].minor.yy316);}
+#line 2107 "parse.c"
         break;
       case 61:
-#line 275 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy46);}
-#line 2099 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 275 "parse.y"
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy316);}
+#line 2112 "parse.c"
         break;
       case 62:
-#line 276 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy410.z, yymsp[0].minor.yy410.n);}
-#line 2104 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 276 "parse.y"
+{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy178.z, yymsp[0].minor.yy178.n);}
+#line 2117 "parse.c"
         break;
       case 65:
-#line 289 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = OE_Restrict * 0x010101; }
-#line 2109 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 289 "parse.y"
+{ yygotominor.yy316 = OE_Restrict * 0x010101; }
+#line 2122 "parse.c"
         break;
       case 66:
-#line 290 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = (yymsp[-1].minor.yy46 & yymsp[0].minor.yy405.mask) | yymsp[0].minor.yy405.value; }
-#line 2114 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 290 "parse.y"
+{ yygotominor.yy316 = (yymsp[-1].minor.yy316 & yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
+#line 2127 "parse.c"
         break;
       case 67:
-#line 292 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy405.value = 0;     yygotominor.yy405.mask = 0x000000; }
-#line 2119 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 292 "parse.y"
+{ yygotominor.yy207.value = 0;     yygotominor.yy207.mask = 0x000000; }
+#line 2132 "parse.c"
         break;
       case 68:
-#line 293 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy405.value = yymsp[0].minor.yy46;     yygotominor.yy405.mask = 0x0000ff; }
-#line 2124 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 293 "parse.y"
+{ yygotominor.yy207.value = yymsp[0].minor.yy316;     yygotominor.yy207.mask = 0x0000ff; }
+#line 2137 "parse.c"
         break;
       case 69:
-#line 294 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy405.value = yymsp[0].minor.yy46<<8;  yygotominor.yy405.mask = 0x00ff00; }
-#line 2129 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 294 "parse.y"
+{ yygotominor.yy207.value = yymsp[0].minor.yy316<<8;  yygotominor.yy207.mask = 0x00ff00; }
+#line 2142 "parse.c"
         break;
       case 70:
-#line 295 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy405.value = yymsp[0].minor.yy46<<16; yygotominor.yy405.mask = 0xff0000; }
-#line 2134 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 295 "parse.y"
+{ yygotominor.yy207.value = yymsp[0].minor.yy316<<16; yygotominor.yy207.mask = 0xff0000; }
+#line 2147 "parse.c"
         break;
       case 71:
-#line 297 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = OE_SetNull; }
-#line 2139 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 297 "parse.y"
+{ yygotominor.yy316 = OE_SetNull; }
+#line 2152 "parse.c"
         break;
       case 72:
-#line 298 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = OE_SetDflt; }
-#line 2144 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 298 "parse.y"
+{ yygotominor.yy316 = OE_SetDflt; }
+#line 2157 "parse.c"
         break;
       case 73:
-#line 299 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = OE_Cascade; }
-#line 2149 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 299 "parse.y"
+{ yygotominor.yy316 = OE_Cascade; }
+#line 2162 "parse.c"
         break;
       case 74:
-#line 300 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = OE_Restrict; }
-#line 2154 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 300 "parse.y"
+{ yygotominor.yy316 = OE_Restrict; }
+#line 2167 "parse.c"
         break;
       case 75:
       case 76:
@@ -2156,490 +2169,482 @@ static void yy_reduce(
       case 93:
       case 95:
       case 96:
-      case 167:
-#line 302 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = yymsp[0].minor.yy46;}
-#line 2165 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 168:
+#line 302 "parse.y"
+{yygotominor.yy316 = yymsp[0].minor.yy316;}
+#line 2178 "parse.c"
         break;
       case 80:
-#line 312 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy410.n = 0; yygotominor.yy410.z = 0;}
-#line 2170 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 312 "parse.y"
+{yygotominor.yy178.n = 0; yygotominor.yy178.z = 0;}
+#line 2183 "parse.c"
         break;
       case 81:
-#line 313 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy410 = yymsp[-1].minor.yy0;}
-#line 2175 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 313 "parse.y"
+{yygotominor.yy178 = yymsp[-1].minor.yy0;}
+#line 2188 "parse.c"
         break;
       case 86:
-#line 319 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy174,yymsp[0].minor.yy46,yymsp[-2].minor.yy46,0);}
-#line 2180 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 319 "parse.y"
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy316,yymsp[-2].minor.yy316,0);}
+#line 2193 "parse.c"
         break;
       case 87:
-#line 321 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy174,yymsp[0].minor.yy46,0,0,0,0);}
-#line 2185 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 321 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy242,yymsp[0].minor.yy316,0,0,0,0);}
+#line 2198 "parse.c"
         break;
       case 88:
-#line 322 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy172);}
-#line 2190 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 322 "parse.y"
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy450);}
+#line 2203 "parse.c"
         break;
       case 89:
-#line 324 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 324 "parse.y"
 {
-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy174, &yymsp[-3].minor.yy410, yymsp[-2].minor.yy174, yymsp[-1].minor.yy46);
-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy46);
+    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy242, &yymsp[-3].minor.yy178, yymsp[-2].minor.yy242, yymsp[-1].minor.yy316);
+    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy316);
 }
-#line 2198 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2211 "parse.c"
         break;
       case 92:
       case 94:
-#line 338 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = OE_Default;}
-#line 2204 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 338 "parse.y"
+{yygotominor.yy316 = OE_Default;}
+#line 2217 "parse.c"
         break;
       case 97:
-#line 343 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = OE_Ignore;}
-#line 2209 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 343 "parse.y"
+{yygotominor.yy316 = OE_Ignore;}
+#line 2222 "parse.c"
         break;
       case 98:
-      case 168:
-#line 344 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = OE_Replace;}
-#line 2215 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 169:
+#line 344 "parse.y"
+{yygotominor.yy316 = OE_Replace;}
+#line 2228 "parse.c"
         break;
       case 99:
-#line 348 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 348 "parse.y"
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy373, 0, yymsp[-1].minor.yy46);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy419, 0, yymsp[-1].minor.yy316);
 }
-#line 2222 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2235 "parse.c"
         break;
       case 102:
-#line 358 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 358 "parse.y"
 {
-  sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, yymsp[0].minor.yy219, yymsp[-5].minor.yy46);
+  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);
 }
-#line 2229 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2242 "parse.c"
         break;
       case 103:
-#line 361 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 361 "parse.y"
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy373, 1, yymsp[-1].minor.yy46);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy419, 1, yymsp[-1].minor.yy316);
 }
-#line 2236 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2249 "parse.c"
         break;
       case 104:
-#line 368 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 368 "parse.y"
 {
-  sqlite3Select(pParse, yymsp[0].minor.yy219, SRT_Callback, 0, 0, 0, 0, 0);
-  sqlite3SelectDelete(yymsp[0].minor.yy219);
+  sqlite3Select(pParse, yymsp[0].minor.yy43, SRT_Callback, 0, 0, 0, 0, 0);
+  sqlite3SelectDelete(yymsp[0].minor.yy43);
 }
-#line 2244 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2257 "parse.c"
         break;
       case 105:
       case 128:
-#line 378 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy219 = yymsp[0].minor.yy219;}
-#line 2250 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 378 "parse.y"
+{yygotominor.yy43 = yymsp[0].minor.yy43;}
+#line 2263 "parse.c"
         break;
       case 106:
-#line 380 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 380 "parse.y"
 {
-  if( yymsp[0].minor.yy219 ){
-    yymsp[0].minor.yy219->op = yymsp[-1].minor.yy46;
-    yymsp[0].minor.yy219->pPrior = yymsp[-2].minor.yy219;
+  if( yymsp[0].minor.yy43 ){
+    yymsp[0].minor.yy43->op = yymsp[-1].minor.yy316;
+    yymsp[0].minor.yy43->pPrior = yymsp[-2].minor.yy43;
   }
-  yygotominor.yy219 = yymsp[0].minor.yy219;
+  yygotominor.yy43 = yymsp[0].minor.yy43;
 }
-#line 2261 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2274 "parse.c"
         break;
       case 108:
-#line 389 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = TK_ALL;}
-#line 2266 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 389 "parse.y"
+{yygotominor.yy316 = TK_ALL;}
+#line 2279 "parse.c"
         break;
       case 110:
-#line 393 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 393 "parse.y"
 {
-  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);
+  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);
 }
-#line 2273 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2286 "parse.c"
         break;
       case 114:
-      case 237:
-#line 414 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy174 = yymsp[-1].minor.yy174;}
-#line 2279 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 238:
+#line 414 "parse.y"
+{yygotominor.yy242 = yymsp[-1].minor.yy242;}
+#line 2292 "parse.c"
         break;
       case 115:
       case 141:
       case 151:
-      case 236:
-#line 415 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy174 = 0;}
-#line 2287 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 237:
+#line 415 "parse.y"
+{yygotominor.yy242 = 0;}
+#line 2300 "parse.c"
         break;
       case 116:
-#line 416 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 416 "parse.y"
 {
-   yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy410.n?&yymsp[0].minor.yy410:0);
+   yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-2].minor.yy242,yymsp[-1].minor.yy450,yymsp[0].minor.yy178.n?&yymsp[0].minor.yy178:0);
 }
-#line 2294 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2307 "parse.c"
         break;
       case 117:
-#line 419 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 419 "parse.y"
 {
-  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-1].minor.yy174, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
+  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-1].minor.yy242, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
 }
-#line 2301 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2314 "parse.c"
         break;
       case 118:
-#line 422 "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.yy410);
-  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-3].minor.yy174, sqlite3Expr(TK_DOT, pLeft, pRight, 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);
 }
-#line 2310 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2323 "parse.c"
         break;
       case 121:
-#line 434 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy410.n = 0;}
-#line 2315 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 434 "parse.y"
+{yygotominor.yy178.n = 0;}
+#line 2328 "parse.c"
         break;
       case 122:
-#line 446 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy373 = sqliteMalloc(sizeof(*yygotominor.yy373));}
-#line 2320 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 446 "parse.y"
+{yygotominor.yy419 = sqliteMalloc(sizeof(*yygotominor.yy419));}
+#line 2333 "parse.c"
         break;
       case 123:
-#line 447 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy373 = yymsp[0].minor.yy373;}
-#line 2325 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 447 "parse.y"
+{
+  yygotominor.yy419 = yymsp[0].minor.yy419;
+  sqlite3SrcListShiftJoinType(yygotominor.yy419);
+}
+#line 2341 "parse.c"
         break;
       case 124:
-#line 452 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 455 "parse.y"
 {
-   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;
+   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;
 }
-#line 2333 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2349 "parse.c"
         break;
       case 125:
-#line 456 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy373 = 0;}
-#line 2338 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 459 "parse.y"
+{yygotominor.yy419 = 0;}
+#line 2354 "parse.c"
         break;
       case 126:
-#line 457 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 460 "parse.y"
 {
-  yygotominor.yy373 = sqlite3SrcListAppend(yymsp[-5].minor.yy373,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410);
-  if( yymsp[-2].minor.yy410.n ) sqlite3SrcListAddAlias(yygotominor.yy373,&yymsp[-2].minor.yy410);
-  if( yymsp[-1].minor.yy172 ){
-    if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pOn = yymsp[-1].minor.yy172; }
-    else { sqlite3ExprDelete(yymsp[-1].minor.yy172); }
-  }
-  if( yymsp[0].minor.yy432 ){
-    if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pUsing = yymsp[0].minor.yy432; }
-    else { sqlite3IdListDelete(yymsp[0].minor.yy432); }
-  }
+  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);
 }
-#line 2354 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2361 "parse.c"
         break;
       case 127:
-#line 471 "ext/pdo_sqlite/sqlite/src/parse.y"
-{
-    yygotominor.yy373 = sqlite3SrcListAppend(yymsp[-6].minor.yy373,0,0);
-    if( yygotominor.yy373 && yygotominor.yy373->nSrc>0 ) yygotominor.yy373->a[yygotominor.yy373->nSrc-1].pSelect = yymsp[-4].minor.yy219;
-    if( yymsp[-2].minor.yy410.n ) sqlite3SrcListAddAlias(yygotominor.yy373,&yymsp[-2].minor.yy410);
-    if( yymsp[-1].minor.yy172 ){
-      if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pOn = yymsp[-1].minor.yy172; }
-      else { sqlite3ExprDelete(yymsp[-1].minor.yy172); }
-    }
-    if( yymsp[0].minor.yy432 ){
-      if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pUsing = yymsp[0].minor.yy432; }
-      else { sqlite3IdListDelete(yymsp[0].minor.yy432); }
-    }
+#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);
   }
-#line 2371 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2368 "parse.c"
         break;
       case 129:
-#line 492 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 476 "parse.y"
 {
-     yygotominor.yy219 = sqlite3SelectNew(0,yymsp[0].minor.yy373,0,0,0,0,0,0,0);
+     sqlite3SrcListShiftJoinType(yymsp[0].minor.yy419);
+     yygotominor.yy43 = sqlite3SelectNew(0,yymsp[0].minor.yy419,0,0,0,0,0,0,0);
   }
-#line 2378 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2376 "parse.c"
         break;
       case 130:
-#line 498 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy410.z=0; yygotominor.yy410.n=0;}
-#line 2383 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 483 "parse.y"
+{yygotominor.yy178.z=0; yygotominor.yy178.n=0;}
+#line 2381 "parse.c"
         break;
       case 132:
-#line 503 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy373 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);}
-#line 2388 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 488 "parse.y"
+{yygotominor.yy419 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178);}
+#line 2386 "parse.c"
         break;
       case 133:
-#line 507 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = JT_INNER; }
-#line 2393 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 492 "parse.y"
+{ yygotominor.yy316 = JT_INNER; }
+#line 2391 "parse.c"
         break;
       case 134:
-#line 508 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
-#line 2398 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 493 "parse.y"
+{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+#line 2396 "parse.c"
         break;
       case 135:
-#line 509 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy410,0); }
-#line 2403 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 494 "parse.y"
+{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy178,0); }
+#line 2401 "parse.c"
         break;
       case 136:
-#line 511 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy410,&yymsp[-1].minor.yy410); }
-#line 2408 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 496 "parse.y"
+{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy178,&yymsp[-1].minor.yy178); }
+#line 2406 "parse.c"
         break;
       case 137:
       case 145:
       case 154:
       case 161:
-      case 175:
-      case 202:
-      case 225:
-      case 227:
-      case 231:
-#line 515 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy172 = yymsp[0].minor.yy172;}
-#line 2421 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 138:
-      case 153:
-      case 160:
+      case 176:
       case 203:
       case 226:
       case 228:
       case 232:
-#line 516 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy172 = 0;}
-#line 2432 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 500 "parse.y"
+{yygotominor.yy450 = yymsp[0].minor.yy450;}
+#line 2419 "parse.c"
+        break;
+      case 138:
+      case 153:
+      case 160:
+      case 204:
+      case 227:
+      case 229:
+      case 233:
+#line 501 "parse.y"
+{yygotominor.yy450 = 0;}
+#line 2430 "parse.c"
         break;
       case 139:
-      case 172:
-#line 520 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy432 = yymsp[-1].minor.yy432;}
-#line 2438 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 173:
+#line 505 "parse.y"
+{yygotominor.yy352 = yymsp[-1].minor.yy352;}
+#line 2436 "parse.c"
         break;
       case 140:
-      case 171:
-#line 521 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy432 = 0;}
-#line 2444 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 172:
+#line 506 "parse.y"
+{yygotominor.yy352 = 0;}
+#line 2442 "parse.c"
         break;
       case 142:
       case 152:
-#line 532 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy174 = yymsp[0].minor.yy174;}
-#line 2450 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 517 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 2448 "parse.c"
         break;
       case 143:
-#line 533 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 518 "parse.y"
 {
-  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174,yymsp[-2].minor.yy172,yymsp[-1].minor.yy410.n>0?&yymsp[-1].minor.yy410:0);
-  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
+  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242,yymsp[-2].minor.yy450,yymsp[-1].minor.yy178.n>0?&yymsp[-1].minor.yy178:0);
+  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
 }
-#line 2458 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2456 "parse.c"
         break;
       case 144:
-#line 537 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 522 "parse.y"
 {
-  yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy172,yymsp[-1].minor.yy410.n>0?&yymsp[-1].minor.yy410:0);
-  if( yygotominor.yy174 && yygotominor.yy174->a ) yygotominor.yy174->a[0].sortOrder = yymsp[0].minor.yy46;
+  yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy450,yymsp[-1].minor.yy178.n>0?&yymsp[-1].minor.yy178:0);
+  if( yygotominor.yy242 && yygotominor.yy242->a ) yygotominor.yy242->a[0].sortOrder = yymsp[0].minor.yy316;
 }
-#line 2466 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2464 "parse.c"
         break;
       case 146:
       case 148:
-#line 546 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = SQLITE_SO_ASC;}
-#line 2472 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 531 "parse.y"
+{yygotominor.yy316 = SQLITE_SO_ASC;}
+#line 2470 "parse.c"
         break;
       case 147:
-#line 547 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = SQLITE_SO_DESC;}
-#line 2477 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 532 "parse.y"
+{yygotominor.yy316 = SQLITE_SO_DESC;}
+#line 2475 "parse.c"
         break;
       case 149:
-#line 549 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy410.z = 0; yygotominor.yy410.n = 0;}
-#line 2482 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 534 "parse.y"
+{yygotominor.yy178.z = 0; yygotominor.yy178.n = 0;}
+#line 2480 "parse.c"
         break;
       case 155:
-#line 567 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy234.pLimit = 0; yygotominor.yy234.pOffset = 0;}
-#line 2487 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 552 "parse.y"
+{yygotominor.yy84.pLimit = 0; yygotominor.yy84.pOffset = 0;}
+#line 2485 "parse.c"
         break;
       case 156:
-#line 568 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy234.pLimit = yymsp[0].minor.yy172; yygotominor.yy234.pOffset = 0;}
-#line 2492 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 553 "parse.y"
+{yygotominor.yy84.pLimit = yymsp[0].minor.yy450; yygotominor.yy84.pOffset = 0;}
+#line 2490 "parse.c"
         break;
       case 157:
-#line 570 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy234.pLimit = yymsp[-2].minor.yy172; yygotominor.yy234.pOffset = yymsp[0].minor.yy172;}
-#line 2497 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 555 "parse.y"
+{yygotominor.yy84.pLimit = yymsp[-2].minor.yy450; yygotominor.yy84.pOffset = yymsp[0].minor.yy450;}
+#line 2495 "parse.c"
         break;
       case 158:
-#line 572 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy234.pOffset = yymsp[-2].minor.yy172; yygotominor.yy234.pLimit = yymsp[0].minor.yy172;}
-#line 2502 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 557 "parse.y"
+{yygotominor.yy84.pOffset = yymsp[-2].minor.yy450; yygotominor.yy84.pLimit = yymsp[0].minor.yy450;}
+#line 2500 "parse.c"
         break;
       case 159:
-#line 576 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy373,yymsp[0].minor.yy172);}
-#line 2507 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 561 "parse.y"
+{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy419,yymsp[0].minor.yy450);}
+#line 2505 "parse.c"
         break;
       case 162:
-#line 587 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Update(pParse,yymsp[-3].minor.yy373,yymsp[-1].minor.yy174,yymsp[0].minor.yy172,yymsp[-4].minor.yy46);}
-#line 2512 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 572 "parse.y"
+{sqlite3Update(pParse,yymsp[-3].minor.yy419,yymsp[-1].minor.yy242,yymsp[0].minor.yy450,yymsp[-4].minor.yy316);}
+#line 2510 "parse.c"
         break;
       case 163:
-#line 593 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
-#line 2517 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 578 "parse.y"
+{yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242,yymsp[0].minor.yy450,&yymsp[-2].minor.yy178);}
+#line 2515 "parse.c"
         break;
       case 164:
-#line 594 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
-#line 2522 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 579 "parse.y"
+{yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[0].minor.yy450,&yymsp[-2].minor.yy178);}
+#line 2520 "parse.c"
         break;
       case 165:
-#line 600 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Insert(pParse, yymsp[-5].minor.yy373, yymsp[-1].minor.yy174, 0, yymsp[-4].minor.yy432, yymsp[-7].minor.yy46);}
-#line 2527 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 585 "parse.y"
+{sqlite3Insert(pParse, yymsp[-5].minor.yy419, yymsp[-1].minor.yy242, 0, yymsp[-4].minor.yy352, yymsp[-7].minor.yy316);}
+#line 2525 "parse.c"
         break;
       case 166:
-#line 602 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Insert(pParse, yymsp[-2].minor.yy373, 0, yymsp[0].minor.yy219, yymsp[-1].minor.yy432, yymsp[-4].minor.yy46);}
-#line 2532 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 587 "parse.y"
+{sqlite3Insert(pParse, yymsp[-2].minor.yy419, 0, yymsp[0].minor.yy43, yymsp[-1].minor.yy352, yymsp[-4].minor.yy316);}
+#line 2530 "parse.c"
         break;
-      case 169:
-      case 229:
-#line 612 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-2].minor.yy174,yymsp[0].minor.yy172,0);}
-#line 2538 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 167:
+#line 589 "parse.y"
+{sqlite3Insert(pParse, yymsp[-3].minor.yy419, 0, 0, yymsp[-2].minor.yy352, yymsp[-5].minor.yy316);}
+#line 2535 "parse.c"
         break;
       case 170:
       case 230:
-#line 613 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[0].minor.yy172,0);}
-#line 2544 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 599 "parse.y"
+{yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-2].minor.yy242,yymsp[0].minor.yy450,0);}
+#line 2541 "parse.c"
         break;
-      case 173:
-#line 622 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy432 = sqlite3IdListAppend(yymsp[-2].minor.yy432,&yymsp[0].minor.yy410);}
-#line 2549 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 171:
+      case 231:
+#line 600 "parse.y"
+{yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[0].minor.yy450,0);}
+#line 2547 "parse.c"
         break;
       case 174:
-#line 623 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy432 = sqlite3IdListAppend(0,&yymsp[0].minor.yy410);}
-#line 2554 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 609 "parse.y"
+{yygotominor.yy352 = sqlite3IdListAppend(yymsp[-2].minor.yy352,&yymsp[0].minor.yy178);}
+#line 2552 "parse.c"
         break;
-      case 176:
-#line 634 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy172 = yymsp[-1].minor.yy172; sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
-#line 2559 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 175:
+#line 610 "parse.y"
+{yygotominor.yy352 = sqlite3IdListAppend(0,&yymsp[0].minor.yy178);}
+#line 2557 "parse.c"
         break;
       case 177:
-      case 182:
-      case 183:
-#line 635 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy172 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
-#line 2566 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 621 "parse.y"
+{yygotominor.yy450 = yymsp[-1].minor.yy450; sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+#line 2562 "parse.c"
         break;
       case 178:
-      case 179:
-#line 636 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy172 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
-#line 2572 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 183:
+      case 184:
+#line 622 "parse.y"
+{yygotominor.yy450 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+#line 2569 "parse.c"
         break;
+      case 179:
       case 180:
-#line 638 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 623 "parse.y"
+{yygotominor.yy450 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+#line 2575 "parse.c"
+        break;
+      case 181:
+#line 625 "parse.y"
 {
-  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);
+  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);
 }
-#line 2581 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2584 "parse.c"
         break;
-      case 181:
-#line 643 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 182:
+#line 630 "parse.y"
 {
-  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 *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 *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
-  yygotominor.yy172 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
+  yygotominor.yy450 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
 }
-#line 2592 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 184:
-#line 652 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy172 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
-#line 2597 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2595 "parse.c"
         break;
       case 185:
-#line 653 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 639 "parse.y"
+{yygotominor.yy450 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+#line 2600 "parse.c"
+        break;
+      case 186:
+#line 640 "parse.y"
 {
   Token *pToken = &yymsp[0].minor.yy0;
-  Expr *pExpr = yygotominor.yy172 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
+  Expr *pExpr = yygotominor.yy450 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
   sqlite3ExprAssignVarNumber(pParse, pExpr);
 }
-#line 2606 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2609 "parse.c"
         break;
-      case 186:
-#line 659 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 187:
+#line 646 "parse.y"
 {
-  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);
+  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);
 }
-#line 2614 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2617 "parse.c"
         break;
-      case 187:
-#line 664 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 188:
+#line 651 "parse.y"
 {
-  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;
+  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;
   }
 }
-#line 2625 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2628 "parse.c"
         break;
-      case 188:
-#line 671 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 189:
+#line 658 "parse.y"
 {
-  yygotominor.yy172 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+  yygotominor.yy450 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
 }
-#line 2633 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2636 "parse.c"
         break;
-      case 189:
-#line 675 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 190:
+#line 662 "parse.y"
 {
   /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
   ** treated as functions that return constants */
-  yygotominor.yy172 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
-  if( yygotominor.yy172 ) yygotominor.yy172->op = TK_CONST_FUNC;  
+  yygotominor.yy450 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
+  if( yygotominor.yy450 ){
+    yygotominor.yy450->op = TK_CONST_FUNC;  
+    yygotominor.yy450->span = yymsp[0].minor.yy0;
+  }
 }
-#line 2643 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2649 "parse.c"
         break;
-      case 190:
       case 191:
       case 192:
       case 193:
@@ -2647,534 +2652,534 @@ static void yy_reduce(
       case 195:
       case 196:
       case 197:
-#line 681 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy172 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy172, yymsp[0].minor.yy172, 0);}
-#line 2655 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
       case 198:
-      case 200:
-#line 691 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 0;}
-#line 2661 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 671 "parse.y"
+{yygotominor.yy450 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy450, yymsp[0].minor.yy450, 0);}
+#line 2661 "parse.c"
         break;
       case 199:
       case 201:
-#line 692 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 1;}
-#line 2667 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 681 "parse.y"
+{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 0;}
+#line 2667 "parse.c"
         break;
-      case 204:
-#line 699 "ext/pdo_sqlite/sqlite/src/parse.y"
-{
-  ExprList *pList;
-  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.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 2683 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 200:
+      case 202:
+#line 682 "parse.y"
+{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 1;}
+#line 2673 "parse.c"
         break;
       case 205:
-#line 712 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 689 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy172, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy172->span,&yymsp[0].minor.yy0);
+  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);
+  }
+  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;
 }
-#line 2691 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2689 "parse.c"
         break;
       case 206:
-#line 716 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 702 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy172, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
+  yygotominor.yy450 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy450, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy450->span,&yymsp[0].minor.yy0);
 }
-#line 2699 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2697 "parse.c"
         break;
       case 207:
-#line 720 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 706 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy172, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
+  yygotominor.yy450 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy450, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0);
 }
-#line 2707 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2705 "parse.c"
         break;
       case 208:
-#line 724 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 710 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy172, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,&yymsp[0].minor.yy0);
+  yygotominor.yy450 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy450, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0);
 }
-#line 2715 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2713 "parse.c"
         break;
       case 209:
-#line 728 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 714 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy172, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
+  yygotominor.yy450 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy450, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy450->span,&yymsp[0].minor.yy0);
 }
-#line 2723 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2721 "parse.c"
         break;
       case 210:
-#line 732 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 718 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
+  yygotominor.yy450 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy450, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
 }
-#line 2731 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2729 "parse.c"
         break;
       case 211:
-#line 736 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 722 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy172, 0, 0);
-  sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
+  yygotominor.yy450 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy450, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
 }
-#line 2739 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2737 "parse.c"
         break;
-      case 214:
-#line 743 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 212:
+#line 726 "parse.y"
 {
-  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;
+  yygotominor.yy450 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy450, 0, 0);
+  sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span);
+}
+#line 2745 "parse.c"
+        break;
+      case 215:
+#line 733 "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;
   }else{
     sqlite3ExprListDelete(pList);
   } 
-  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);
+  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);
 }
-#line 2755 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2761 "parse.c"
         break;
-      case 217:
-#line 759 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 218:
+#line 749 "parse.y"
 {
-    yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy172, 0, 0);
-    if( yygotominor.yy172 ){
-      yygotominor.yy172->pList = yymsp[-1].minor.yy174;
+    yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy450, 0, 0);
+    if( yygotominor.yy450 ){
+      yygotominor.yy450->pList = yymsp[-1].minor.yy242;
     }else{
-      sqlite3ExprListDelete(yymsp[-1].minor.yy174);
+      sqlite3ExprListDelete(yymsp[-1].minor.yy242);
     }
-    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);
+    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);
   }
-#line 2769 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2775 "parse.c"
         break;
-      case 218:
-#line 769 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 219:
+#line 759 "parse.y"
 {
-    yygotominor.yy172 = sqlite3Expr(TK_SELECT, 0, 0, 0);
-    if( yygotominor.yy172 ){
-      yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
+    yygotominor.yy450 = sqlite3Expr(TK_SELECT, 0, 0, 0);
+    if( yygotominor.yy450 ){
+      yygotominor.yy450->pSelect = yymsp[-1].minor.yy43;
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy219);
+      sqlite3SelectDelete(yymsp[-1].minor.yy43);
     }
-    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+    sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
   }
-#line 2782 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2788 "parse.c"
         break;
-      case 219:
-#line 778 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 220:
+#line 768 "parse.y"
 {
-    yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy172, 0, 0);
-    if( yygotominor.yy172 ){
-      yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
+    yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy450, 0, 0);
+    if( yygotominor.yy450 ){
+      yygotominor.yy450->pSelect = yymsp[-1].minor.yy43;
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy219);
+      sqlite3SelectDelete(yymsp[-1].minor.yy43);
     }
-    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);
+    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);
   }
-#line 2796 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2802 "parse.c"
         break;
-      case 220:
-#line 788 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 221:
+#line 778 "parse.y"
 {
-    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);
+    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);
     }else{
       sqlite3SrcListDelete(pSrc);
     }
-    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);
+    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);
   }
-#line 2811 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2817 "parse.c"
         break;
-      case 221:
-#line 799 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 222:
+#line 789 "parse.y"
 {
-    Expr *p = yygotominor.yy172 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
+    Expr *p = yygotominor.yy450 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
     if( p ){
-      p->pSelect = yymsp[-1].minor.yy219;
+      p->pSelect = yymsp[-1].minor.yy43;
       sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
     }else{
-      sqlite3SelectDelete(yymsp[-1].minor.yy219);
+      sqlite3SelectDelete(yymsp[-1].minor.yy43);
     }
   }
-#line 2824 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2830 "parse.c"
         break;
-      case 222:
-#line 811 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 223:
+#line 801 "parse.y"
 {
-  yygotominor.yy172 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, 0);
-  if( yygotominor.yy172 ){
-    yygotominor.yy172->pList = yymsp[-2].minor.yy174;
+  yygotominor.yy450 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, 0);
+  if( yygotominor.yy450 ){
+    yygotominor.yy450->pList = yymsp[-2].minor.yy242;
   }else{
-    sqlite3ExprListDelete(yymsp[-2].minor.yy174);
+    sqlite3ExprListDelete(yymsp[-2].minor.yy242);
   }
-  sqlite3ExprSpan(yygotominor.yy172, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+  sqlite3ExprSpan(yygotominor.yy450, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
 }
-#line 2837 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 223:
-#line 822 "ext/pdo_sqlite/sqlite/src/parse.y"
-{
-  yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174, yymsp[-2].minor.yy172, 0);
-  yygotominor.yy174 = sqlite3ExprListAppend(yygotominor.yy174, yymsp[0].minor.yy172, 0);
-}
-#line 2845 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2843 "parse.c"
         break;
       case 224:
-#line 826 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 812 "parse.y"
 {
-  yygotominor.yy174 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy172, 0);
-  yygotominor.yy174 = sqlite3ExprListAppend(yygotominor.yy174, yymsp[0].minor.yy172, 0);
+  yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242, yymsp[-2].minor.yy450, 0);
+  yygotominor.yy242 = sqlite3ExprListAppend(yygotominor.yy242, yymsp[0].minor.yy450, 0);
 }
-#line 2853 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2851 "parse.c"
         break;
-      case 233:
-#line 853 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 225:
+#line 816 "parse.y"
 {
-  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);
+  yygotominor.yy242 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy450, 0);
+  yygotominor.yy242 = sqlite3ExprListAppend(yygotominor.yy242, yymsp[0].minor.yy450, 0);
 }
-#line 2861 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2859 "parse.c"
         break;
       case 234:
-      case 279:
-#line 859 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = OE_Abort;}
-#line 2867 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 843 "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);
+}
+#line 2867 "parse.c"
         break;
       case 235:
-#line 860 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = OE_None;}
-#line 2872 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 281:
+#line 849 "parse.y"
+{yygotominor.yy316 = OE_Abort;}
+#line 2873 "parse.c"
         break;
-      case 238:
-#line 870 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 236:
+#line 850 "parse.y"
+{yygotominor.yy316 = OE_None;}
+#line 2878 "parse.c"
+        break;
+      case 239:
+#line 860 "parse.y"
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy410.n>0 ){
+  if( yymsp[-1].minor.yy178.n>0 ){
     p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
-    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n);
+    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy178.z, yymsp[-1].minor.yy178.n);
   }
-  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;
+  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;
 }
-#line 2885 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2891 "parse.c"
         break;
-      case 239:
-#line 879 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 240:
+#line 869 "parse.y"
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy410.n>0 ){
+  if( yymsp[-1].minor.yy178.n>0 ){
     p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
-    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n);
+    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy178.z, yymsp[-1].minor.yy178.n);
   }
-  yygotominor.yy174 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy410);
-  if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
+  yygotominor.yy242 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy178);
+  if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316;
 }
-#line 2898 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 241:
-#line 893 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy373, yymsp[-1].minor.yy46);}
-#line 2903 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2904 "parse.c"
         break;
       case 242:
-      case 243:
-#line 897 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Vacuum(pParse);}
-#line 2909 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 883 "parse.y"
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy419, yymsp[-1].minor.yy316);}
+#line 2909 "parse.c"
         break;
+      case 243:
       case 244:
-      case 246:
-#line 903 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,0);}
-#line 2915 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 888 "parse.y"
+{sqlite3Vacuum(pParse);}
+#line 2915 "parse.c"
         break;
       case 245:
-#line 904 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy0,0);}
-#line 2920 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 895 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy178,0);}
+#line 2920 "parse.c"
+        break;
+      case 246:
+#line 896 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy0,0);}
+#line 2925 "parse.c"
         break;
       case 247:
-#line 906 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 897 "parse.y"
 {
-  sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,1);
+  sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy178,1);
 }
-#line 2927 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2932 "parse.c"
         break;
       case 248:
-#line 909 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-1].minor.yy410,0);}
-#line 2932 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 900 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-4].minor.yy178,&yymsp[-3].minor.yy178,&yymsp[-1].minor.yy178,0);}
+#line 2937 "parse.c"
         break;
       case 249:
-#line 910 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Pragma(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,0,0);}
-#line 2937 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 901 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178,0,0);}
+#line 2942 "parse.c"
         break;
-      case 255:
-#line 922 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 257:
+#line 915 "parse.y"
 {
   Token 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);
+  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);
 }
-#line 2947 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2952 "parse.c"
         break;
-      case 256:
-#line 931 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 258:
+#line 924 "parse.y"
 {
-  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[-1].minor.yy46, yymsp[0].minor.yy172, yymsp[-9].minor.yy46);
-  yygotominor.yy410 = (yymsp[-6].minor.yy410.n==0?yymsp[-7].minor.yy410:yymsp[-6].minor.yy410);
+  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);
 }
-#line 2955 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 257:
-      case 260:
-#line 937 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = TK_BEFORE; }
-#line 2961 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 258:
-#line 938 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = TK_AFTER;  }
-#line 2966 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 2960 "parse.c"
         break;
       case 259:
-#line 939 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = TK_INSTEAD;}
-#line 2971 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 262:
+#line 930 "parse.y"
+{ yygotominor.yy316 = TK_BEFORE; }
+#line 2966 "parse.c"
+        break;
+      case 260:
+#line 931 "parse.y"
+{ yygotominor.yy316 = TK_AFTER;  }
+#line 2971 "parse.c"
         break;
       case 261:
-      case 262:
-#line 944 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy370.a = yymsp[0].major; yygotominor.yy370.b = 0;}
-#line 2977 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 932 "parse.y"
+{ yygotominor.yy316 = TK_INSTEAD;}
+#line 2976 "parse.c"
         break;
       case 263:
-#line 946 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy370.a = TK_UPDATE; yygotominor.yy370.b = yymsp[0].minor.yy432;}
-#line 2982 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
       case 264:
+#line 937 "parse.y"
+{yygotominor.yy354.a = yymsp[0].major; yygotominor.yy354.b = 0;}
+#line 2982 "parse.c"
+        break;
       case 265:
-#line 949 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = TK_ROW; }
-#line 2988 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 939 "parse.y"
+{yygotominor.yy354.a = TK_UPDATE; yygotominor.yy354.b = yymsp[0].minor.yy352;}
+#line 2987 "parse.c"
         break;
       case 266:
-#line 951 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy46 = TK_STATEMENT; }
-#line 2993 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
       case 267:
-#line 955 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy172 = 0; }
-#line 2998 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 942 "parse.y"
+{ yygotominor.yy316 = TK_ROW; }
+#line 2993 "parse.c"
         break;
       case 268:
-#line 956 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy172 = yymsp[0].minor.yy172; }
-#line 3003 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 944 "parse.y"
+{ yygotominor.yy316 = TK_STATEMENT; }
+#line 2998 "parse.c"
         break;
       case 269:
-#line 960 "ext/pdo_sqlite/sqlite/src/parse.y"
-{
-  if( yymsp[-2].minor.yy243 ){
-    yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243;
-  }else{
-    yymsp[-2].minor.yy243 = yymsp[-1].minor.yy243;
-  }
-  yymsp[-2].minor.yy243->pLast = yymsp[-1].minor.yy243;
-  yygotominor.yy243 = yymsp[-2].minor.yy243;
-}
-#line 3016 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 948 "parse.y"
+{ yygotominor.yy450 = 0; }
+#line 3003 "parse.c"
         break;
       case 270:
-#line 969 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy243 = 0; }
-#line 3021 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 949 "parse.y"
+{ yygotominor.yy450 = yymsp[0].minor.yy450; }
+#line 3008 "parse.c"
         break;
       case 271:
-#line 975 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy243 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy410, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); }
-#line 3026 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 953 "parse.y"
+{
+  if( yymsp[-2].minor.yy75 ){
+    yymsp[-2].minor.yy75->pLast->pNext = yymsp[-1].minor.yy75;
+  }else{
+    yymsp[-2].minor.yy75 = yymsp[-1].minor.yy75;
+  }
+  yymsp[-2].minor.yy75->pLast = yymsp[-1].minor.yy75;
+  yygotominor.yy75 = yymsp[-2].minor.yy75;
+}
+#line 3021 "parse.c"
         break;
       case 272:
-#line 980 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy243 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy410, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);}
-#line 3031 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 962 "parse.y"
+{ yygotominor.yy75 = 0; }
+#line 3026 "parse.c"
         break;
       case 273:
-#line 983 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy243 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy410, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);}
-#line 3036 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 968 "parse.y"
+{ yygotominor.yy75 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy178, yymsp[-1].minor.yy242, yymsp[0].minor.yy450, yymsp[-4].minor.yy316); }
+#line 3031 "parse.c"
         break;
       case 274:
-#line 987 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy243 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy410, yymsp[0].minor.yy172);}
-#line 3041 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 973 "parse.y"
+{yygotominor.yy75 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy178, yymsp[-4].minor.yy352, yymsp[-1].minor.yy242, 0, yymsp[-7].minor.yy316);}
+#line 3036 "parse.c"
         break;
       case 275:
-#line 990 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy243 = sqlite3TriggerSelectStep(yymsp[0].minor.yy219); }
-#line 3046 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 976 "parse.y"
+{yygotominor.yy75 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy178, yymsp[-1].minor.yy352, 0, yymsp[0].minor.yy43, yymsp[-4].minor.yy316);}
+#line 3041 "parse.c"
         break;
       case 276:
-#line 993 "ext/pdo_sqlite/sqlite/src/parse.y"
+#line 980 "parse.y"
+{yygotominor.yy75 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy178, yymsp[0].minor.yy450);}
+#line 3046 "parse.c"
+        break;
+      case 277:
+#line 983 "parse.y"
+{yygotominor.yy75 = sqlite3TriggerSelectStep(yymsp[0].minor.yy43); }
+#line 3051 "parse.c"
+        break;
+      case 278:
+#line 986 "parse.y"
 {
-  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);
+  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);
   }
 }
-#line 3057 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3062 "parse.c"
         break;
-      case 277:
-#line 1000 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 279:
+#line 993 "parse.y"
 {
-  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);
+  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);
   }
 }
-#line 3068 "ext/pdo_sqlite/sqlite/src/parse.c"
-        break;
-      case 278:
-#line 1010 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = OE_Rollback;}
-#line 3073 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3073 "parse.c"
         break;
       case 280:
-#line 1012 "ext/pdo_sqlite/sqlite/src/parse.y"
-{yygotominor.yy46 = OE_Fail;}
-#line 3078 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 1003 "parse.y"
+{yygotominor.yy316 = OE_Rollback;}
+#line 3078 "parse.c"
         break;
-      case 281:
-#line 1017 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 282:
+#line 1005 "parse.y"
+{yygotominor.yy316 = OE_Fail;}
+#line 3083 "parse.c"
+        break;
+      case 283:
+#line 1010 "parse.y"
 {
-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy373);
+  sqlite3DropTrigger(pParse,yymsp[0].minor.yy419,yymsp[-1].minor.yy316);
 }
-#line 3085 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3090 "parse.c"
         break;
-      case 282:
-#line 1023 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 284:
+#line 1016 "parse.y"
 {
-  sqlite3Attach(pParse, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, yymsp[0].minor.yy386);
+  sqlite3Attach(pParse, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, yymsp[0].minor.yy158);
 }
-#line 3092 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3097 "parse.c"
         break;
-      case 283:
-#line 1028 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy386 = 0; }
-#line 3097 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 285:
+#line 1021 "parse.y"
+{ yygotominor.yy158 = 0; }
+#line 3102 "parse.c"
         break;
-      case 284:
-#line 1029 "ext/pdo_sqlite/sqlite/src/parse.y"
-{ yygotominor.yy386 = yymsp[0].minor.yy172; }
-#line 3102 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 286:
+#line 1022 "parse.y"
+{ yygotominor.yy158 = yymsp[0].minor.yy450; }
+#line 3107 "parse.c"
         break;
-      case 287:
-#line 1035 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 289:
+#line 1028 "parse.y"
 {
-  sqlite3Detach(pParse, yymsp[0].minor.yy172);
+  sqlite3Detach(pParse, yymsp[0].minor.yy450);
 }
-#line 3109 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3114 "parse.c"
         break;
-      case 288:
-#line 1041 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 290:
+#line 1034 "parse.y"
 {sqlite3Reindex(pParse, 0, 0);}
-#line 3114 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3119 "parse.c"
         break;
-      case 289:
-#line 1042 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Reindex(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
-#line 3119 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 291:
+#line 1035 "parse.y"
+{sqlite3Reindex(pParse, &yymsp[-1].minor.yy178, &yymsp[0].minor.yy178);}
+#line 3124 "parse.c"
         break;
-      case 290:
-#line 1047 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 292:
+#line 1040 "parse.y"
 {sqlite3Analyze(pParse, 0, 0);}
-#line 3124 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3129 "parse.c"
         break;
-      case 291:
-#line 1048 "ext/pdo_sqlite/sqlite/src/parse.y"
-{sqlite3Analyze(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
-#line 3129 "ext/pdo_sqlite/sqlite/src/parse.c"
+      case 293:
+#line 1041 "parse.y"
+{sqlite3Analyze(pParse, &yymsp[-1].minor.yy178, &yymsp[0].minor.yy178);}
+#line 3134 "parse.c"
         break;
-      case 292:
-#line 1053 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 294:
+#line 1046 "parse.y"
 {
-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy410);
+  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy419,&yymsp[0].minor.yy178);
 }
-#line 3136 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3141 "parse.c"
         break;
-      case 293:
-#line 1056 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 295:
+#line 1049 "parse.y"
 {
-  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy410);
+  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy178);
 }
-#line 3143 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3148 "parse.c"
         break;
-      case 294:
-#line 1059 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 296:
+#line 1052 "parse.y"
 {
-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy373);
+  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy419);
 }
-#line 3150 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3155 "parse.c"
         break;
-      case 297:
-#line 1068 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 299:
+#line 1061 "parse.y"
 {sqlite3VtabFinishParse(pParse,0);}
-#line 3155 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3160 "parse.c"
         break;
-      case 298:
-#line 1069 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 300:
+#line 1062 "parse.y"
 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
-#line 3160 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3165 "parse.c"
         break;
-      case 299:
-#line 1070 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 301:
+#line 1063 "parse.y"
 {
-    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, &yymsp[0].minor.yy410);
+    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy178, &yymsp[-2].minor.yy178, &yymsp[0].minor.yy178);
 }
-#line 3167 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3172 "parse.c"
         break;
-      case 302:
-#line 1075 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 304:
+#line 1068 "parse.y"
 {sqlite3VtabArgInit(pParse);}
-#line 3172 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3177 "parse.c"
         break;
-      case 304:
-      case 305:
       case 306:
+      case 307:
       case 308:
-#line 1077 "ext/pdo_sqlite/sqlite/src/parse.y"
+      case 310:
+#line 1070 "parse.y"
 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
-#line 3180 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3185 "parse.c"
         break;
   };
   yygoto = yyRuleInfo[yyruleno].lhs;
@@ -3231,7 +3236,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] ){
@@ -3241,7 +3246,7 @@ static void yy_syntax_error(
     }
     pParse->parseError = 1;
   }
-#line 3248 "ext/pdo_sqlite/sqlite/src/parse.c"
+#line 3253 "parse.c"
   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
 }
 
index 301eb9b8e5cb34af2035a5168f6f6503e2e34cde..479f94b16d2164b7194240630cdf7fcf03ffa952 100644 (file)
@@ -104,7 +104,7 @@ explain ::= .           { sqlite3BeginParse(pParse, 0); }
 %ifndef SQLITE_OMIT_EXPLAIN
 explain ::= EXPLAIN.              { sqlite3BeginParse(pParse, 1); }
 explain ::= EXPLAIN QUERY PLAN.   { sqlite3BeginParse(pParse, 2); }
-%endif
+%endif  SQLITE_OMIT_EXPLAIN
 
 ///////////////////// Begin and end transactions. ////////////////////////////
 //
@@ -134,7 +134,7 @@ ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
 %type temp {int}
 %ifndef SQLITE_OMIT_TEMPDB
 temp(A) ::= TEMP.  {A = 1;}
-%endif
+%endif  SQLITE_OMIT_TEMPDB
 temp(A) ::= .      {A = 0;}
 create_table_args ::= LP columnlist conslist_opt(X) RP(Y). {
   sqlite3EndTable(pParse,&X,&Y,0);
@@ -179,7 +179,7 @@ id(A) ::= ID(X).         {A = X;}
   TEMP TRIGGER VACUUM VIEW VIRTUAL
 %ifdef SQLITE_OMIT_COMPOUND_SELECT
   EXCEPT INTERSECT UNION
-%endif
+%endif SQLITE_OMIT_COMPOUND_SELECT
   REINDEX RENAME CTIME_KW IF
   .
 %wildcard ANY.
@@ -249,14 +249,14 @@ carglist ::= carglist carg.
 carglist ::= .
 carg ::= CONSTRAINT nm ccons.
 carg ::= ccons.
-carg ::= DEFAULT term(X).            {sqlite3AddDefaultValue(pParse,X);}
-carg ::= DEFAULT LP expr(X) RP.      {sqlite3AddDefaultValue(pParse,X);}
-carg ::= DEFAULT PLUS term(X).       {sqlite3AddDefaultValue(pParse,X);}
-carg ::= DEFAULT MINUS term(X).      {
+ccons ::= DEFAULT term(X).            {sqlite3AddDefaultValue(pParse,X);}
+ccons ::= DEFAULT LP expr(X) RP.      {sqlite3AddDefaultValue(pParse,X);}
+ccons ::= DEFAULT PLUS term(X).       {sqlite3AddDefaultValue(pParse,X);}
+ccons ::= DEFAULT MINUS term(X).      {
   Expr *p = sqlite3Expr(TK_UMINUS, X, 0, 0);
   sqlite3AddDefaultValue(pParse,p);
 }
-carg ::= DEFAULT id(X).              {
+ccons ::= DEFAULT id(X).              {
   Expr *p = sqlite3Expr(TK_STRING, 0, 0, &X);
   sqlite3AddDefaultValue(pParse,p);
 }
@@ -355,13 +355,13 @@ ifexists(A) ::= .            {A = 0;}
 ///////////////////// The CREATE VIEW statement /////////////////////////////
 //
 %ifndef SQLITE_OMIT_VIEW
-cmd ::= CREATE(X) temp(T) VIEW nm(Y) dbnm(Z) AS select(S). {
-  sqlite3CreateView(pParse, &X, &Y, &Z, S, T);
+cmd ::= CREATE(X) temp(T) VIEW ifnotexists(E) nm(Y) dbnm(Z) AS select(S). {
+  sqlite3CreateView(pParse, &X, &Y, &Z, S, T, E);
 }
 cmd ::= DROP VIEW ifexists(E) fullname(X). {
   sqlite3DropTable(pParse, X, 1, E);
 }
-%endif // SQLITE_OMIT_VIEW
+%endif  SQLITE_OMIT_VIEW
 
 //////////////////////// The SELECT statement /////////////////////////////////
 //
@@ -388,7 +388,7 @@ select(A) ::= select(X) multiselect_op(Y) oneselect(Z).  {
 multiselect_op(A) ::= UNION(OP).             {A = @OP;}
 multiselect_op(A) ::= UNION ALL.             {A = TK_ALL;}
 multiselect_op(A) ::= EXCEPT|INTERSECT(OP).  {A = @OP;}
-%endif // SQLITE_OMIT_COMPOUND_SELECT
+%endif SQLITE_OMIT_COMPOUND_SELECT
 oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
                  groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
   A = sqlite3SelectNew(W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset);
@@ -444,7 +444,10 @@ as(X) ::= .            {X.n = 0;}
 // A complete FROM clause.
 //
 from(A) ::= .                                 {A = sqliteMalloc(sizeof(*A));}
-from(A) ::= FROM seltablist(X).               {A = X;}
+from(A) ::= FROM seltablist(X).               {
+  A = X;
+  sqlite3SrcListShiftJoinType(A);
+}
 
 // "seltablist" is a "Select Table List" - the content of the FROM clause
 // in a SELECT statement.  "stl_prefix" is a prefix of this list.
@@ -455,31 +458,12 @@ stl_prefix(A) ::= seltablist(X) joinop(Y).    {
 }
 stl_prefix(A) ::= .                           {A = 0;}
 seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
-  A = sqlite3SrcListAppend(X,&Y,&D);
-  if( Z.n ) sqlite3SrcListAddAlias(A,&Z);
-  if( N ){
-    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
-    else { sqlite3ExprDelete(N); }
-  }
-  if( U ){
-    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
-    else { sqlite3IdListDelete(U); }
-  }
+  A = sqlite3SrcListAppendFromTerm(X,&Y,&D,&Z,0,N,U);
 }
 %ifndef SQLITE_OMIT_SUBQUERY
   seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
                     as(Z) on_opt(N) using_opt(U). {
-    A = sqlite3SrcListAppend(X,0,0);
-    if( A && A->nSrc>0 ) A->a[A->nSrc-1].pSelect = S;
-    if( Z.n ) sqlite3SrcListAddAlias(A,&Z);
-    if( N ){
-      if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
-      else { sqlite3ExprDelete(N); }
-    }
-    if( U ){
-      if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
-      else { sqlite3IdListDelete(U); }
-    }
+    A = sqlite3SrcListAppendFromTerm(X,0,0,&Z,S,N,U);
   }
   
   // A seltablist_paren nonterminal represents anything in a FROM that
@@ -490,9 +474,10 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
   %destructor seltablist_paren {sqlite3SelectDelete($$);}
   seltablist_paren(A) ::= select(S).      {A = S;}
   seltablist_paren(A) ::= seltablist(F).  {
+     sqlite3SrcListShiftJoinType(F);
      A = sqlite3SelectNew(0,F,0,0,0,0,0,0,0);
   }
-%endif // SQLITE_OMIT_SUBQUERY
+%endif  SQLITE_OMIT_SUBQUERY
 
 %type dbnm {Token}
 dbnm(A) ::= .          {A.z=0; A.n=0;}
@@ -600,6 +585,8 @@ cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F)
             {sqlite3Insert(pParse, X, Y, 0, F, R);}
 cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S).
             {sqlite3Insert(pParse, X, 0, S, F, R);}
+cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES.
+            {sqlite3Insert(pParse, X, 0, 0, F, R);}
 
 %type insert_cmd {int}
 insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
@@ -660,7 +647,7 @@ expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
   A = sqlite3Expr(TK_CAST, E, 0, &T);
   sqlite3ExprSpan(A,&X,&Y);
 }
-%endif // SQLITE_OMIT_CAST
+%endif  SQLITE_OMIT_CAST
 expr(A) ::= ID(X) LP distinct(D) exprlist(Y) RP(E). {
   A = sqlite3ExprFunction(Y, &X);
   sqlite3ExprSpan(A,&X,&E);
@@ -676,7 +663,10 @@ term(A) ::= CTIME_KW(OP). {
   /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
   ** treated as functions that return constants */
   A = sqlite3ExprFunction(0,&OP);
-  if( A ) A->op = TK_CONST_FUNC;  
+  if( A ){
+    A->op = TK_CONST_FUNC;  
+    A->span = OP;
+  }
 }
 expr(A) ::= expr(X) AND(OP) expr(Y).            {A = sqlite3Expr(@OP, X, Y, 0);}
 expr(A) ::= expr(X) OR(OP) expr(Y).             {A = sqlite3Expr(@OP, X, Y, 0);}
@@ -805,7 +795,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
       sqlite3SelectDelete(Y);
     }
   }
-%endif // SQLITE_OMIT_SUBQUERY
+%endif SQLITE_OMIT_SUBQUERY
 
 /* CASE expressions */
 expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
@@ -894,21 +884,24 @@ cmd ::= DROP INDEX ifexists(E) fullname(X).   {sqlite3DropIndex(pParse, X, E);}
 
 ///////////////////////////// The VACUUM command /////////////////////////////
 //
+%ifndef SQLITE_OMIT_VACUUM
 cmd ::= VACUUM.                {sqlite3Vacuum(pParse);}
 cmd ::= VACUUM nm.             {sqlite3Vacuum(pParse);}
+%endif  SQLITE_OMIT_VACUUM
 
 ///////////////////////////// The PRAGMA command /////////////////////////////
 //
 %ifndef SQLITE_OMIT_PRAGMA
-cmd ::= PRAGMA nm(X) dbnm(Z) EQ nm(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z) EQ nmnum(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
 cmd ::= PRAGMA nm(X) dbnm(Z) EQ ON(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
-cmd ::= PRAGMA nm(X) dbnm(Z) EQ plus_num(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
 cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). {
   sqlite3Pragma(pParse,&X,&Z,&Y,1);
 }
-cmd ::= PRAGMA nm(X) dbnm(Z) LP nm(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z) LP nmnum(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
 cmd ::= PRAGMA nm(X) dbnm(Z).             {sqlite3Pragma(pParse,&X,&Z,0,0);}
-%endif // SQLITE_OMIT_PRAGMA
+nmnum(A) ::= plus_num(X).             {A = X;}
+nmnum(A) ::= nm(X).                   {A = X;}
+%endif SQLITE_OMIT_PRAGMA
 plus_num(A) ::= plus_opt number(X).   {A = X;}
 minus_num(A) ::= MINUS number(X).     {A = X;}
 number(A) ::= INTEGER|FLOAT(X).       {A = X;}
@@ -926,10 +919,10 @@ cmd ::= CREATE trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). {
   sqlite3FinishTrigger(pParse, S, &all);
 }
 
-trigger_decl(A) ::= temp(T) TRIGGER nm(B) dbnm(Z) trigger_time(C)
-                    trigger_event(D)
+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);
+  sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, F, G, T, NOERR);
   A = (Z.n==0?B:Z);
 }
 
@@ -1004,7 +997,7 @@ expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y).  {
     sqlite3ExprSpan(A, &X, &Y);
   }
 }
-%endif // !SQLITE_OMIT_TRIGGER
+%endif  !SQLITE_OMIT_TRIGGER
 
 %type raisetype {int}
 raisetype(A) ::= ROLLBACK.  {A = OE_Rollback;}
@@ -1014,10 +1007,10 @@ raisetype(A) ::= FAIL.      {A = OE_Fail;}
 
 ////////////////////////  DROP TRIGGER statement //////////////////////////////
 %ifndef SQLITE_OMIT_TRIGGER
-cmd ::= DROP TRIGGER fullname(X). {
-  sqlite3DropTrigger(pParse,X);
+cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). {
+  sqlite3DropTrigger(pParse,X,NOERR);
 }
-%endif // !SQLITE_OMIT_TRIGGER
+%endif  !SQLITE_OMIT_TRIGGER
 
 //////////////////////// ATTACH DATABASE file AS name /////////////////////////
 cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). {
@@ -1040,7 +1033,7 @@ cmd ::= DETACH database_kw_opt expr(D). {
 %ifndef SQLITE_OMIT_REINDEX
 cmd ::= REINDEX.                {sqlite3Reindex(pParse, 0, 0);}
 cmd ::= REINDEX nm(X) dbnm(Y).  {sqlite3Reindex(pParse, &X, &Y);}
-%endif
+%endif  SQLITE_OMIT_REINDEX
 
 /////////////////////////////////// ANALYZE ///////////////////////////////////
 %ifndef SQLITE_OMIT_ANALYZE
@@ -1061,7 +1054,7 @@ add_column_fullname ::= fullname(X). {
 }
 kwcolumn_opt ::= .
 kwcolumn_opt ::= COLUMNKW.
-%endif
+%endif  SQLITE_OMIT_ALTERTABLE
 
 //////////////////////// CREATE VIRTUAL TABLE ... /////////////////////////////
 %ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -1079,4 +1072,4 @@ vtabargtoken ::= lp anylist RP(X).  {sqlite3VtabArgExtend(pParse,&X);}
 lp ::= LP(X).                       {sqlite3VtabArgExtend(pParse,&X);}
 anylist ::= .
 anylist ::= anylist ANY(X).         {sqlite3VtabArgExtend(pParse,&X);}
-%endif
+%endif  SQLITE_OMIT_VIRTUALTABLE
index fbcc1adc012989aa41eaea6c47a11e9708bae166..b1c5954de7eb8dfbc5cbfdd5f998a71d009c148a 100644 (file)
@@ -482,12 +482,17 @@ void sqlite3Pragma(
       sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC);
       sqlite3ViewGetColumnNames(pParse, pTab);
       for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
+        const Token *pDflt;
         sqlite3VdbeAddOp(v, OP_Integer, i, 0);
         sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0);
         sqlite3VdbeOp3(v, OP_String8, 0, 0,
            pCol->zType ? pCol->zType : "", 0);
         sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0);
-        sqlite3ExprCode(pParse, pCol->pDflt);
+        if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){
+          sqlite3VdbeOp3(v, OP_String8, 0, 0, (char*)pDflt->z, pDflt->n);
+        }else{
+          sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+        }
         sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0);
         sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
       }
@@ -635,9 +640,13 @@ void sqlite3Pragma(
     }
   }else
 
+#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
+# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
+#endif
+
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
   if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
-    int i, j, addr;
+    int i, j, addr, mxErr;
 
     /* Code that appears at the end of the integrity check.  If no error
     ** messages have been generated, output OK.  Otherwise output the
@@ -655,7 +664,16 @@ void sqlite3Pragma(
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     sqlite3VdbeSetNumCols(v, 1);
     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC);
-    sqlite3VdbeAddOp(v, OP_MemInt, 0, 0);  /* Initialize error count to 0 */
+
+    /* Set the maximum error count */
+    mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
+    if( zRight ){
+      mxErr = atoi(zRight);
+      if( mxErr<=0 ){
+        mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
+      }
+    }
+    sqlite3VdbeAddOp(v, OP_MemInt, mxErr, 0);
 
     /* Do an integrity check on each database file */
     for(i=0; i<db->nDb; i++){
@@ -666,6 +684,9 @@ void sqlite3Pragma(
       if( OMIT_TEMPDB && i==1 ) continue;
 
       sqlite3CodeVerifySchema(pParse, i);
+      addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0);
+      sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
+      sqlite3VdbeJumpHere(v, addr);
 
       /* Do an integrity check of the B-Tree
       */
@@ -680,28 +701,28 @@ void sqlite3Pragma(
           cnt++;
         }
       }
-      assert( cnt>0 );
-      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
-      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
-      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
-      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+7);
+      if( cnt==0 ) continue;
+      sqlite3VdbeAddOp(v, OP_IntegrityCk, 0, i);
+      addr = sqlite3VdbeAddOp(v, OP_IsNull, -1, 0);
       sqlite3VdbeOp3(v, OP_String8, 0, 0,
          sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
          P3_DYNAMIC);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-      sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
+      sqlite3VdbeAddOp(v, OP_Concat, 0, 0);
       sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
-      sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
+      sqlite3VdbeJumpHere(v, addr);
 
       /* Make sure all the indices are constructed correctly.
       */
-      sqlite3CodeVerifySchema(pParse, i);
       for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
         Table *pTab = sqliteHashData(x);
         Index *pIdx;
         int loopTop;
 
         if( pTab->pIndex==0 ) continue;
+        addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0);
+        sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
+        sqlite3VdbeJumpHere(v, addr);
         sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
         sqlite3VdbeAddOp(v, OP_MemInt, 0, 1);
         loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
@@ -709,7 +730,7 @@ void sqlite3Pragma(
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
           int jmp2;
           static const VdbeOpList idxErr[] = {
-            { OP_MemIncr,     1,  0,  0},
+            { OP_MemIncr,    -1,  0,  0},
             { OP_String8,     0,  0,  "rowid "},
             { OP_Rowid,       1,  0,  0},
             { OP_String8,     0,  0,  " missing from index "},
@@ -734,13 +755,16 @@ void sqlite3Pragma(
              { OP_MemLoad,      1,  0,  0},
              { OP_MemLoad,      2,  0,  0},
              { OP_Eq,           0,  0,  0},  /* 6 */
-             { OP_MemIncr,      1,  0,  0},
+             { OP_MemIncr,     -1,  0,  0},
              { OP_String8,      0,  0,  "wrong # of entries in index "},
              { OP_String8,      0,  0,  0},  /* 9 */
              { OP_Concat,       0,  0,  0},
              { OP_Callback,     1,  0,  0},
           };
           if( pIdx->tnum==0 ) continue;
+          addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0);
+          sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
+          sqlite3VdbeJumpHere(v, addr);
           addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
           sqlite3VdbeChangeP1(v, addr+1, j+2);
           sqlite3VdbeChangeP2(v, addr+1, addr+4);
@@ -752,6 +776,7 @@ void sqlite3Pragma(
       } 
     }
     addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
+    sqlite3VdbeChangeP1(v, addr+1, mxErr);
     sqlite3VdbeJumpHere(v, addr+2);
   }else
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -889,6 +914,7 @@ void sqlite3Pragma(
       sqlite3VdbeChangeP1(v, addr, iDb);
       sqlite3VdbeChangeP2(v, addr, iCookie);
       sqlite3VdbeSetNumCols(v, 1);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P3_TRANSIENT);
     }
   }
 #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
@@ -940,6 +966,22 @@ void sqlite3Pragma(
     sqlite3_key(db, zRight, strlen(zRight));
   }else
 #endif
+#if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD)
+  if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
+#if SQLITE_HAS_CODEC
+    if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
+      extern void sqlite3_activate_see(const char*);
+      sqlite3_activate_see(&zRight[4]);
+    }
+#endif
+#ifdef SQLITE_ENABLE_CEROD
+    if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
+      extern void sqlite3_activate_cerod(const char*);
+      sqlite3_activate_cerod(&zRight[6]);
+    }
+#endif
+  }
+#endif
 
   {}
 
index 0eae2598896dbc567edc64d86247f80eb072bff0..e584f789af4d037fbe31ecde7449289e12dac8ee 100644 (file)
@@ -41,28 +41,26 @@ static void corruptSchema(InitData *pData, const char *zExtra){
 **     argv[0] = name of thing being created
 **     argv[1] = root page number for table or index. 0 for trigger or view.
 **     argv[2] = SQL text for the CREATE statement.
-**     argv[3] = "1" for temporary files, "0" for main database, "2" or more
-**               for auxiliary database files.
 **
 */
 int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
   InitData *pData = (InitData*)pInit;
   sqlite3 *db = pData->db;
-  int iDb;
+  int iDb = pData->iDb;
 
   pData->rc = SQLITE_OK;
+  DbClearProperty(db, iDb, DB_Empty);
   if( sqlite3MallocFailed() ){
     corruptSchema(pData, 0);
     return SQLITE_NOMEM;
   }
 
-  assert( argc==4 );
+  assert( argc==3 );
   if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
-  if( argv[1]==0 || argv[3]==0 ){
+  if( argv[1]==0 ){
     corruptSchema(pData, 0);
     return 1;
   }
-  iDb = atoi(argv[3]);
   assert( iDb>=0 && iDb<db->nDb );
   if( argv[2] && argv[2][0] ){
     /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
@@ -125,8 +123,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   int size;
   Table *pTab;
   Db *pDb;
-  char const *azArg[5];
-  char zDbNum[30];
+  char const *azArg[4];
   int meta[10];
   InitData initData;
   char const *zMasterSchema;
@@ -177,12 +174,11 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   azArg[0] = zMasterName;
   azArg[1] = "1";
   azArg[2] = zMasterSchema;
-  sprintf(zDbNum, "%d", iDb);
-  azArg[3] = zDbNum;
-  azArg[4] = 0;
+  azArg[3] = 0;
   initData.db = db;
+  initData.iDb = iDb;
   initData.pzErrMsg = pzErrMsg;
-  rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
+  rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
   if( rc ){
     sqlite3SafetyOn(db);
     return initData.rc;
@@ -295,8 +291,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   }else{
     char *zSql;
     zSql = sqlite3MPrintf(
-        "SELECT name, rootpage, sql, '%s' FROM '%q'.%s",
-        zDbNum, db->aDb[iDb].zName, zMasterName);
+        "SELECT name, rootpage, sql FROM '%q'.%s",
+        db->aDb[iDb].zName, zMasterName);
     sqlite3SafetyOff(db);
     rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
     if( rc==SQLITE_ABORT ) rc = initData.rc;
@@ -449,12 +445,13 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
 /*
 ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
 */
-int sqlite3_prepare(
+int sqlite3Prepare(
   sqlite3 *db,              /* Database handle. */
   const char *zSql,         /* UTF-8 encoded SQL statement. */
   int nBytes,               /* Length of zSql in bytes. */
+  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
   sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
-  const char** pzTail       /* OUT: End of parsed string */
+  const char **pzTail       /* OUT: End of parsed string */
 ){
   Parse sParse;
   char *zErrMsg = 0;
@@ -507,7 +504,9 @@ int sqlite3_prepare(
   if( sqlite3MallocFailed() ){
     sParse.rc = SQLITE_NOMEM;
   }
-  if( pzTail ) *pzTail = sParse.zTail;
+  if( pzTail ){
+    *pzTail = sParse.zTail;
+  }
   rc = sParse.rc;
 
 #ifndef SQLITE_OMIT_EXPLAIN
@@ -525,13 +524,16 @@ int sqlite3_prepare(
       sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC);
       sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC);
     }
-  } 
+  }
 #endif
 
   if( sqlite3SafetyOff(db) ){
     rc = SQLITE_MISUSE;
   }
   if( rc==SQLITE_OK ){
+    if( saveSqlFlag ){
+      sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql);
+    }
     *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
   }else if( sParse.pVdbe ){
     sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
@@ -546,17 +548,78 @@ int sqlite3_prepare(
 
   rc = sqlite3ApiExit(db, rc);
   sqlite3ReleaseThreadData();
+  assert( (rc&db->errMask)==rc );
   return rc;
 }
 
+/*
+** Rerun the compilation of a statement after a schema change.
+** Return true if the statement was recompiled successfully.
+** Return false if there is an error of some kind.
+*/
+int sqlite3Reprepare(Vdbe *p){
+  int rc;
+  Vdbe *pNew;
+  const char *zSql;
+  sqlite3 *db;
+  
+  zSql = sqlite3VdbeGetSql(p);
+  if( zSql==0 ){
+    return 0;
+  }
+  db = sqlite3VdbeDb(p);
+  rc = sqlite3Prepare(db, zSql, -1, 0, (sqlite3_stmt**)&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);
+  return 1;
+}
+
+
+/*
+** Two versions of the official API.  Legacy and new use.  In the legacy
+** version, the original SQL text is not saved in the prepared statement
+** and so if a schema change occurs, SQLITE_SCHEMA is returned by
+** sqlite3_step().  In the new version, the original SQL text is retained
+** and the statement is automatically recompiled if an schema change
+** occurs.
+*/
+int sqlite3_prepare(
+  sqlite3 *db,              /* Database handle. */
+  const char *zSql,         /* UTF-8 encoded SQL statement. */
+  int nBytes,               /* Length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+  const char **pzTail       /* OUT: End of parsed string */
+){
+  return sqlite3Prepare(db,zSql,nBytes,0,ppStmt,pzTail);
+}
+int sqlite3_prepare_v2(
+  sqlite3 *db,              /* Database handle. */
+  const char *zSql,         /* UTF-8 encoded SQL statement. */
+  int nBytes,               /* Length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+  const char **pzTail       /* OUT: End of parsed string */
+){
+  return sqlite3Prepare(db,zSql,nBytes,1,ppStmt,pzTail);
+}
+
+
 #ifndef SQLITE_OMIT_UTF16
 /*
 ** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
 */
-int sqlite3_prepare16(
+static int sqlite3Prepare16(
   sqlite3 *db,              /* Database handle. */ 
   const void *zSql,         /* UTF-8 encoded SQL statement. */
   int nBytes,               /* Length of zSql in bytes. */
+  int saveSqlFlag,          /* True to save SQL text into the sqlite3_stmt */
   sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
   const void **pzTail       /* OUT: End of parsed string */
 ){
@@ -573,7 +636,7 @@ int sqlite3_prepare16(
   }
   zSql8 = sqlite3utf16to8(zSql, nBytes);
   if( zSql8 ){
-    rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);
+    rc = sqlite3Prepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8);
   }
 
   if( zTail8 && pzTail ){
@@ -588,4 +651,32 @@ int sqlite3_prepare16(
   sqliteFree(zSql8); 
   return sqlite3ApiExit(db, rc);
 }
+
+/*
+** Two versions of the official API.  Legacy and new use.  In the legacy
+** version, the original SQL text is not saved in the prepared statement
+** and so if a schema change occurs, SQLITE_SCHEMA is returned by
+** sqlite3_step().  In the new version, the original SQL text is retained
+** and the statement is automatically recompiled if an schema change
+** occurs.
+*/
+int sqlite3_prepare16(
+  sqlite3 *db,              /* Database handle. */ 
+  const void *zSql,         /* UTF-8 encoded SQL statement. */
+  int nBytes,               /* Length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+  const void **pzTail       /* OUT: End of parsed string */
+){
+  return sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail);
+}
+int sqlite3_prepare16_v2(
+  sqlite3 *db,              /* Database handle. */ 
+  const void *zSql,         /* UTF-8 encoded SQL statement. */
+  int nBytes,               /* Length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
+  const void **pzTail       /* OUT: End of parsed string */
+){
+  return sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail);
+}
+
 #endif /* SQLITE_OMIT_UTF16 */
index b4c37fb61de51a8918ae202b5c31cacfcc29776a..a05fec21f634f0a92ef669460f5f4346a07ad318 100644 (file)
@@ -857,7 +857,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
   va_start(ap, zFormat);
   base_vprintf(0, 0, zBuf, sizeof(zBuf), zFormat, ap);
   va_end(ap);
-  fprintf(stdout,"%d: %s", getpid(), zBuf);
+  fprintf(stdout,"%s", zBuf);
   fflush(stdout);
 }
 #endif
index 51d5d72e77827874b99a228c84d8b8d6cf0b27a3..5adc84aaf42b8155597570ac72e1409c9becffb6 100644 (file)
@@ -37,7 +37,7 @@
 ** (Later):  Actually, OP_NewRowid does not depend on a good source of
 ** randomness any more.  But we will leave this code in all the same.
 */
-static int randomByte(){
+static int randomByte(void){
   unsigned char t;
 
   /* All threads share a single random number generator.
index 57b415bf58b63a93f45871ae7787159c958748c4..9fda4c8bf3cdd7b31c97f90722d78e1b733a53f8 100644 (file)
@@ -299,8 +299,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
     /* When the NATURAL keyword is present, add WHERE clause terms for
     ** every column that the two tables have in common.
     */
-    if( pLeft->jointype & JT_NATURAL ){
-      if( pLeft->pOn || pLeft->pUsing ){
+    if( pRight->jointype & JT_NATURAL ){
+      if( pRight->pOn || pRight->pUsing ){
         sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
            "an ON or USING clause", 0);
         return 1;
@@ -318,7 +318,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
 
     /* Disallow both ON and USING clauses in the same join
     */
-    if( pLeft->pOn && pLeft->pUsing ){
+    if( pRight->pOn && pRight->pUsing ){
       sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
         "clauses in the same join");
       return 1;
@@ -327,10 +327,10 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
     /* Add the ON clause to the end of the WHERE clause, connected by
     ** an AND operator.
     */
-    if( pLeft->pOn ){
-      setJoinExpr(pLeft->pOn, pRight->iCursor);
-      p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn);
-      pLeft->pOn = 0;
+    if( pRight->pOn ){
+      setJoinExpr(pRight->pOn, pRight->iCursor);
+      p->pWhere = sqlite3ExprAnd(p->pWhere, pRight->pOn);
+      pRight->pOn = 0;
     }
 
     /* Create extra terms on the WHERE clause for each column named
@@ -340,8 +340,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
     ** Report an error if any column mentioned in the USING clause is
     ** not contained in both tables to be joined.
     */
-    if( pLeft->pUsing ){
-      IdList *pList = pLeft->pUsing;
+    if( pRight->pUsing ){
+      IdList *pList = pRight->pUsing;
       for(j=0; j<pList->nId; j++){
         char *zName = pList->a[j].zName;
         if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
@@ -1069,7 +1069,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
     Expr *p, *pR;
     char *zType;
     char *zName;
-    char *zBasename;
+    int nName;
     CollSeq *pColl;
     int cnt;
     NameContext sNC;
@@ -1102,17 +1102,15 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
     /* Make sure the column name is unique.  If the name is not unique,
     ** append a integer to the name so that it becomes unique.
     */
-    zBasename = zName;
+    nName = strlen(zName);
     for(j=cnt=0; j<i; j++){
       if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
-        zName = sqlite3MPrintf("%s:%d", zBasename, ++cnt);
+        zName[nName] = 0;
+        zName = sqlite3MPrintf("%z:%d", zName, ++cnt);
         j = -1;
         if( zName==0 ) break;
       }
     }
-    if( zBasename!=zName ){
-      sqliteFree(zBasename);
-    }
     pCol->zName = zName;
 
     /* Get the typename, type affinity, and collating sequence for the
@@ -1309,13 +1307,13 @@ static int prepSelectStmt(Parse *pParse, Select *p){
 
             if( i>0 ){
               struct SrcList_item *pLeft = &pTabList->a[i-1];
-              if( (pLeft->jointype & JT_NATURAL)!=0 &&
+              if( (pLeft[1].jointype & JT_NATURAL)!=0 &&
                         columnIndex(pLeft->pTab, zName)>=0 ){
                 /* In a NATURAL join, omit the join columns from the 
                 ** table on the right */
                 continue;
               }
-              if( sqlite3IdListIndex(pLeft->pUsing, zName)>=0 ){
+              if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){
                 /* In a join with a USING clause, omit columns in the
                 ** using clause from the table on the right. */
                 continue;
@@ -1936,6 +1934,7 @@ static int multiSelect(
         }
         sqlite3VdbeChangeP2(v, addr, nCol);
         sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO);
+        pLoop->addrOpenEphm[i] = -1;
       }
     }
 
@@ -2175,7 +2174,7 @@ static int flattenSubquery(
   **
   ** which is not at all the same thing.
   */
-  if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){
+  if( pSubSrc->nSrc>1 && (pSubitem->jointype & JT_OUTER)!=0 ){
     return 0;
   }
 
@@ -2192,8 +2191,7 @@ static int flattenSubquery(
   ** But the t2.x>0 test will always fail on a NULL row of t2, which
   ** effectively converts the OUTER JOIN into an INNER JOIN.
   */
-  if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 
-      && pSub->pWhere!=0 ){
+  if( (pSubitem->jointype & JT_OUTER)!=0 && pSub->pWhere!=0 ){
     return 0;
   }
 
@@ -2232,7 +2230,7 @@ static int flattenSubquery(
       pSrc->a[i+iFrom] = pSubSrc->a[i];
       memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
     }
-    pSrc->a[iFrom+nSubSrc-1].jointype = jointype;
+    pSrc->a[iFrom].jointype = jointype;
   }
 
   /* Now begin substituting subquery result set expressions for 
@@ -2605,7 +2603,14 @@ int sqlite3SelectResolve(
     }
   }
 
-  return SQLITE_OK;
+  /* If this is one SELECT of a compound, be sure to resolve names
+  ** in the other SELECTs.
+  */
+  if( p->pPrior ){
+    return sqlite3SelectResolve(pParse, p->pPrior, pOuterNC);
+  }else{
+    return SQLITE_OK;
+  }
 }
 
 /*
@@ -3293,3 +3298,99 @@ select_end:
   sqliteFree(sAggInfo.aFunc);
   return rc;
 }
+
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+/*
+*******************************************************************************
+** The following code is used for testing and debugging only.  The code
+** that follows does not appear in normal builds.
+**
+** These routines are used to print out the content of all or part of a 
+** parse structures such as Select or Expr.  Such printouts are useful
+** for helping to understand what is happening inside the code generator
+** during the execution of complex SELECT statements.
+**
+** These routine are not called anywhere from within the normal
+** code base.  Then are intended to be called from within the debugger
+** or from temporary "printf" statements inserted for debugging.
+*/
+void sqlite3PrintExpr(Expr *p){
+  if( p->token.z && p->token.n>0 ){
+    sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z);
+  }else{
+    sqlite3DebugPrintf("(%d", p->op);
+  }
+  if( p->pLeft ){
+    sqlite3DebugPrintf(" ");
+    sqlite3PrintExpr(p->pLeft);
+  }
+  if( p->pRight ){
+    sqlite3DebugPrintf(" ");
+    sqlite3PrintExpr(p->pRight);
+  }
+  sqlite3DebugPrintf(")");
+}
+void sqlite3PrintExprList(ExprList *pList){
+  int i;
+  for(i=0; i<pList->nExpr; i++){
+    sqlite3PrintExpr(pList->a[i].pExpr);
+    if( i<pList->nExpr-1 ){
+      sqlite3DebugPrintf(", ");
+    }
+  }
+}
+void sqlite3PrintSelect(Select *p, int indent){
+  sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p);
+  sqlite3PrintExprList(p->pEList);
+  sqlite3DebugPrintf("\n");
+  if( p->pSrc ){
+    char *zPrefix;
+    int i;
+    zPrefix = "FROM";
+    for(i=0; i<p->pSrc->nSrc; i++){
+      struct SrcList_item *pItem = &p->pSrc->a[i];
+      sqlite3DebugPrintf("%*s ", indent+6, zPrefix);
+      zPrefix = "";
+      if( pItem->pSelect ){
+        sqlite3DebugPrintf("(\n");
+        sqlite3PrintSelect(pItem->pSelect, indent+10);
+        sqlite3DebugPrintf("%*s)", indent+8, "");
+      }else if( pItem->zName ){
+        sqlite3DebugPrintf("%s", pItem->zName);
+      }
+      if( pItem->pTab ){
+        sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName);
+      }
+      if( pItem->zAlias ){
+        sqlite3DebugPrintf(" AS %s", pItem->zAlias);
+      }
+      if( i<p->pSrc->nSrc-1 ){
+        sqlite3DebugPrintf(",");
+      }
+      sqlite3DebugPrintf("\n");
+    }
+  }
+  if( p->pWhere ){
+    sqlite3DebugPrintf("%*s WHERE ", indent, "");
+    sqlite3PrintExpr(p->pWhere);
+    sqlite3DebugPrintf("\n");
+  }
+  if( p->pGroupBy ){
+    sqlite3DebugPrintf("%*s GROUP BY ", indent, "");
+    sqlite3PrintExprList(p->pGroupBy);
+    sqlite3DebugPrintf("\n");
+  }
+  if( p->pHaving ){
+    sqlite3DebugPrintf("%*s HAVING ", indent, "");
+    sqlite3PrintExpr(p->pHaving);
+    sqlite3DebugPrintf("\n");
+  }
+  if( p->pOrderBy ){
+    sqlite3DebugPrintf("%*s ORDER BY ", indent, "");
+    sqlite3PrintExprList(p->pOrderBy);
+    sqlite3DebugPrintf("\n");
+  }
+}
+/* End of the structure debug printing code
+*****************************************************************************/
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
index 6058bc195ebdc21262298d8c456f7a4660d52791..0cf75e2046122a8dc0b4ebaf9f6d6dd03f5f46ab 100644 (file)
 # define stifle_history(X)
 #endif
 
+#if defined(_WIN32) || defined(WIN32)
+# include <io.h>
+#else
 /* Make sure isatty() has a prototype.
 */
 extern int isatty();
+#endif
+
+/*
+** If the following flag is set, then command execution stops
+** at an error if we are not interactive.
+*/
+static int bail_on_error = 0;
+
+/*
+** Threat stdin as an interactive input if the following variable
+** is true.  Otherwise, assume stdin is connected to a file or pipe.
+*/
+static int stdin_is_interactive = 1;
 
 /*
 ** The following is the open SQLite database.  We make a pointer
@@ -180,10 +196,7 @@ static char *local_getline(char *zPrompt, FILE *in){
 }
 
 /*
-** Retrieve a single line of input text.  "isatty" is true if text
-** is coming from a terminal.  In that case, we issue a prompt and
-** attempt to use "readline" for command-line editing.  If "isatty"
-** is false, use "local_getline" instead of "readline" and issue no prompt.
+** Retrieve a single line of input text.
 **
 ** zPrior is a string of prior text retrieved.  If not the empty
 ** string, then issue a continuation prompt.
@@ -212,6 +225,7 @@ struct previous_mode_data {
   int showHeader;
   int colWidth[100];
 };
+
 /*
 ** An pointer to an instance of this structure is passed from
 ** the main program to the callback.  This is used to communicate
@@ -223,6 +237,7 @@ struct callback_data {
   int cnt;               /* Number of records displayed so far */
   FILE *out;             /* Write results here */
   int mode;              /* An output mode setting */
+  int writableSchema;    /* True if PRAGMA writable_schema=ON */
   int showHeader;        /* True to show column names in List or Column mode */
   char *zDestTable;      /* Name of destination table when MODE_Insert */
   char separator[20];    /* Separator character for MODE_List */
@@ -235,7 +250,6 @@ struct callback_data {
                          ** .explain ON */
   char outfile[FILENAME_MAX]; /* Filename for *out */
   const char *zDbFilename;    /* name of the database file */
-  char *zKey;                 /* Encryption key */
 };
 
 /*
@@ -347,6 +361,29 @@ static void output_html_string(FILE *out, const char *z){
   }
 }
 
+/*
+** If a field contains any character identified by a 1 in the following
+** array, then the string must be quoted for CSV.
+*/
+static const char needCsvQuote[] = {
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1, 
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,   
+};
+
 /*
 ** Output a single term of CSV.  Actually, p->separator is used for
 ** the separator, which may or may not be a comma.  p->nullvalue is
@@ -354,12 +391,27 @@ static void output_html_string(FILE *out, const char *z){
 ** appear outside of quotes.
 */
 static void output_csv(struct callback_data *p, const char *z, int bSep){
+  FILE *out = p->out;
   if( z==0 ){
-    fprintf(p->out,"%s",p->nullvalue);
-  }else if( isNumber(z, 0) ){
-    fprintf(p->out,"%s",z);
+    fprintf(out,"%s",p->nullvalue);
   }else{
-    output_c_string(p->out, z);
+    int i;
+    for(i=0; z[i]; i++){
+      if( needCsvQuote[((unsigned char*)z)[i]] ){
+        i = 0;
+        break;
+      }
+    }
+    if( i==0 ){
+      putc('"', out);
+      for(i=0; z[i]; i++){
+        if( z[i]=='"' ) putc('"', out);
+        putc(z[i], out);
+      }
+      putc('"', out);
+    }else{
+      fprintf(out, "%s", z);
+    }
   }
   if( bSep ){
     fprintf(p->out, p->separator);
@@ -584,7 +636,7 @@ static void set_table_name(struct callback_data *p, const char *zName){
 ** If the third argument, quote, is not '\0', then it is used as a 
 ** quote character for zAppend.
 */
-static char * appendText(char *zIn, char const *zAppend, char quote){
+static char *appendText(char *zIn, char const *zAppend, char quote){
   int len;
   int i;
   int nAppend = strlen(zAppend);
@@ -625,6 +677,9 @@ static char * appendText(char *zIn, char const *zAppend, char quote){
 /*
 ** Execute a query statement that has a single result column.  Print
 ** that result column on a line by itself with a semicolon terminator.
+**
+** This is used, for example, to show the schema of the database by
+** querying the SQLITE_MASTER table.
 */
 static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
   sqlite3_stmt *pSelect;
@@ -666,6 +721,19 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
     fprintf(p->out, "ANALYZE sqlite_master;\n");
   }else if( strncmp(zTable, "sqlite_", 7)==0 ){
     return 0;
+  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
+    char *zIns;
+    if( !p->writableSchema ){
+      fprintf(p->out, "PRAGMA writable_schema=ON;\n");
+      p->writableSchema = 1;
+    }
+    zIns = sqlite3_mprintf(
+       "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
+       "VALUES('table','%q','%q',0,'%q');",
+       zTable, zTable, zSql);
+    fprintf(p->out, "%s\n", zIns);
+    sqlite3_free(zIns);
+    return 0;
   }else{
     fprintf(p->out, "%s;\n", zSql);
   }
@@ -699,7 +767,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
       zSelect = appendText(zSelect, zText, '"');
       rc = sqlite3_step(pTableInfo);
       if( rc==SQLITE_ROW ){
-        zSelect = appendText(zSelect, ") || ', ' || ", 0);
+        zSelect = appendText(zSelect, ") || ',' || ", 0);
       }else{
         zSelect = appendText(zSelect, ") ", 0);
       }
@@ -718,15 +786,14 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
       rc = run_table_dump_query(p->out, p->db, zSelect);
     }
     if( zSelect ) free(zSelect);
-    if( rc!=SQLITE_OK ){
-      return 1;
-    }
   }
   return 0;
 }
 
 /*
-** Run zQuery.  Update dump_callback() as the callback routine.
+** Run zQuery.  Use dump_callback() as the callback routine so that
+** the contents of the query are output as SQL statements.
+**
 ** If we get a SQLITE_CORRUPT error, rerun the query after appending
 ** "ORDER BY rowid DESC" to the end.
 */
@@ -754,6 +821,7 @@ static int run_schema_dump_query(
 ** Text of a help message
 */
 static char zHelp[] =
+  ".bail ON|OFF           Stop after hitting an error.  Default OFF\n"
   ".databases             List names and files of attached databases\n"
   ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
   ".echo ON|OFF           Turn command echo on or off\n"
@@ -790,7 +858,7 @@ static char zHelp[] =
 ;
 
 /* Forward reference */
-static void process_input(struct callback_data *p, FILE *in);
+static int process_input(struct callback_data *p, FILE *in);
 
 /*
 ** Make sure the database is open.  If it is not, then open it.  If
@@ -850,11 +918,28 @@ static void resolve_backslashes(char *z){
   z[j] = 0;
 }
 
+/*
+** Interpret zArg as a boolean value.  Return either 0 or 1.
+*/
+static int booleanValue(char *zArg){
+  int val = atoi(zArg);
+  int j;
+  for(j=0; zArg[j]; j++){
+    zArg[j] = tolower(zArg[j]);
+  }
+  if( strcmp(zArg,"on")==0 ){
+    val = 1;
+  }else if( strcmp(zArg,"yes")==0 ){
+    val = 1;
+  }
+  return val;
+}
+
 /*
 ** If an input line begins with "." then invoke this routine to
 ** process that line.
 **
-** Return 1 to exit and 0 to continue.
+** Return 1 on error, 2 to exit, and 0 otherwise.
 */
 static int do_meta_command(char *zLine, struct callback_data *p){
   int i = 1;
@@ -889,6 +974,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
   if( nArg==0 ) return rc;
   n = strlen(azArg[0]);
   c = azArg[0][0];
+  if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
+    bail_on_error = booleanValue(azArg[1]);
+  }else
+
   if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
     struct callback_data data;
     char *zErrMsg = 0;
@@ -911,14 +1000,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     char *zErrMsg = 0;
     open_db(p);
     fprintf(p->out, "BEGIN TRANSACTION;\n");
+    p->writableSchema = 0;
     if( nArg==1 ){
       run_schema_dump_query(p, 
         "SELECT name, type, sql FROM sqlite_master "
         "WHERE sql NOT NULL AND type=='table'", 0
       );
-      run_schema_dump_query(p, 
-        "SELECT name, type, sql FROM sqlite_master "
-        "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0
+      run_table_dump_query(p->out, p->db,
+        "SELECT sql FROM sqlite_master "
+        "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
       );
     }else{
       int i;
@@ -928,13 +1018,19 @@ static int do_meta_command(char *zLine, struct callback_data *p){
           "SELECT name, type, sql FROM sqlite_master "
           "WHERE tbl_name LIKE shellstatic() AND type=='table'"
           "  AND sql NOT NULL", 0);
-        run_schema_dump_query(p,
-          "SELECT name, type, sql FROM sqlite_master "
-          "WHERE tbl_name LIKE shellstatic() AND type!='table'"
-          "  AND type!='meta' AND sql NOT NULL", 0);
+        run_table_dump_query(p->out, p->db,
+          "SELECT sql FROM sqlite_master "
+          "WHERE sql NOT NULL"
+          "  AND type IN ('index','trigger','view')"
+          "  AND tbl_name LIKE shellstatic()"
+        );
         zShellStatic = 0;
       }
     }
+    if( p->writableSchema ){
+      fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
+      p->writableSchema = 0;
+    }
     if( zErrMsg ){
       fprintf(stderr,"Error: %s\n", zErrMsg);
       sqlite3_free(zErrMsg);
@@ -944,37 +1040,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){
   }else
 
   if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
-    int j;
-    char *z = azArg[1];
-    int val = atoi(azArg[1]);
-    for(j=0; z[j]; j++){
-      z[j] = tolower((unsigned char)z[j]);
-    }
-    if( strcmp(z,"on")==0 ){
-      val = 1;
-    }else if( strcmp(z,"yes")==0 ){
-      val = 1;
-    }
-    p->echoOn = val;
+    p->echoOn = booleanValue(azArg[1]);
   }else
 
   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
-    rc = 1;
+    rc = 2;
   }else
 
   if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
-    int j;
-    static char zOne[] = "1";
-    char *z = nArg>=2 ? azArg[1] : zOne;
-    int val = atoi(z);
-    for(j=0; z[j]; j++){
-      z[j] = tolower((unsigned char)z[j]);
-    }
-    if( strcmp(z,"on")==0 ){
-      val = 1;
-    }else if( strcmp(z,"yes")==0 ){
-      val = 1;
-    }
+    int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
     if(val == 1) {
       if(!p->explainPrev.valid) {
         p->explainPrev.valid = 1;
@@ -1005,21 +1079,9 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='h' && (strncmp(azArg[0], "header", n)==0
-                 ||
+  if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
                  strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
-    int j;
-    char *z = azArg[1];
-    int val = atoi(azArg[1]);
-    for(j=0; z[j]; j++){
-      z[j] = tolower((unsigned char)z[j]);
-    }
-    if( strcmp(z,"on")==0 ){
-      val = 1;
-    }else if( strcmp(z,"yes")==0 ){
-      val = 1;
-    }
-    p->showHeader = val;
+    p->showHeader = booleanValue(azArg[1]);
   }else
 
   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
@@ -1056,6 +1118,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     if( rc ){
       fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
       nCol = 0;
+      rc = 1;
     }else{
       nCol = sqlite3_column_count(pStmt);
     }
@@ -1076,7 +1139,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     if( rc ){
       fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
       sqlite3_finalize(pStmt);
-      return 0;
+      return 1;
     }
     in = fopen(zFile, "rb");
     if( in==0 ){
@@ -1122,6 +1185,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
       if( rc!=SQLITE_OK ){
         fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
         zCommit = "ROLLBACK";
+        rc = 1;
         break;
       }
     }
@@ -1167,6 +1231,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     if( rc!=SQLITE_OK ){
       fprintf(stderr, "%s\n", zErrMsg);
       sqlite3_free(zErrMsg);
+      rc = 1;
     }
   }else
 #endif
@@ -1201,7 +1266,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
         set_table_name(p, "table");
       }
     }else {
-      fprintf(stderr,"mode should be on of: "
+      fprintf(stderr,"mode should be one of: "
          "column csv html insert line list tabs tcl\n");
     }
   }else
@@ -1238,7 +1303,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
   }else
 
   if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
-    rc = 1;
+    rc = 2;
   }else
 
   if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
@@ -1390,6 +1455,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
         }
         printf("\n");
       }
+    }else{
+      rc = 1;
     }
     sqlite3_free_table(azResult);
   }else
@@ -1469,24 +1536,40 @@ static int _is_command_terminator(const char *zLine){
 ** is coming from a file or device.  A prompt is issued and history
 ** is saved only if input is interactive.  An interrupt signal will
 ** cause this routine to exit immediately, unless input is interactive.
+**
+** Return the number of errors.
 */
-static void process_input(struct callback_data *p, FILE *in){
+static int process_input(struct callback_data *p, FILE *in){
   char *zLine;
   char *zSql = 0;
   int nSql = 0;
   char *zErrMsg;
   int rc;
-  while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){
+  int errCnt = 0;
+  int lineno = 0;
+  int startline = 0;
+
+  while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
+    fflush(p->out);
+    zLine = one_input_line(zSql, in);
+    if( zLine==0 ){
+      break;  /* We have reached EOF */
+    }
     if( seenInterrupt ){
       if( in!=0 ) break;
       seenInterrupt = 0;
     }
+    lineno++;
     if( p->echoOn ) printf("%s\n", zLine);
     if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
     if( zLine && zLine[0]=='.' && nSql==0 ){
-      int rc = do_meta_command(zLine, p);
+      rc = do_meta_command(zLine, p);
       free(zLine);
-      if( rc ) break;
+      if( rc==2 ){
+        break;
+      }else if( rc ){
+        errCnt++;
+      }
       continue;
     }
     if( _is_command_terminator(zLine) ){
@@ -1503,6 +1586,7 @@ static void process_input(struct callback_data *p, FILE *in){
           exit(1);
         }
         strcpy(zSql, zLine);
+        startline = lineno;
       }
     }else{
       int len = strlen(zLine);
@@ -1521,14 +1605,20 @@ static void process_input(struct callback_data *p, FILE *in){
       open_db(p);
       rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
       if( rc || zErrMsg ){
-        /* if( in!=0 && !p->echoOn ) printf("%s\n",zSql); */
+        char zPrefix[100];
+        if( in!=0 || !stdin_is_interactive ){
+          sprintf(zPrefix, "SQL error near line %d:", startline);
+        }else{
+          sprintf(zPrefix, "SQL error:");
+        }
         if( zErrMsg!=0 ){
-          printf("SQL error: %s\n", zErrMsg);
+          printf("%s %s\n", zPrefix, zErrMsg);
           sqlite3_free(zErrMsg);
           zErrMsg = 0;
         }else{
-          printf("SQL error: %s\n", sqlite3_errmsg(p->db));
+          printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
         }
+        errCnt++;
       }
       free(zSql);
       zSql = 0;
@@ -1539,6 +1629,7 @@ static void process_input(struct callback_data *p, FILE *in){
     if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
     free(zSql);
   }
+  return errCnt;
 }
 
 /*
@@ -1563,16 +1654,30 @@ static char *find_home_dir(void){
   home_dir = getcwd(home_path, _MAX_PATH);
 #endif
 
+#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
+  if (!home_dir) {
+    home_dir = getenv("USERPROFILE");
+  }
+#endif
+
   if (!home_dir) {
     home_dir = getenv("HOME");
-    if (!home_dir) {
-      home_dir = getenv("HOMEPATH"); /* Windows? */
-    }
   }
 
 #if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
   if (!home_dir) {
-    home_dir = "c:";
+    char *zDrive, *zPath;
+    int n;
+    zDrive = getenv("HOMEDRIVE");
+    zPath = getenv("HOMEPATH");
+    if( zDrive && zPath ){
+      n = strlen(zDrive) + strlen(zPath) + 1;
+      home_dir = malloc( n );
+      if( home_dir==0 ) return 0;
+      sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
+      return home_dir;
+    }
+    home_dir = "c:\\";
   }
 #endif
 
@@ -1615,7 +1720,7 @@ static void process_sqliterc(
   }
   in = fopen(sqliterc,"rb");
   if( in ){
-    if( isatty(fileno(stdout)) ){
+    if( stdin_is_interactive ){
       printf("Loading resources from %s\n",sqliterc);
     }
     process_input(p,in);
@@ -1632,19 +1737,25 @@ static const char zOptions[] =
   "   -init filename       read/process named file\n"
   "   -echo                print commands before execution\n"
   "   -[no]header          turn headers on or off\n"
+  "   -bail                stop after hitting an error\n"
+  "   -interactive         force interactive I/O\n"
+  "   -batch               force batch I/O\n"
   "   -column              set output mode to 'column'\n"
+  "   -csv                 set output mode to 'csv'\n"
   "   -html                set output mode to HTML\n"
   "   -line                set output mode to 'line'\n"
   "   -list                set output mode to 'list'\n"
   "   -separator 'x'       set output field separator (|)\n"
   "   -nullvalue 'text'    set text string for NULL values\n"
   "   -version             show SQLite version\n"
-  "   -help                show this text, also show dot-commands\n"
 ;
 static void usage(int showDetail){
-  fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0);
+  fprintf(stderr,
+      "Usage: %s [OPTIONS] FILENAME [SQL]\n"  
+      "FILENAME is the name of an SQLite database. A new database is created\n"
+      "if the file does not previously exist.\n", Argv0);
   if( showDetail ){
-    fprintf(stderr, "Options are:\n%s", zOptions);
+    fprintf(stderr, "OPTIONS include:\n%s", zOptions);
   }else{
     fprintf(stderr, "Use the -help option for additional information\n");
   }
@@ -1669,6 +1780,7 @@ int main(int argc, char **argv){
   const char *zInitFile = 0;
   char *zFirstCmd = 0;
   int i;
+  int rc = 0;
 
 #ifdef __MACOS__
   argc = ccommand(&argv);
@@ -1676,6 +1788,7 @@ int main(int argc, char **argv){
 
   Argv0 = argv[0];
   main_init(&data);
+  stdin_is_interactive = isatty(0);
 
   /* Make sure we have a valid signal handler early, before anything
   ** else is done.
@@ -1689,15 +1802,15 @@ int main(int argc, char **argv){
   ** and the first command to execute.
   */
   for(i=1; i<argc-1; i++){
+    char *z;
     if( argv[i][0]!='-' ) break;
+    z = argv[i];
+    if( z[0]=='-' && z[1]=='-' ) z++;
     if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
       i++;
     }else if( strcmp(argv[i],"-init")==0 ){
       i++;
       zInitFile = argv[i];
-    }else if( strcmp(argv[i],"-key")==0 ){
-      i++;
-      data.zKey = sqlite3_mprintf("%s",argv[i]);
     }
   }
   if( i<argc ){
@@ -1743,7 +1856,8 @@ int main(int argc, char **argv){
   */
   for(i=1; i<argc && argv[i][0]=='-'; i++){
     char *z = argv[i];
-    if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){
+    if( z[1]=='-' ){ z++; }
+    if( strcmp(z,"-init")==0 ){
       i++;
     }else if( strcmp(z,"-html")==0 ){
       data.mode = MODE_Html;
@@ -1753,6 +1867,9 @@ int main(int argc, char **argv){
       data.mode = MODE_Line;
     }else if( strcmp(z,"-column")==0 ){
       data.mode = MODE_Column;
+    }else if( strcmp(z,"-csv")==0 ){
+      data.mode = MODE_Csv;
+      strcpy(data.separator,",");
     }else if( strcmp(z,"-separator")==0 ){
       i++;
       sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);
@@ -1765,10 +1882,16 @@ int main(int argc, char **argv){
       data.showHeader = 0;
     }else if( strcmp(z,"-echo")==0 ){
       data.echoOn = 1;
+    }else if( strcmp(z,"-bail")==0 ){
+      bail_on_error = 1;
     }else if( strcmp(z,"-version")==0 ){
       printf("%s\n", sqlite3_libversion());
       return 0;
-    }else if( strcmp(z,"-help")==0 ){
+    }else if( strcmp(z,"-interactive")==0 ){
+      stdin_is_interactive = 1;
+    }else if( strcmp(z,"-batch")==0 ){
+      stdin_is_interactive = 0;
+    }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
       usage(1);
     }else{
       fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
@@ -1795,7 +1918,7 @@ int main(int argc, char **argv){
   }else{
     /* Run commands received from standard input
     */
-    if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){
+    if( stdin_is_interactive ){
       char *zHome;
       char *zHistory = 0;
       printf(
@@ -1810,7 +1933,7 @@ int main(int argc, char **argv){
 #if defined(HAVE_READLINE) && HAVE_READLINE==1
       if( zHistory ) read_history(zHistory);
 #endif
-      process_input(&data, 0);
+      rc = process_input(&data, 0);
       if( zHistory ){
         stifle_history(100);
         write_history(zHistory);
@@ -1818,7 +1941,7 @@ int main(int argc, char **argv){
       }
       free(zHome);
     }else{
-      process_input(&data, stdin);
+      rc = process_input(&data, stdin);
     }
   }
   set_table_name(&data, 0);
@@ -1827,5 +1950,5 @@ int main(int argc, char **argv){
       fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
     }
   }
-  return 0;
+  return rc;
 }
index a1b4759f84741e7217a24abb14a4e4216eb3a382..9c80edfc21f4f393b927bfd781119afe2dcb2d6b 100644 (file)
@@ -125,7 +125,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 ** value then the query is aborted, all subsequent SQL statements
 ** are skipped and the sqlite3_exec() function returns the SQLITE_ABORT.
 **
-** The 4th parameter is an arbitrary pointer that is passed
+** The 1st parameter is an arbitrary pointer that is passed
 ** to the callback function as its first parameter.
 **
 ** The 2nd parameter to the callback function is the number of
@@ -198,6 +198,44 @@ int sqlite3_exec(
 #define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
 /* end-of-error-codes */
 
+/*
+** Using the sqlite3_extended_result_codes() API, you can cause
+** SQLite to return result codes with additional information in
+** their upper bits.  The lower 8 bits will be the same as the
+** primary result codes above.  But the upper bits might contain
+** more specific error information.
+**
+** To extract the primary result code from an extended result code,
+** simply mask off the lower 8 bits.
+**
+**        primary = extended & 0xff;
+**
+** New result error codes may be added from time to time.  Software
+** that uses the extended result codes should plan accordingly and be
+** sure to always handle new unknown codes gracefully.
+**
+** The SQLITE_OK result code will never be extended.  It will always
+** be exactly zero.
+**
+** The extended result codes always have the primary result code
+** as a prefix.  Primary result codes only contain a single "_"
+** character.  Extended result codes contain two or more "_" characters.
+*/
+#define SQLITE_IOERR_READ          (SQLITE_IOERR | (1<<8))
+#define SQLITE_IOERR_SHORT_READ    (SQLITE_IOERR | (2<<8))
+#define SQLITE_IOERR_WRITE         (SQLITE_IOERR | (3<<8))
+#define SQLITE_IOERR_FSYNC         (SQLITE_IOERR | (4<<8))
+#define SQLITE_IOERR_DIR_FSYNC     (SQLITE_IOERR | (5<<8))
+#define SQLITE_IOERR_TRUNCATE      (SQLITE_IOERR | (6<<8))
+#define SQLITE_IOERR_FSTAT         (SQLITE_IOERR | (7<<8))
+#define SQLITE_IOERR_UNLOCK        (SQLITE_IOERR | (8<<8))
+#define SQLITE_IOERR_RDLOCK        (SQLITE_IOERR | (9<<8))
+
+/*
+** Enable or disable the extended result codes.
+*/
+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,
@@ -277,13 +315,30 @@ int sqlite3_complete16(const void *sql);
 ** currently locked by another process or thread.  If the busy callback
 ** is NULL, then sqlite3_exec() returns SQLITE_BUSY immediately if
 ** it finds a locked table.  If the busy callback is not NULL, then
-** sqlite3_exec() invokes the callback with three arguments.  The
-** second argument is the name of the locked table and the third
-** argument is the number of times the table has been busy.  If the
+** sqlite3_exec() invokes the callback with two arguments.  The
+** first argument to the handler is a copy of the void* pointer which
+** is the third argument to this routine.  The second argument to
+** the handler is the number of times that the busy handler has
+** been invoked for this locking event.  If the
 ** busy callback returns 0, then sqlite3_exec() immediately returns
 ** SQLITE_BUSY.  If the callback returns non-zero, then sqlite3_exec()
 ** tries to open the table again and the cycle repeats.
 **
+** The presence of a busy handler does not guarantee that
+** it will be invoked when there is lock contention.
+** If SQLite determines that invoking the busy handler could result in
+** a deadlock, it will return SQLITE_BUSY instead.
+** Consider a scenario where one process is holding a read lock that
+** it is trying to promote to a reserved lock and
+** a second process is holding a reserved lock that it is trying
+** to promote to an exclusive lock.  The first process cannot proceed
+** because it is blocked by the second and the second process cannot
+** proceed because it is blocked by the first.  If both processes
+** invoke the busy handlers, neither will make any progress.  Therefore,
+** SQLite returns SQLITE_BUSY for the first process, hoping that this
+** will induce the first process to release its read lock and allow
+** the second process to proceed.
+**
 ** The default busy callback is NULL.
 **
 ** Sqlite is re-entrant, so the busy handler may start a new query. 
@@ -478,6 +533,7 @@ int sqlite3_set_authorizer(
 #define SQLITE_ANALYZE              28   /* Table Name      NULL            */
 #define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
 #define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
+#define SQLITE_FUNCTION             31   /* Function Name   NULL            */
 
 /*
 ** The return value of the authorization function should be one of the
@@ -653,6 +709,31 @@ int sqlite3_prepare16(
   const void **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
 
+/*
+** Newer versions of the prepare API work just like the legacy versions
+** but with one exception:  The a copy of the SQL text is saved in the
+** sqlite3_stmt structure that is returned.  If this copy exists, it
+** modifieds the behavior of sqlite3_step() slightly.  First, sqlite3_step()
+** will no longer return an SQLITE_SCHEMA error but will instead automatically
+** rerun the compiler to rebuild the prepared statement.  Secondly, 
+** sqlite3_step() now turns a full result code - the result code that
+** use used to have to call sqlite3_reset() to get.
+*/
+int sqlite3_prepare_v2(
+  sqlite3 *db,            /* Database handle */
+  const char *zSql,       /* SQL statement, UTF-8 encoded */
+  int nBytes,             /* Length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+int sqlite3_prepare16_v2(
+  sqlite3 *db,            /* Database handle */
+  const void *zSql,       /* SQL statement, UTF-16 encoded */
+  int nBytes,             /* Length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+
 /*
 ** Pointers to the following two opaque structures are used to communicate
 ** with the implementations of user-defined functions.
@@ -1104,9 +1185,13 @@ void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
 ** SQLITE_TRANSIENT value means that the content will likely change in
 ** the near future and that SQLite should make its own private copy of
 ** the content before returning.
+**
+** The typedef is necessary to work around problems in certain
+** C++ compilers.  See ticket #2191.
 */
-#define SQLITE_STATIC      ((void(*)(void *))0)
-#define SQLITE_TRANSIENT   ((void(*)(void *))-1)
+typedef void (*sqlite3_destructor_type)(void*);
+#define SQLITE_STATIC      ((sqlite3_destructor_type)0)
+#define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)
 
 /*
 ** User-defined functions invoke the following routines in order to
@@ -1517,6 +1602,42 @@ int sqlite3_load_extension(
 */
 int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
+/*
+****** EXPERIMENTAL - subject to change without notice **************
+**
+** Register an extension entry point that is automatically invoked
+** whenever a new database connection is opened.
+**
+** This API can be invoked at program startup in order to register
+** one or more statically linked extensions that will be available
+** to all new database connections.
+**
+** Duplicate extensions are detected so calling this routine multiple
+** times with the same extension is harmless.
+**
+** This routine stores a pointer to the extension in an array
+** that is obtained from malloc().  If you run a memory leak
+** checker on your program and it reports a leak because of this
+** array, then invoke sqlite3_automatic_extension_reset() prior
+** to shutdown to free the memory.
+**
+** Automatic extensions apply across all threads.
+*/
+int sqlite3_auto_extension(void *xEntryPoint);
+
+
+/*
+****** EXPERIMENTAL - subject to change without notice **************
+**
+** Disable all previously registered automatic extensions.  This
+** routine undoes the effect of all prior sqlite3_automatic_extension()
+** calls.
+**
+** This call disabled automatic extensions in all threads.
+*/
+void sqlite3_reset_auto_extension(void);
+
+
 /*
 ****** EXPERIMENTAL - subject to change without notice **************
 **
@@ -1544,11 +1665,11 @@ typedef struct sqlite3_module sqlite3_module;
 struct sqlite3_module {
   int iVersion;
   int (*xCreate)(sqlite3*, void *pAux,
-               int argc, char **argv,
-               sqlite3_vtab **ppVTab);
+               int argc, const char *const*argv,
+               sqlite3_vtab **ppVTab, char**);
   int (*xConnect)(sqlite3*, void *pAux,
-               int argc, char **argv,
-               sqlite3_vtab **ppVTab);
+               int argc, const char *const*argv,
+               sqlite3_vtab **ppVTab, char**);
   int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
   int (*xDisconnect)(sqlite3_vtab *pVTab);
   int (*xDestroy)(sqlite3_vtab *pVTab);
@@ -1668,10 +1789,21 @@ int sqlite3_create_module(
 ** be taylored to the specific needs of the module implementation.   The
 ** purpose of this superclass is to define certain fields that are common
 ** to all module implementations.
+**
+** Virtual tables methods can set an error message by assigning a
+** string obtained from sqlite3_mprintf() to zErrMsg.  The method should
+** take care that any prior string is freed by a call to sqlite3_free()
+** prior to assigning a new string to zErrMsg.  After the error message
+** is delivered up to the client application, the string will be automatically
+** freed by sqlite3_free() and the zErrMsg field will be zeroed.  Note
+** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field
+** since virtual tables are commonly implemented in loadable extensions which
+** do not have access to sqlite3MPrintf() or sqlite3Free().
 */
 struct sqlite3_vtab {
   const sqlite3_module *pModule;  /* The module for this virtual table */
   int nRef;                       /* Used internally */
+  char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
   /* Virtual table implementations will typically add additional fields */
 };
 
@@ -1696,6 +1828,24 @@ struct sqlite3_vtab_cursor {
 */
 int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable);
 
+/*
+** Virtual tables can provide alternative implementations of functions
+** using the xFindFunction method.  But global versions of those functions
+** must exist in order to be overloaded.
+**
+** This API makes sure a global version of a function with a particular
+** name and number of parameters exists.  If no such function exists
+** before this API is called, a new function is created.  The implementation
+** of the new function always causes an exception to be thrown.  So
+** the new function is not good for anything by itself.  Its only
+** purpose is to be a place-holder function that can be overloaded
+** by virtual tables.
+**
+** This API should be considered part of the virtual table interface,
+** which is experimental and subject to change.
+*/
+int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+
 /*
 ** The interface to the virtual-table mechanism defined above (back up
 ** to a comment remarkably similar to this one) is currently considered
index 9b3dae74077ea00284ae47a9f8c43ed86ebead6e..1df21d6aa9beb5d4b30bee236dc468e0f844afe1 100644 (file)
@@ -19,7 +19,7 @@
 */
 #ifndef _SQLITE3EXT_H_
 #define _SQLITE3EXT_H_
-#include <sqlite3.h>
+#include "sqlite3.h"
 
 typedef struct sqlite3_api_routines sqlite3_api_routines;
 
@@ -92,7 +92,7 @@ struct sqlite3_api_routines {
   void * (*get_auxdata)(sqlite3_context*,int);
   int  (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
   int  (*global_recover)(void);
-  void  (*interrupt)(sqlite3*);
+  void  (*interruptx)(sqlite3*);
   sqlite_int64  (*last_insert_rowid)(sqlite3*);
   const char * (*libversion)(void);
   int  (*libversion_number)(void);
@@ -143,6 +143,7 @@ struct sqlite3_api_routines {
   const void * (*value_text16le)(sqlite3_value*);
   int  (*value_type)(sqlite3_value*);
   char * (*vmprintf)(const char*,va_list);
+  int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
 };
 
 /*
@@ -221,7 +222,7 @@ struct sqlite3_api_routines {
 #define sqlite3_get_auxdata            sqlite3_api->get_auxdata
 #define sqlite3_get_table              sqlite3_api->get_table
 #define sqlite3_global_recover         sqlite3_api->global_recover
-#define sqlite3_interrupt              sqlite3_api->interrupt
+#define sqlite3_interrupt              sqlite3_api->interruptx
 #define sqlite3_last_insert_rowid      sqlite3_api->last_insert_rowid
 #define sqlite3_libversion             sqlite3_api->libversion
 #define sqlite3_libversion_number      sqlite3_api->libversion_number
@@ -272,6 +273,7 @@ struct sqlite3_api_routines {
 #define sqlite3_value_text16le         sqlite3_api->value_text16le
 #define sqlite3_value_type             sqlite3_api->value_type
 #define sqlite3_vmprintf               sqlite3_api->vmprintf
+#define sqlite3_overload_function      sqlite3_api->overload_function
 #endif /* SQLITE_CORE */
 
 #define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api;
index 58e21c4f3cb1cf87f4de04c9a68588da22c65e11..0f6dfd04f568a18eaa127391d9d4d88b6770a863 100644 (file)
@@ -447,6 +447,7 @@ struct sqlite3 {
   Db *aDb;                      /* All backends */
   int flags;                    /* Miscellanous flags. See below */
   int errCode;                  /* Most recent error code (SQLITE_*) */
+  int errMask;                  /* & result codes with this before returning */
   u8 autoCommit;                /* The auto-commit flag. */
   u8 temp_store;                /* 1: file 2: memory 0: default */
   int nTable;                   /* Number of tables in the database */
@@ -462,7 +463,7 @@ struct sqlite3 {
     u8 busy;                    /* TRUE if currently initializing */
   } init;
   int nExtension;               /* Number of loaded extensions */
-  void *aExtension;             /* Array of shared libraray handles */
+  void **aExtension;            /* Array of shared libraray handles */
   struct Vdbe *pVdbe;           /* List of active virtual machines */
   int activeVdbeCnt;            /* Number of vdbes currently executing */
   void (*xTrace)(void*,const char*);        /* Trace function */
@@ -1090,6 +1091,11 @@ typedef unsigned int Bitmask;
 ** is modified by an INSERT, DELETE, or UPDATE statement.  In standard SQL,
 ** such a table must be a simple name: ID.  But in SQLite, the table can
 ** now be identified by a database name, a dot, then the table name: ID.ID.
+**
+** The jointype starts out showing the join type between the current table
+** and the next table on the list.  The parser builds the list this way.
+** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each
+** jointype expresses the join between the table and the previous table.
 */
 struct SrcList {
   i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
@@ -1101,7 +1107,7 @@ struct SrcList {
     Table *pTab;      /* An SQL table corresponding to zName */
     Select *pSelect;  /* A SELECT statement used in place of a table name */
     u8 isPopulated;   /* Temporary table associated with SELECT is populated */
-    u8 jointype;      /* Type of join between this table and the next */
+    u8 jointype;      /* Type of join between this able and the previous */
     i16 iCursor;      /* The VDBE cursor number used to access this table */
     Expr *pOn;        /* The ON clause of a join */
     IdList *pUsing;   /* The USING clause of a join */
@@ -1512,6 +1518,7 @@ struct DbFixer {
 */
 typedef struct {
   sqlite3 *db;        /* The database being initialized */
+  int iDb;            /* 0 for main database.  1 for TEMP, 2.. for ATTACHed */
   char **pzErrMsg;    /* Error message stored here */
   int rc;             /* Result code stored here */
 } InitData;
@@ -1600,7 +1607,7 @@ void sqlite3AddDefaultValue(Parse*,Expr*);
 void sqlite3AddCollateType(Parse*, const char*, int);
 void sqlite3EndTable(Parse*,Token*,Token*,Select*);
 
-void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int);
+void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
 
 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
   int sqlite3ViewGetColumnNames(Parse*,Table*);
@@ -1615,7 +1622,9 @@ int sqlite3ArrayAllocate(void**,int,int);
 IdList *sqlite3IdListAppend(IdList*, Token*);
 int sqlite3IdListIndex(IdList*,const char*);
 SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
-void sqlite3SrcListAddAlias(SrcList*, Token*);
+SrcList *sqlite3SrcListAppendFromTerm(SrcList*, Token*, Token*, Token*,
+                                      Select*, Expr*, IdList*);
+void sqlite3SrcListShiftJoinType(SrcList*);
 void sqlite3SrcListAssignCursors(Parse*, SrcList*);
 void sqlite3IdListDelete(IdList*);
 void sqlite3SrcListDelete(SrcList*);
@@ -1691,9 +1700,9 @@ 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*);
+  void sqlite3DropTrigger(Parse*, SrcList*, int);
   void sqlite3DropTriggerPtr(Parse*, Trigger*);
   int sqlite3TriggersExist(Parse*, Table*, int, ExprList*);
   int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, 
@@ -1821,8 +1830,10 @@ int sqlite3OpenTempDatabase(Parse *);
 
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
   void sqlite3CloseExtensions(sqlite3*);
+  int sqlite3AutoLoadExtensions(sqlite3*);
 #else
 # define sqlite3CloseExtensions(X)
+# define sqlite3AutoLoadExtensions(X)  SQLITE_OK
 #endif
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
@@ -1860,6 +1871,8 @@ int sqlite3OpenTempDatabase(Parse *);
    int sqlite3VtabRollback(sqlite3 *db);
    int sqlite3VtabCommit(sqlite3 *db);
 #endif
+void sqlite3VtabLock(sqlite3_vtab*);
+void sqlite3VtabUnlock(sqlite3_vtab*);
 void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
 void sqlite3VtabFinishParse(Parse*, Token*);
 void sqlite3VtabArgInit(Parse*);
@@ -1869,6 +1882,8 @@ int sqlite3VtabCallConnect(Parse*, Table*);
 int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
 int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *);
 FuncDef *sqlite3VtabOverloadFunction(FuncDef*, int nArg, Expr*);
+void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
+int sqlite3Reprepare(Vdbe*);
 
 #ifdef SQLITE_SSE
 #include "sseInt.h"
index c4e228361fbd95ed7fa50e67003ffea1002f3a59..30c14848989ac54cf6048f2b0c23a10c2d92dacd 100644 (file)
@@ -146,7 +146,7 @@ int sqlite3_get_table(
     assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
     res.azResult[0] = (char*)res.nData;
   }
-  if( rc==SQLITE_ABORT ){
+  if( (rc&0xff)==SQLITE_ABORT ){
     sqlite3_free_table(&res.azResult[1]);
     if( res.zErrMsg ){
       if( pzErrMsg ){
@@ -156,12 +156,12 @@ int sqlite3_get_table(
       sqliteFree(res.zErrMsg);
     }
     db->errCode = res.rc;
-    return res.rc;
+    return res.rc & db->errMask;
   }
   sqliteFree(res.zErrMsg);
   if( rc!=SQLITE_OK ){
     sqlite3_free_table(&res.azResult[1]);
-    return rc;
+    return rc & db->errMask;
   }
   if( res.nAlloc>res.nData ){
     char **azNew;
@@ -176,7 +176,7 @@ int sqlite3_get_table(
   *pazResult = &res.azResult[1];
   if( pnColumn ) *pnColumn = res.nColumn;
   if( pnRow ) *pnRow = res.nRow;
-  return rc;
+  return rc & db->errMask;
 }
 
 /*
index 8572b7cf657763970478ece92c870d198d67cb90..2f33307c93c1015b6962f4c0a3ad684acedcaa62 100644 (file)
@@ -553,6 +553,7 @@ static int auth_callback(
     case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
     case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;
     case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;
+    case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break;
     default                       : zCode="????"; break;
   }
   Tcl_DStringInit(&str);
@@ -1035,7 +1036,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     nSep = strlen(zSep);
     nNull = strlen(zNull);
     if( nSep==0 ){
-      Tcl_AppendResult(interp, "Error: non-null separator required for copy", 0);
+      Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);
       return TCL_ERROR;
     }
     if(sqlite3StrICmp(zConflict, "rollback") != 0 &&
@@ -1172,6 +1173,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   ** default.
   */
   case DB_ENABLE_LOAD_EXTENSION: {
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
     int onoff;
     if( objc!=3 ){
       Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
@@ -1182,6 +1184,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     }
     sqlite3_enable_load_extension(pDb->db, onoff);
     break;
+#else
+    Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
+                     0);
+    return TCL_ERROR;
+#endif
   }
 
   /*
@@ -2001,6 +2008,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   const char *zArg;
   char *zErrMsg;
   const char *zFile;
+  Tcl_DString translatedFilename;
   if( objc==2 ){
     zArg = Tcl_GetStringFromObj(objv[1], 0);
     if( strcmp(zArg,"-version")==0 ){
@@ -2049,9 +2057,11 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   }
   memset(p, 0, sizeof(*p));
   zFile = Tcl_GetStringFromObj(objv[2], 0);
+  zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
   sqlite3_open(zFile, &p->db);
+  Tcl_DStringFree(&translatedFilename);
   if( SQLITE_OK!=sqlite3_errcode(p->db) ){
-    zErrMsg = strdup(sqlite3_errmsg(p->db));
+    zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
     sqlite3_close(p->db);
     p->db = 0;
   }
@@ -2061,10 +2071,11 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   if( p->db==0 ){
     Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
     Tcl_Free((char*)p);
-    free(zErrMsg);
+    sqlite3_free(zErrMsg);
     return TCL_ERROR;
   }
   p->maxStmt = NUM_PREPARED_STMTS;
+  p->interp = interp;
   zArg = Tcl_GetStringFromObj(objv[1], 0);
   Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
 
@@ -2084,7 +2095,6 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
 #endif
   }
 #endif  
-  p->interp = interp;
   return TCL_OK;
 }
 
@@ -2200,6 +2210,7 @@ int TCLSH_MAIN(int argc, char **argv){
     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*);
 
     Sqlitetest1_Init(interp);
     Sqlitetest2_Init(interp);
@@ -2212,6 +2223,7 @@ int TCLSH_MAIN(int argc, char **argv){
     Sqlitetestasync_Init(interp);
     Sqlitetesttclvar_Init(interp);
     Sqlitetestschema_Init(interp);
+    Sqlitetest_autoext_Init(interp);
     Md5_Init(interp);
 #ifdef SQLITE_SSE
     Sqlitetestsse_Init(interp);
@@ -2220,6 +2232,9 @@ int TCLSH_MAIN(int argc, char **argv){
 #endif
   if( argc>=2 || TCLSH==2 ){
     int i;
+    char zArgc[32];
+    sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
+    Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
     Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
     Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
     for(i=3-TCLSH; i<argc; i++){
index fd474b276356237c914daaa0de7950c121ef6934..7402956dd3b2390c5b7de8c029a592328552550e 100644 (file)
@@ -63,9 +63,25 @@ static int get_sqlite_pointer(
   return TCL_OK;
 }
 
+/*
+** Decode a pointer to an sqlite3 object.
+*/
+static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
+  struct SqliteDb *p;
+  Tcl_CmdInfo cmdInfo;
+  if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){
+    p = (struct SqliteDb*)cmdInfo.objClientData;
+    *ppDb = p->db;
+  }else{
+    *ppDb = (sqlite3*)sqlite3TextToPtr(zA);
+  }
+  return TCL_OK;
+}
+
+
 const char *sqlite3TestErrorName(int rc){
   const char *zName = 0;
-  switch( rc ){
+  switch( rc & 0xff ){
     case SQLITE_OK:         zName = "SQLITE_OK";          break;
     case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
     case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
@@ -121,14 +137,6 @@ int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
   return 0;
 }
 
-/*
-** Decode a pointer to an sqlite3 object.
-*/
-static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
-  *ppDb = (sqlite3*)sqlite3TextToPtr(zA);
-  return TCL_OK;
-}
-
 /*
 ** Decode a pointer to an sqlite3_stmt object.
 */
@@ -227,6 +235,65 @@ static int test_exec_printf(
   return TCL_OK;
 }
 
+/*
+** Usage:  sqlite3_exec  DB  SQL
+**
+** Invoke the sqlite3_exec interface using the open database DB
+*/
+static int test_exec(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  char **argv            /* Text of each argument */
+){
+  sqlite3 *db;
+  Tcl_DString str;
+  int rc;
+  char *zErr = 0;
+  char zBuf[30];
+  if( argc!=3 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
+       " DB SQL", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
+  Tcl_DStringInit(&str);
+  rc = sqlite3_exec(db, argv[2], exec_printf_cb, &str, &zErr);
+  sprintf(zBuf, "%d", rc);
+  Tcl_AppendElement(interp, zBuf);
+  Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
+  Tcl_DStringFree(&str);
+  if( zErr ) sqlite3_free(zErr);
+  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
+  return TCL_OK;
+}
+
+/*
+** Usage:  sqlite3_exec_nr  DB  SQL
+**
+** Invoke the sqlite3_exec interface using the open database DB.  Discard
+** all results
+*/
+static int test_exec_nr(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  char **argv            /* Text of each argument */
+){
+  sqlite3 *db;
+  int rc;
+  char *zErr = 0;
+  if( argc!=3 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
+       " DB SQL", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
+  rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
+  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
+  return TCL_OK;
+}
+
 /*
 ** Usage:  sqlite3_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...
 **
@@ -442,6 +509,34 @@ static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
   }
 }
 
+/*
+** These are test functions.    hex8() interprets its argument as
+** UTF8 and returns a hex encoding.  hex16le() interprets its argument
+** as UTF16le and returns a hex encoding.
+*/
+static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){
+  const unsigned char *z;
+  int i;
+  char zBuf[200];
+  z = sqlite3_value_text(argv[0]);
+  for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){
+    sprintf(&zBuf[i*2], "%02x", z[i]&0xff);
+  }
+  zBuf[i*2] = 0;
+  sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
+}
+static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){
+  const unsigned short int *z;
+  int i;
+  char zBuf[400];
+  z = sqlite3_value_text16(argv[0]);
+  for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){
+    sprintf(&zBuf[i*4], "%04x", z[i]&0xff);
+  }
+  zBuf[i*4] = 0;
+  sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
+}
+
 /*
 ** A structure into which to accumulate text.
 */
@@ -548,6 +643,14 @@ 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);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_create_function(db, "hex8", 1, SQLITE_ANY, 0, 
+          hex8Func, 0, 0);
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, 0, 
+          hex16Func, 0, 0);
+  }
 
 #ifndef SQLITE_OMIT_UTF16
   /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
@@ -657,6 +760,30 @@ static int test_create_aggregate(
 }
 
 
+/*
+** Usage:  printf TEXT
+**
+** Send output to printf.  Use this rather than puts to merge the output
+** in the correct sequence with debugging printfs inserted into C code.
+** Puts uses a separate buffer and debugging statements will be out of
+** sequence if it is used.
+*/
+static int test_printf(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  char **argv            /* Text of each argument */
+){
+  if( argc!=2 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " TEXT\"", 0);
+    return TCL_ERROR;
+  }
+  printf("%s\n", argv[1]);
+  return TCL_OK;
+}
+
+
 
 /*
 ** Usage:  sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
@@ -1025,6 +1152,29 @@ static int test_enable_shared(
 }
 #endif
 
+/*
+** Usage: sqlite3_extended_result_codes   DB    BOOLEAN
+**
+*/
+static int test_extended_result_codes(
+  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int objc,              /* Number of arguments */
+  Tcl_Obj *CONST objv[]  /* Command arguments */
+){
+  int enable;
+  sqlite3 *db;
+
+  if( objc!=3 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+  if( Tcl_GetBooleanFromObj(interp, objv[2], &enable) ) return TCL_ERROR;
+  sqlite3_extended_result_codes(db, enable);
+  return TCL_OK;
+}
+
 /*
 ** Usage: sqlite3_libversion_number
 **
@@ -1289,7 +1439,7 @@ static int test_finalize(
 ){
   sqlite3_stmt *pStmt;
   int rc;
-  sqlite3 *db;
+  sqlite3 *db = 0;
 
   if( objc!=2 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -1417,6 +1567,7 @@ static int test_changes(
 ** the FLAG option of sqlite3_bind is "static"
 */
 static char *sqlite_static_bind_value = 0;
+static int sqlite_static_bind_nbyte = 0;
 
 /*
 ** Usage:  sqlite3_bind  VM  IDX  VALUE  FLAGS
@@ -1449,6 +1600,9 @@ static int test_bind(
     rc = sqlite3_bind_null(pStmt, idx);
   }else if( strcmp(argv[4],"static")==0 ){
     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0);
+  }else if( strcmp(argv[4],"static-nbytes")==0 ){
+    rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value,
+                                       sqlite_static_bind_nbyte, 0);
   }else if( strcmp(argv[4],"normal")==0 ){
     rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT);
   }else if( strcmp(argv[4],"blob10")==0 ){
@@ -2291,6 +2445,8 @@ static int test_errcode(
   Tcl_Obj *CONST objv[]
 ){
   sqlite3 *db;
+  int rc;
+  char zBuf[30];
 
   if( objc!=2 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", 
@@ -2298,7 +2454,13 @@ static int test_errcode(
     return TCL_ERROR;
   }
   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
-  Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0);
+  rc = sqlite3_errcode(db);
+  if( (rc&0xff)==rc ){
+    zBuf[0] = 0;
+  }else{
+    sprintf(zBuf,"+%d", rc>>8);
+  }
+  Tcl_AppendResult(interp, (char *)errorName(rc), zBuf, 0);
   return TCL_OK;
 }
 
@@ -2418,7 +2580,60 @@ static int test_prepare(
 }
 
 /*
-** Usage: sqlite3_prepare DB sql bytes tailvar
+** Usage: sqlite3_prepare_v2 DB sql bytes tailvar
+**
+** Compile up to <bytes> bytes of the supplied SQL string <sql> using
+** database handle <DB>. The parameter <tailval> is the name of a global
+** variable that is set to the unused portion of <sql> (if any). A
+** STMT handle is returned.
+*/
+static int test_prepare_v2(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3 *db;
+  const char *zSql;
+  int bytes;
+  const char *zTail = 0;
+  sqlite3_stmt *pStmt = 0;
+  char zBuf[50];
+  int rc;
+
+  if( objc!=5 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", 
+       Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+  zSql = Tcl_GetString(objv[2]);
+  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
+
+  rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, &zTail);
+  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
+  if( zTail ){
+    if( bytes>=0 ){
+      bytes = bytes - (zTail-zSql);
+    }
+    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
+  }
+  if( rc!=SQLITE_OK ){
+    assert( pStmt==0 );
+    sprintf(zBuf, "(%d) ", rc);
+    Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
+    return TCL_ERROR;
+  }
+
+  if( pStmt ){
+    if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
+    Tcl_AppendResult(interp, zBuf, 0);
+  }
+  return TCL_OK;
+}
+
+/*
+** Usage: sqlite3_prepare16 DB sql bytes tailvar
 **
 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
 ** database handle <DB>. The parameter <tailval> is the name of a global
@@ -2475,6 +2690,64 @@ static int test_prepare16(
   return TCL_OK;
 }
 
+/*
+** Usage: sqlite3_prepare16_v2 DB sql bytes tailvar
+**
+** Compile up to <bytes> bytes of the supplied SQL string <sql> using
+** database handle <DB>. The parameter <tailval> is the name of a global
+** variable that is set to the unused portion of <sql> (if any). A
+** STMT handle is returned.
+*/
+static int test_prepare16_v2(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+#ifndef SQLITE_OMIT_UTF16
+  sqlite3 *db;
+  const void *zSql;
+  const void *zTail = 0;
+  Tcl_Obj *pTail = 0;
+  sqlite3_stmt *pStmt = 0;
+  char zBuf[50]; 
+  int rc;
+  int bytes;                /* The integer specified as arg 3 */
+  int objlen;               /* The byte-array length of arg 2 */
+
+  if( objc!=5 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", 
+       Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+  zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
+  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
+
+  rc = sqlite3_prepare16_v2(db, zSql, bytes, &pStmt, &zTail);
+  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
+  if( rc ){
+    return TCL_ERROR;
+  }
+
+  if( zTail ){
+    objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
+  }else{
+    objlen = 0;
+  }
+  pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
+  Tcl_IncrRefCount(pTail);
+  Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
+  Tcl_DecrRefCount(pTail);
+
+  if( pStmt ){
+    if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
+  }
+  Tcl_AppendResult(interp, zBuf, 0);
+#endif /* SQLITE_OMIT_UTF16 */
+  return TCL_OK;
+}
+
 /*
 ** Usage: sqlite3_open filename ?options-list?
 */
@@ -3540,6 +3813,18 @@ static void set_options(Tcl_Interp *interp){
   Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY);
 #endif
 
+#ifdef SQLITE_ENABLE_FTS1
+  Tcl_SetVar2(interp, "sqlite_options", "fts1", "1", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "fts1", "0", TCL_GLOBAL_ONLY);
+#endif
+
+#ifdef SQLITE_ENABLE_FTS2
+  Tcl_SetVar2(interp, "sqlite_options", "fts2", "1", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "fts2", "0", TCL_GLOBAL_ONLY);
+#endif
+
 #ifdef SQLITE_OMIT_GLOBALRECOVER
   Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY);
 #else
@@ -3698,6 +3983,35 @@ static void set_options(Tcl_Interp *interp){
 #endif
 }
 
+/*
+** tclcmd:   working_64bit_int
+**
+** Some TCL builds (ex: cygwin) do not support 64-bit integers.  This
+** leads to a number of test failures.  The present command checks the
+** TCL build to see whether or not it supports 64-bit integers.  It
+** returns TRUE if it does and FALSE if not.
+**
+** This command is used to warn users that their TCL build is defective
+** and that the errors they are seeing in the test scripts might be
+** a result of their defective TCL rather than problems in SQLite.
+*/
+static int working_64bit_int(
+  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int objc,              /* Number of arguments */
+  Tcl_Obj *CONST objv[]  /* Command arguments */
+){
+  Tcl_Obj *pTestObj;
+  int working = 0;
+
+  pTestObj = Tcl_NewWideIntObj(1000000*(i64)1234567890);
+  working = strcmp(Tcl_GetString(pTestObj), "1234567890000000")==0;
+  Tcl_DecrRefCount(pTestObj);
+  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(working));
+  return TCL_OK;
+}
+
+
 /*
 ** Register commands with the TCL interpreter.
 */
@@ -3722,6 +4036,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_mprintf_n_test",        (Tcl_CmdProc*)test_mprintf_n        },
      { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
      { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
+     { "sqlite3_exec",                  (Tcl_CmdProc*)test_exec             },
+     { "sqlite3_exec_nr",               (Tcl_CmdProc*)test_exec_nr          },
      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
@@ -3743,6 +4059,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },
      { "sqlite3_stack_used",            (Tcl_CmdProc*)test_stack_used       },
      { "sqlite3_busy_timeout",          (Tcl_CmdProc*)test_busy_timeout     },
+     { "printf",                        (Tcl_CmdProc*)test_printf           },
   };
   static struct {
      char *zName;
@@ -3771,6 +4088,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 
      { "sqlite3_prepare",               test_prepare       ,0 },
      { "sqlite3_prepare16",             test_prepare16     ,0 },
+     { "sqlite3_prepare_v2",            test_prepare_v2    ,0 },
+     { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
      { "sqlite3_finalize",              test_finalize      ,0 },
      { "sqlite3_reset",                 test_reset         ,0 },
      { "sqlite3_expired",               test_expired       ,0 },
@@ -3786,6 +4105,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 
      { "sqlite3_load_extension",        test_load_extension,     0},
      { "sqlite3_enable_load_extension", test_enable_load,        0},
+     { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
 
      /* sqlite3_column_*() API */
      { "sqlite3_column_count",          test_column_count  ,0 },
@@ -3819,6 +4139,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 #endif
 #endif
      { "sqlite3_global_recover",    test_global_recover, 0   },
+     { "working_64bit_int",         working_64bit_int,   0   },
 
      /* Functions from os.h */
 #ifndef SQLITE_OMIT_DISKIO
@@ -3938,6 +4259,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 #endif
   Tcl_LinkVar(interp, "sqlite_static_bind_value",
       (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
+  Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",
+      (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT);
   Tcl_LinkVar(interp, "sqlite_temp_directory",
       (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
   Tcl_LinkVar(interp, "bitmask_size",
index 6557fb4f4d475160e674b1a0891b260983d6ea42..ebf357e121f9f72b9438b76f79b161c3bb2b6f64 100644 (file)
@@ -567,6 +567,7 @@ static int btree_integrity_check(
   int nRoot;
   int *aRoot;
   int i;
+  int nErr;
   char *zResult;
 
   if( argc<3 ){
@@ -581,7 +582,7 @@ static int btree_integrity_check(
     if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR;
   }
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
-  zResult = sqlite3BtreeIntegrityCheck(pBt, aRoot, nRoot);
+  zResult = sqlite3BtreeIntegrityCheck(pBt, aRoot, nRoot, 10000, &nErr);
 #else
   zResult = 0;
 #endif
@@ -598,7 +599,6 @@ static int btree_integrity_check(
 **
 ** Print information about all cursors to standard output for debugging.
 */
-#ifdef SQLITE_DEBUG
 static int btree_cursor_list(
   void *NotUsed,
   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
@@ -616,7 +616,6 @@ static int btree_cursor_list(
   sqlite3BtreeCursorList(pBt);
   return SQLITE_OK;
 }
-#endif
 
 /*
 ** Usage:   btree_cursor ID TABLENUM WRITEABLE
@@ -1053,6 +1052,7 @@ static int btree_data(
   rc = sqlite3BtreeData(pCur, 0, n, zBuf);
   if( rc ){
     Tcl_AppendResult(interp, errorName(rc), 0);
+    free(zBuf);
     return TCL_ERROR;
   }
   zBuf[n] = 0;
@@ -1187,7 +1187,6 @@ static int btree_payload_size(
 **   aResult[8] =  Local payload size
 **   aResult[9] =  Parent page number
 */
-#ifdef SQLITE_DEBUG
 static int btree_cursor_info(
   void *NotUsed,
   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
@@ -1225,7 +1224,6 @@ static int btree_cursor_info(
   Tcl_AppendResult(interp, &zBuf[1], 0);
   return SQLITE_OK;
 }
-#endif
 
 /*
 ** The command is provided for the purpose of setting breakpoints.
@@ -1441,10 +1439,8 @@ int Sqlitetest3_Init(Tcl_Interp *interp){
      { "btree_rollback_statement", (Tcl_CmdProc*)btree_rollback_statement },
      { "btree_from_db",            (Tcl_CmdProc*)btree_from_db            },
      { "btree_set_cache_size",     (Tcl_CmdProc*)btree_set_cache_size     },
-#ifdef SQLITE_DEBUG
      { "btree_cursor_info",        (Tcl_CmdProc*)btree_cursor_info        },
      { "btree_cursor_list",        (Tcl_CmdProc*)btree_cursor_list        },
-#endif
   };
   int i;
 
index 69db09aa4fb0a3c8ab4287acbdac6f2768d12d33..3837e276ec55e53ed4fd90ee9952220bb4b936d4 100644 (file)
@@ -394,16 +394,16 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
   int tokenType;
   int lastTokenParsed = -1;
   sqlite3 *db = pParse->db;
-  extern void *sqlite3ParserAlloc(void*(*)(int));
+  extern void *sqlite3ParserAlloc(void*(*)(size_t));
   extern void sqlite3ParserFree(void*, void(*)(void*));
-  extern int sqlite3Parser(void*, int, Token, Parse*);
+  extern void sqlite3Parser(void*, int, Token, Parse*);
 
   if( db->activeVdbeCnt==0 ){
     db->u1.isInterrupted = 0;
   }
   pParse->rc = SQLITE_OK;
   i = 0;
-  pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX);
+  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3MallocX);
   if( pEngine==0 ){
     return SQLITE_NOMEM;
   }
index 15992df3812a1103c4515cf1ecb0b64d9b941834..a6eabbf62a096357564be2298fa2ed996f602a06 100644 (file)
@@ -49,7 +49,8 @@ void sqlite3BeginTrigger(
   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 isTemp,         /* True if the TEMPORARY keyword is present */
+  int noErr           /* Suppress errors if the trigger already exists */
 ){
   Trigger *pTrigger = 0;
   Table *pTab;
@@ -115,7 +116,9 @@ void sqlite3BeginTrigger(
     goto trigger_cleanup;
   }
   if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
-    sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+    if( !noErr ){
+      sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+    }
     goto trigger_cleanup;
   }
 
@@ -439,7 +442,7 @@ void sqlite3DeleteTrigger(Trigger *pTrigger){
 ** same job as this routine except it takes a pointer to the trigger
 ** instead of the trigger name.
 **/
-void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
+void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
   Trigger *pTrigger = 0;
   int i;
   const char *zDb;
@@ -463,7 +466,9 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
     if( pTrigger ) break;
   }
   if( !pTrigger ){
-    sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
+    if( !noErr ){
+      sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
+    }
     goto drop_trigger_cleanup;
   }
   sqlite3DropTriggerPtr(pParse, pTrigger);
@@ -663,12 +668,12 @@ static int codeTriggerProgram(
     pParse->trigStack->orconf = orconf;
     switch( pTriggerStep->op ){
       case TK_SELECT: {
-       Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);            
-       assert(ss);
-       assert(ss->pSrc);
-        sqlite3SelectResolve(pParse, ss, 0);
-       sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
-       sqlite3SelectDelete(ss);
+       Select *ss = sqlite3SelectDup(pTriggerStep->pSelect);
+        if( ss ){
+          sqlite3SelectResolve(pParse, ss, 0);
+          sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
+          sqlite3SelectDelete(ss);
+        }
        break;
       }
       case TK_UPDATE: {
index 05d238433a9e57ca96bed54c008a08a9a7475a95..6b78a6dee6621412205dfa6810b18d7e76addbf6 100644 (file)
@@ -64,7 +64,7 @@
 
 /*
 ** This table maps from the first byte of a UTF-8 character to the number
-** of trailing bytes expected. A value '255' indicates that the table key
+** of trailing bytes expected. A value '4' indicates that the table key
 ** is not a legal first byte for a UTF-8 character.
 */
 static const u8 xtra_utf8_bytes[256]  = {
@@ -79,10 +79,10 @@ static const u8 xtra_utf8_bytes[256]  = {
 0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
 
 /* 10wwwwww */
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,
+4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,
+4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,
+4, 4, 4, 4, 4, 4, 4, 4,     4, 4, 4, 4, 4, 4, 4, 4,
 
 /* 110yyyyy */
 1, 1, 1, 1, 1, 1, 1, 1,     1, 1, 1, 1, 1, 1, 1, 1,
@@ -92,7 +92,7 @@ static const u8 xtra_utf8_bytes[256]  = {
 2, 2, 2, 2, 2, 2, 2, 2,     2, 2, 2, 2, 2, 2, 2, 2,
 
 /* 11110yyy */
-3, 3, 3, 3, 3, 3, 3, 3,     255, 255, 255, 255, 255, 255, 255, 255,
+3, 3, 3, 3, 3, 3, 3, 3,     4, 4, 4, 4, 4, 4, 4, 4,
 };
 
 /*
@@ -101,11 +101,24 @@ static const u8 xtra_utf8_bytes[256]  = {
 ** read by a naive implementation of a UTF-8 character reader. The code
 ** in the READ_UTF8 macro explains things best.
 */
-static const int xtra_utf8_bits[4] =  {
-0,
-12416,          /* (0xC0 << 6) + (0x80) */
-925824,         /* (0xE0 << 12) + (0x80 << 6) + (0x80) */
-63447168        /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
+static const int xtra_utf8_bits[] =  {
+  0,
+  12416,          /* (0xC0 << 6) + (0x80) */
+  925824,         /* (0xE0 << 12) + (0x80 << 6) + (0x80) */
+  63447168        /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
+};
+
+/*
+** If a UTF-8 character contains N bytes extra bytes (N bytes follow
+** the initial byte so that the total character length is N+1) then
+** masking the character with utf8_mask[N] must produce a non-zero
+** result.  Otherwise, we have an (illegal) overlong encoding.
+*/
+static const int utf_mask[] = {
+  0x00000000,
+  0xffffff80,
+  0xfffff800,
+  0xffff0000,
 };
 
 #define READ_UTF8(zIn, c) { \
@@ -113,11 +126,14 @@ static const int xtra_utf8_bits[4] =  {
   c = *(zIn)++;                                        \
   xtra = xtra_utf8_bytes[c];                           \
   switch( xtra ){                                      \
-    case 255: c = (int)0xFFFD; break;                  \
+    case 4: c = (int)0xFFFD; break;                    \
     case 3: c = (c<<6) + *(zIn)++;                     \
     case 2: c = (c<<6) + *(zIn)++;                     \
     case 1: c = (c<<6) + *(zIn)++;                     \
     c -= xtra_utf8_bits[xtra];                         \
+    if( (utf_mask[xtra]&c)==0                          \
+        || (c&0xFFFFF800)==0xD800                      \
+        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }    \
   }                                                    \
 }
 int sqlite3ReadUtf8(const unsigned char *z){
@@ -181,6 +197,7 @@ int sqlite3ReadUtf8(const unsigned char *z){
     int c2 = (*zIn++);                                                \
     c2 += ((*zIn++)<<8);                                              \
     c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
+    if( (c & 0xFFFF0000)==0 ) c = 0xFFFD;                             \
   }                                                                   \
 }
 
@@ -191,6 +208,7 @@ int sqlite3ReadUtf8(const unsigned char *z){
     int c2 = ((*zIn++)<<8);                                           \
     c2 += (*zIn++);                                                   \
     c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
+    if( (c & 0xFFFF0000)==0 ) c = 0xFFFD;                             \
   }                                                                   \
 }
 
@@ -245,7 +263,7 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
   unsigned char *zIn;                   /* Input iterator */
   unsigned char *zTerm;                 /* End of input */
   unsigned char *z;                     /* Output iterator */
-  int c;
+  unsigned int c;
 
   assert( pMem->flags&MEM_Str );
   assert( pMem->enc!=desiredEnc );
@@ -475,7 +493,7 @@ char *sqlite3utf16to8(const void *z, int nByte){
 ** in pZ (or up until the first pair of 0x00 bytes, whichever comes first).
 */
 int sqlite3utf16ByteLen(const void *zIn, int nChar){
-  int c = 1;
+  unsigned int c = 1;
   char const *z = zIn;
   int n = 0;
   if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
@@ -556,11 +574,11 @@ void sqlite3utf16Substr(
 ** characters in each encoding are inverses of each other.
 */
 void sqlite3utfSelfTest(){
-  int i;
+  unsigned int i, t;
   unsigned char zBuf[20];
   unsigned char *z;
   int n;
-  int c;
+  unsigned int c;
 
   for(i=0; i<0x00110000; i++){
     z = zBuf;
@@ -568,7 +586,10 @@ void sqlite3utfSelfTest(){
     n = z-zBuf;
     z = zBuf;
     READ_UTF8(z, c);
-    assert( c==i );
+    t = i;
+    if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
+    if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
+    assert( c==t );
     assert( (z-zBuf)==n );
   }
   for(i=0; i<0x00110000; i++){
index 5ca9ec4086dab2ff7d2ef3491d7322b2387040d0..bdb381d4b7807c1be6cf22ec461fe96c2e0c280d 100644 (file)
@@ -1446,7 +1446,7 @@ int sqlite3ApiExit(sqlite3* db, int rc){
     sqlite3Error(db, SQLITE_NOMEM, 0);
     rc = SQLITE_NOMEM;
   }
-  return rc;
+  return rc & (db ? db->errMask : 0xff);
 }
 
 /* 
index 336df67ccbf8807e99c2181f5496391652ca1b27..07f62ae77f6248610079c0638d217507e8a00400 100644 (file)
 #include "os.h"
 
 #ifndef SQLITE_OMIT_VACUUM
-/*
-** Generate a random name of 20 character in length.
-*/
-static void randomName(unsigned char *zBuf){
-  static const unsigned char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "0123456789";
-  int i;
-  sqlite3Randomness(20, zBuf);
-  for(i=0; i<20; i++){
-    zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
-  }
-}
-
 /*
 ** Execute zSql on database db. Return an error code.
 */
@@ -69,8 +55,6 @@ static int execExecSql(sqlite3 *db, const char *zSql){
   return sqlite3_finalize(pStmt);
 }
 
-#endif
-
 /*
 ** The non-standard VACUUM command is used to clean up the database,
 ** collapse free space, etc.  It is modelled after the VACUUM command
@@ -94,60 +78,25 @@ void sqlite3Vacuum(Parse *pParse){
 */
 int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   int rc = SQLITE_OK;     /* Return code from service routines */
-#ifndef SQLITE_OMIT_VACUUM
-  const char *zFilename;  /* full pathname of the database file */
-  int nFilename;          /* number of characters  in zFilename[] */
-  char *zTemp = 0;        /* a temporary file in same directory as zFilename */
   Btree *pMain;           /* The database being vacuumed */
-  Btree *pTemp;
-  char *zSql = 0;
-  int saved_flags;       /* Saved value of the db->flags */
-  Db *pDb = 0;           /* Database to detach at end of vacuum */
+  Btree *pTemp;           /* The temporary database we vacuum into */
+  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);
     rc = SQLITE_ERROR;
     goto end_of_vacuum;
   }
-
-  /* Get the full pathname of the database file and create a
-  ** temporary filename in the same directory as the original file.
-  */
   pMain = db->aDb[0].pBt;
-  zFilename = sqlite3BtreeGetFilename(pMain);
-  assert( zFilename );
-  if( zFilename[0]=='\0' ){
-    /* The in-memory database. Do nothing. Return directly to avoid causing
-    ** an error trying to DETACH the vacuum_db (which never got attached)
-    ** in the exit-handler.
-    */
-    return SQLITE_OK;
-  }
-  nFilename = strlen(zFilename);
-  zTemp = sqliteMalloc( nFilename+100 );
-  if( zTemp==0 ){
-    rc = SQLITE_NOMEM;
-    goto end_of_vacuum;
-  }
-  strcpy(zTemp, zFilename);
-
-  /* The randomName() procedure in the following loop uses an excellent
-  ** source of randomness to generate a name from a space of 1.3e+31 
-  ** possibilities.  So unless the directory already contains on the order
-  ** of 1.3e+31 files, the probability that the following loop will
-  ** run more than once or twice is vanishingly small.  We are certain
-  ** enough that this loop will always terminate (and terminate quickly)
-  ** that we don't even bother to set a maximum loop count.
-  */
-  do {
-    zTemp[nFilename] = '-';
-    randomName((unsigned char*)&zTemp[nFilename+1]);
-  } while( sqlite3OsFileExists(zTemp) );
 
   /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
   ** can be set to 'off' for this file, as it is not recovered if a crash
@@ -190,7 +139,9 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   */
   rc = execExecSql(db, 
       "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) "
-      "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'");
+      "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
+      "   AND rootpage>0"
+  );
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
   rc = execExecSql(db, 
       "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000)"
@@ -200,11 +151,6 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
       "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) "
       "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
-  rc = execExecSql(db, 
-      "SELECT 'CREATE VIEW vacuum_db.' || substr(sql,13,100000000) "
-      "  FROM sqlite_master WHERE type='view'"
-  );
-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
   /* Loop through the tables in the main database. For each, do
   ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy
@@ -214,7 +160,9 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
       "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
       "|| ' SELECT * FROM ' || quote(name) || ';'"
       "FROM sqlite_master "
-      "WHERE type = 'table' AND name!='sqlite_sequence';"
+      "WHERE type = 'table' AND name!='sqlite_sequence' "
+      "  AND rootpage>0"
+
   );
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
@@ -233,17 +181,19 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
 
-  /* Copy the triggers from the main database to the temporary database.
-  ** This was deferred before in case the triggers interfered with copying
-  ** the data. It's possible the indices should be deferred until this
-  ** point also.
+  /* Copy the triggers, views, and virtual tables from the main database
+  ** over to the temporary database.  None of these objects has any
+  ** associated storage, so all we have to do is copy their entries
+  ** from the SQLITE_MASTER table.
   */
-  rc = execExecSql(db, 
-      "SELECT 'CREATE TRIGGER  vacuum_db.' || substr(sql, 16, 1000000) "
-      "FROM sqlite_master WHERE type='trigger'"
+  rc = execSql(db,
+      "INSERT INTO vacuum_db.sqlite_master "
+      "  SELECT type, name, tbl_name, rootpage, sql"
+      "    FROM sqlite_master"
+      "   WHERE type='view' OR type='trigger'"
+      "      OR (type='table' AND rootpage=0)"
   );
-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
+  if( rc ) goto end_of_vacuum;
 
   /* At this point, unless the main db was completely empty, there is now a
   ** transaction open on the vacuum database, but not on the main database.
@@ -309,21 +259,12 @@ end_of_vacuum:
     pDb->pSchema = 0;
   }
 
-  /* If one of the execSql() calls above returned SQLITE_NOMEM, then the
-  ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()).
-  ** Fix this so the flag and return code match.
-  */
-  if( rc==SQLITE_NOMEM ){
-    sqlite3MallocFailed();
-  }
-
-  if( zTemp ){
-    sqlite3OsDelete(zTemp);
-    sqliteFree(zTemp);
-  }
+  sqlite3OsDelete(zTemp);
+  strcat(zTemp, "-journal");
+  sqlite3OsDelete(zTemp);
   sqliteFree( zSql );
   sqlite3ResetInternalSchema(db, 0);
-#endif
 
   return rc;
 }
+#endif  /* SQLITE_OMIT_VACUUM */
index 98b9916abe992936d603d0cf88b5923de13280af..2e5b3957b9f3a9587a50a6abaf832617e387ab89 100644 (file)
@@ -454,6 +454,21 @@ int sqlite3VdbeExec(
   p->resOnStack = 0;
   db->busyHandler.nBusy = 0;
   CHECK_FOR_INTERRUPT;
+#ifdef SQLITE_DEBUG
+  if( (p->db->flags & SQLITE_VdbeListing)!=0
+    || sqlite3OsFileExists("vdbe_explain")
+  ){
+    int i;
+    printf("VDBE Program Listing:\n");
+    sqlite3VdbePrintSql(p);
+    for(i=0; i<p->nOp; i++){
+      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
+    }
+  }
+  if( sqlite3OsFileExists("vdbe_trace") ){
+    p->trace = stdout;
+  }
+#endif
   for(pc=p->pc; rc==SQLITE_OK; pc++){
     assert( pc>=0 && pc<p->nOp );
     assert( pTos<=&p->aStack[pc] );
@@ -1812,32 +1827,31 @@ case OP_IfNot: {            /* no-push */
 
 /* Opcode: IsNull P1 P2 *
 **
-** If any of the top abs(P1) values on the stack are NULL, then jump
-** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
-** unchanged.
+** Check the top of the stack and jump to P2 if the top of the stack
+** is NULL.  If P1 is positive, then pop P1 elements from the stack
+** regardless of whether or not the jump is taken.  If P1 is negative,
+** pop -P1 elements from the stack only if the jump is taken and leave
+** the stack unchanged if the jump is not taken.
 */
 case OP_IsNull: {            /* same as TK_ISNULL, no-push */
-  int i, cnt;
-  Mem *pTerm;
-  cnt = pOp->p1;
-  if( cnt<0 ) cnt = -cnt;
-  pTerm = &pTos[1-cnt];
-  assert( pTerm>=p->aStack );
-  for(i=0; i<cnt; i++, pTerm++){
-    if( pTerm->flags & MEM_Null ){
-      pc = pOp->p2-1;
-      break;
+  if( pTos->flags & MEM_Null ){
+    pc = pOp->p2-1;
+    if( pOp->p1<0 ){
+      popStack(&pTos, -pOp->p1);
     }
   }
-  if( pOp->p1>0 ) popStack(&pTos, cnt);
+  if( pOp->p1>0 ){
+    popStack(&pTos, pOp->p1);
+  }
   break;
 }
 
 /* Opcode: NotNull P1 P2 *
 **
-** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
-** stack if P1 times if P1 is greater than zero.  If P1 is less than
-** zero then leave the stack unchanged.
+** Jump to P2 if the top abs(P1) values on the stack are all not NULL.  
+** Regardless of whether or not the jump is taken, pop the stack
+** P1 times if P1 is greater than zero.  But if P1 is negative,
+** leave the stack unchanged.
 */
 case OP_NotNull: {            /* same as TK_NOTNULL, no-push */
   int i, cnt;
@@ -2010,7 +2024,9 @@ case OP_Column: {
         pC->aRow = 0;
       }
     }
-    assert( zRec!=0 || avail>=payloadSize || avail>=9 );
+    /* The following assert is true in all cases accept when
+    ** the database file has been corrupted externally.
+    **    assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */
     szHdrSz = GetVarint((u8*)zData, offset);
 
     /* The KeyFetch() or DataFetch() above are fast and will get the entire
@@ -2501,6 +2517,8 @@ case OP_VerifyCookie: {       /* no-push */
   }
   if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
     sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0);
+    sqlite3ResetInternalSchema(db, pOp->p1);
+    sqlite3ExpirePreparedStatements(db);
     rc = SQLITE_SCHEMA;
   }
   break;
@@ -2907,7 +2925,7 @@ case OP_MoveGt: {       /* no-push */
 **
 ** The top of the stack holds a blob constructed by MakeRecord.  P1 is
 ** an index.  If no entry exists in P1 that matches the blob then jump
-** to P1.  If an entry does existing, fall through.  The cursor is left
+** to P2.  If an entry does existing, fall through.  The cursor is left
 ** pointing to the entry that matches.  The blob is popped from the stack.
 **
 ** The difference between this operation and Distinct is that
@@ -2980,7 +2998,7 @@ case OP_IsUnique: {        /* no-push */
   R = pTos->i;
   assert( (pTos->flags & MEM_Dyn)==0 );
   pTos--;
-  assert( i>=0 && i<=p->nCursor );
+  assert( i>=0 && i<p->nCursor );
   pCx = p->apCsr[i];
   assert( pCx!=0 );
   pCrsr = pCx->pCursor;
@@ -3081,6 +3099,9 @@ case OP_NotExists: {        /* no-push */
     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. */
     if( res!=0 ){
       pc = pOp->p2 - 1;
       pC->rowidIsValid = 0;
@@ -3852,38 +3873,6 @@ case OP_IdxGE: {        /* no-push */
   break;
 }
 
-/* Opcode: IdxIsNull P1 P2 *
-**
-** The top of the stack contains an index entry such as might be generated
-** by the MakeIdxRec opcode.  This routine looks at the first P1 fields of
-** that key.  If any of the first P1 fields are NULL, then a jump is made
-** to address P2.  Otherwise we fall straight through.
-**
-** The index entry is always popped from the stack.
-*/
-case OP_IdxIsNull: {        /* no-push */
-  int i = pOp->p1;
-  int k, n;
-  const char *z;
-  u32 serial_type;
-
-  assert( pTos>=p->aStack );
-  assert( pTos->flags & MEM_Blob );
-  z = pTos->z;
-  n = pTos->n;
-  k = sqlite3GetVarint32((u8*)z, &serial_type);
-  for(; k<n && i>0; i--){
-    k += sqlite3GetVarint32((u8*)&z[k], &serial_type);
-    if( serial_type==0 ){   /* Serial type 0 is a NULL */
-      pc = pOp->p2-1;
-      break;
-    }
-  }
-  Release(pTos);
-  pTos--;
-  break;
-}
-
 /* Opcode: Destroy P1 P2 *
 **
 ** Delete an entire database table or index whose root page in the database
@@ -3906,9 +3895,9 @@ case OP_IdxIsNull: {        /* no-push */
 */
 case OP_Destroy: {
   int iMoved;
-  Vdbe *pVdbe;
   int iCnt;
 #ifndef SQLITE_OMIT_VIRTUALTABLE
+  Vdbe *pVdbe;
   iCnt = 0;
   for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
     if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){
@@ -4032,10 +4021,14 @@ case OP_CreateTable: {
   break;
 }
 
-/* Opcode: ParseSchema P1 * P3
+/* Opcode: ParseSchema P1 P2 P3
 **
 ** Read and parse all entries from the SQLITE_MASTER table of database P1
-** that match the WHERE clause P3.
+** that match the WHERE clause P3.  P2 is the "force" flag.   Always do
+** the parsing if P2 is true.  If P2 is false, then this routine is a
+** no-op if the schema is not currently loaded.  In other words, if P2
+** is false, the SQLITE_MASTER table is only parsed if the rest of the
+** schema is already loaded into the symbol table.
 **
 ** This opcode invokes the parser to create a new virtual machine,
 ** then runs the new virtual machine.  It is thus a reentrant opcode.
@@ -4047,13 +4040,16 @@ case OP_ParseSchema: {        /* no-push */
   InitData initData;
 
   assert( iDb>=0 && iDb<db->nDb );
-  if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
+  if( !pOp->p2 && !DbHasProperty(db, iDb, DB_SchemaLoaded) ){
+    break;
+  }
   zMaster = SCHEMA_TABLE(iDb);
   initData.db = db;
+  initData.iDb = pOp->p1;
   initData.pzErrMsg = &p->zErrMsg;
   zSql = sqlite3MPrintf(
-     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
-     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
+     "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
+     db->aDb[iDb].zName, zMaster, pOp->p3);
   if( zSql==0 ) goto no_mem;
   sqlite3SafetyOff(db);
   assert( db->init.busy==0 );
@@ -4124,11 +4120,16 @@ case OP_DropTrigger: {        /* no-push */
 
 
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/* Opcode: IntegrityCk * P2 *
+/* Opcode: IntegrityCk P1 P2 *
 **
 ** Do an analysis of the currently open database.  Push onto the
 ** stack the text of an error message describing any problems.
-** If there are no errors, push a "ok" onto the stack.
+** If no problems are found, push a NULL onto the stack.
+**
+** P1 is the address of a memory cell that contains the maximum
+** number of allowed errors.  At most mem[P1] errors will be reported.
+** In other words, the analysis stops as soon as mem[P1] errors are 
+** seen.  Mem[P1] is updated with the number of errors remaining.
 **
 ** The root page numbers of all tables in the database are integer
 ** values on the stack.  This opcode pulls as many integers as it
@@ -4137,13 +4138,15 @@ case OP_DropTrigger: {        /* no-push */
 ** If P2 is not zero, the check is done on the auxiliary database
 ** file, not the main database file.
 **
-** This opcode is used for testing purposes only.
+** This opcode is used to implement the integrity_check pragma.
 */
 case OP_IntegrityCk: {
   int nRoot;
   int *aRoot;
   int j;
+  int nErr;
   char *z;
+  Mem *pnErr;
 
   for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){
     if( (pTos[-nRoot].flags & MEM_Int)==0 ) break;
@@ -4151,6 +4154,10 @@ case OP_IntegrityCk: {
   assert( nRoot>0 );
   aRoot = sqliteMallocRaw( sizeof(int*)*(nRoot+1) );
   if( aRoot==0 ) goto no_mem;
+  j = pOp->p1;
+  assert( j>=0 && j<p->nMem );
+  pnErr = &p->aMem[j];
+  assert( (pnErr->flags & MEM_Int)!=0 );
   for(j=0; j<nRoot; j++){
     Mem *pMem = &pTos[-j];
     aRoot[j] = pMem->i;
@@ -4158,12 +4165,12 @@ case OP_IntegrityCk: {
   aRoot[j] = 0;
   popStack(&pTos, nRoot);
   pTos++;
-  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
-  if( z==0 || z[0]==0 ){
-    if( z ) sqliteFree(z);
-    pTos->z = "ok";
-    pTos->n = 2;
-    pTos->flags = MEM_Str | MEM_Static | MEM_Term;
+  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot,
+                                 pnErr->i, &nErr);
+  pnErr->i -= nErr;
+  if( nErr==0 ){
+    assert( z==0 );
+    pTos->flags = MEM_Null;
   }else{
     pTos->z = z;
     pTos->n = strlen(z);
@@ -4499,6 +4506,7 @@ case OP_AggFinal: {        /* no-push */
 }
 
 
+#ifndef SQLITE_OMIT_VACUUM
 /* Opcode: Vacuum * * *
 **
 ** Vacuum the entire database.  This opcode will cause other virtual
@@ -4511,6 +4519,7 @@ case OP_Vacuum: {        /* no-push */
   if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
   break;
 }
+#endif
 
 /* Opcode: Expire P1 * *
 **
@@ -4672,9 +4681,9 @@ case OP_VFilter: {   /* no-push */
   assert( (pTos[0].flags&MEM_Int)!=0 && pTos[-1].flags==MEM_Int );
   nArg = pTos[-1].i;
 
-  /* Invoke the xFilter method if one is defined. */
-  if( pModule->xFilter ){
-    int res;
+  /* Invoke the xFilter method */
+  {
+    int res = 0;
     int i;
     Mem **apArg = p->apArg;
     for(i = 0; i<nArg; i++){
@@ -4857,7 +4866,9 @@ case OP_VUpdate: {   /* no-push */
       apArg[i] = pX;
     }
     if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
+    sqlite3VtabLock(pVtab);
     rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
+    sqlite3VtabUnlock(pVtab);
     if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
     if( pOp->p1 && rc==SQLITE_OK ){
       assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
index 903a18dcd22a72884d3cf40072275f8f41223e2e..385a60bd89e4238f6301371418fd8ef6d05cfbbf 100644 (file)
@@ -129,12 +129,16 @@ int sqlite3VdbeFinalize(Vdbe*);
 void sqlite3VdbeResolveLabel(Vdbe*, int);
 int sqlite3VdbeCurrentAddr(Vdbe*);
 void sqlite3VdbeTrace(Vdbe*,FILE*);
+void sqlite3VdbeResetStepResult(Vdbe*);
 int sqlite3VdbeReset(Vdbe*);
 int sqliteVdbeSetVariables(Vdbe*,int,const char**);
 void sqlite3VdbeSetNumCols(Vdbe*,int);
 int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
 void sqlite3VdbeCountChanges(Vdbe*);
 sqlite3 *sqlite3VdbeDb(Vdbe*);
+void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
+const char *sqlite3VdbeGetSql(Vdbe*);
+void sqlite3VdbeSwap(Vdbe*,Vdbe*);
 
 #ifndef NDEBUG
   void sqlite3VdbeComment(Vdbe*, const char*, ...);
index db8034061b58dbd408a2df5370978c45f027e583..d2f737c990349941b80f2df1c471d0ef506ab94c 100644 (file)
@@ -15,6 +15,8 @@
 ** 6000 lines long) it was split up into several smaller files and
 ** this header information was factored out.
 */
+#ifndef _VDBEINT_H_
+#define _VDBEINT_H_
 
 /*
 ** intToKey() and keyToInt() used to transform the rowid.  But with
@@ -328,6 +330,8 @@ struct Vdbe {
   u8 inVtabMethod;        /* See comments above */
   int nChange;            /* Number of db changes made since last reset */
   i64 startTime;          /* Time when query started - used for profiling */
+  int nSql;             /* Number of bytes in zSql */
+  char *zSql;           /* Text of the SQL statement that generated this */
 #ifdef SQLITE_SSE
   int fetchId;          /* Statement number used by sqlite3_fetch_statement */
   int lru;              /* Counter used for LRU cache replacement */
@@ -401,3 +405,5 @@ void sqlite3VdbeFifoInit(Fifo*);
 int sqlite3VdbeFifoPush(Fifo*, i64);
 int sqlite3VdbeFifoPop(Fifo*, i64*);
 void sqlite3VdbeFifoClear(Fifo*);
+
+#endif /* !defined(_VDBEINT_H_) */
index a0ced3d791fda7e03a243dadd2cb58b0f3fdca8d..9440bbd10539a1167a0c27fd3357ab2adbb7ef95 100644 (file)
@@ -153,9 +153,13 @@ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
 /*
 ** Execute the statement pStmt, either until a row of data is ready, the
 ** statement is completely executed or an error occurs.
+**
+** This routine implements the bulk of the logic behind the sqlite_step()
+** API.  The only thing omitted is the automatic recompile if a 
+** schema change has occurred.  That detail is handled by the
+** outer sqlite3_step() wrapper procedure.
 */
-int sqlite3_step(sqlite3_stmt *pStmt){
-  Vdbe *p = (Vdbe*)pStmt;
+static int sqlite3Step(Vdbe *p){
   sqlite3 *db;
   int rc;
 
@@ -172,7 +176,8 @@ int sqlite3_step(sqlite3_stmt *pStmt){
     if( p->rc==SQLITE_OK ){
       p->rc = SQLITE_SCHEMA;
     }
-    return SQLITE_ERROR;
+    rc = SQLITE_ERROR;
+    goto end_of_step;
   }
   db = p->db;
   if( sqlite3SafetyOn(db) ){
@@ -254,8 +259,42 @@ int sqlite3_step(sqlite3_stmt *pStmt){
 
   sqlite3Error(p->db, rc, 0);
   p->rc = sqlite3ApiExit(p->db, p->rc);
+end_of_step:
+  assert( (rc&0xff)==rc );
+  if( p->zSql && (rc&0xff)<SQLITE_ROW ){
+    /* This behavior occurs if sqlite3_prepare_v2() was used to build
+    ** the prepared statement.  Return error codes directly */
+    return p->rc;
+  }else{
+    /* This is for legacy sqlite3_prepare() builds and when the code
+    ** is SQLITE_ROW or SQLITE_DONE */
+    return rc;
+  }
+}
+
+/*
+** This is the top-level implementation of sqlite3_step().  Call
+** sqlite3Step() to do most of the work.  If a schema error occurs,
+** call sqlite3Reprepare() and try again.
+*/
+#ifdef SQLITE_OMIT_PARSER
+int sqlite3_step(sqlite3_stmt *pStmt){
+  return sqlite3Step((Vdbe*)pStmt);
+}
+#else
+int sqlite3_step(sqlite3_stmt *pStmt){
+  int cnt = 0;
+  int rc;
+  Vdbe *v = (Vdbe*)pStmt;
+  while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
+         && cnt++ < 5
+         && sqlite3Reprepare(v) ){
+    sqlite3_reset(pStmt);
+    v->expired = 0;
+  }
   return rc;
 }
+#endif
 
 /*
 ** Extract the user data from a sqlite3_context structure and return a
@@ -266,6 +305,27 @@ void *sqlite3_user_data(sqlite3_context *p){
   return p->pFunc->pUserData;
 }
 
+/*
+** The following is the implementation of an SQL function that always
+** fails with an error message stating that the function is used in the
+** wrong context.  The sqlite3_overload_function() API might construct
+** SQL function that use this routine so that the functions will exist
+** for name resolution but are actually overloaded by the xFindFunction
+** method of virtual tables.
+*/
+void sqlite3InvalidFunction(
+  sqlite3_context *context,  /* The function calling context */
+  int argc,                  /* Number of arguments to the function */
+  sqlite3_value **argv       /* Value of each argument */
+){
+  const char *zName = context->pFunc->zName;
+  char *zErr;
+  zErr = sqlite3MPrintf(
+      "unable to use function %s in the requested context", zName);
+  sqlite3_result_error(context, zErr, -1);
+  sqliteFree(zErr);
+}
+
 /*
 ** Allocate or return the aggregate context for a user function.  A new
 ** context is allocated on the first call.  Subsequent calls return the
@@ -815,6 +875,7 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
     rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
     sqlite3MallocAllow();
   }
+  assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
   return rc;
 }
 
index c71c8f4ea6df7c749b663bb6d5ca46c8b0e47d3f..be85e7b8cb3ac0a73a9559484eb6a967100df8c8 100644 (file)
@@ -48,6 +48,46 @@ Vdbe *sqlite3VdbeCreate(sqlite3 *db){
   return p;
 }
 
+/*
+** Remember the SQL string for a prepared statement.
+*/
+void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n){
+  if( p==0 ) return;
+  assert( p->zSql==0 );
+  p->zSql = sqlite3StrNDup(z, n);
+}
+
+/*
+** Return the SQL associated with a prepared statement
+*/
+const char *sqlite3VdbeGetSql(Vdbe *p){
+  return p->zSql;
+}
+
+/*
+** Swap all content between two VDBE structures.
+*/
+void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
+  Vdbe tmp, *pTmp;
+  char *zTmp;
+  int nTmp;
+  tmp = *pA;
+  *pA = *pB;
+  *pB = tmp;
+  pTmp = pA->pNext;
+  pA->pNext = pB->pNext;
+  pB->pNext = pTmp;
+  pTmp = pA->pPrev;
+  pA->pPrev = pB->pPrev;
+  pB->pPrev = pTmp;
+  zTmp = pA->zSql;
+  pA->zSql = pB->zSql;
+  pB->zSql = zTmp;
+  nTmp = pA->nSql;
+  pA->nSql = pB->nSql;
+  pB->nSql = nTmp;
+}
+
 /*
 ** Turn tracing on or off
 */
@@ -812,21 +852,6 @@ void sqlite3VdbeMakeReady(
     p->aMem[n].flags = MEM_Null;
   }
 
-#ifdef SQLITE_DEBUG
-  if( (p->db->flags & SQLITE_VdbeListing)!=0
-    || sqlite3OsFileExists("vdbe_explain")
-  ){
-    int i;
-    printf("VDBE Program Listing:\n");
-    sqlite3VdbePrintSql(p);
-    for(i=0; i<p->nOp; i++){
-      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
-    }
-  }
-  if( sqlite3OsFileExists("vdbe_trace") ){
-    p->trace = stdout;
-  }
-#endif
   p->pTos = &p->aStack[-1];
   p->pc = -1;
   p->rc = SQLITE_OK;
@@ -1145,7 +1170,9 @@ static int vdbeCommit(sqlite3 *db){
     ** transaction files are deleted.
     */
     rc = sqlite3OsDelete(zMaster);
-    assert( rc==SQLITE_OK );
+    if( rc ){
+      return rc;
+    }
     sqliteFree(zMaster);
     zMaster = 0;
     rc = sqlite3OsSyncDirectory(zMainFile);
@@ -1287,9 +1314,10 @@ int sqlite3VdbeHalt(Vdbe *p){
 
   /* No commit or rollback needed if the program never started */
   if( p->pc>=0 ){
-
+    int mrc;   /* Primary error code from p->rc */
     /* Check for one of the special errors - SQLITE_NOMEM or SQLITE_IOERR */
-    isSpecialError = ((p->rc==SQLITE_NOMEM || p->rc==SQLITE_IOERR)?1:0);
+    mrc = p->rc & 0xff;
+    isSpecialError = ((mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR)?1:0);
     if( isSpecialError ){
       /* This loop does static analysis of the query to see which of the
       ** following three categories it falls into:
@@ -1421,6 +1449,14 @@ int sqlite3VdbeHalt(Vdbe *p){
   return SQLITE_OK;
 }
 
+/*
+** Each VDBE holds the result of the most recent sqlite3_step() call
+** in p->rc.  This routine sets that result back to SQLITE_OK.
+*/
+void sqlite3VdbeResetStepResult(Vdbe *p){
+  p->rc = SQLITE_OK;
+}
+
 /*
 ** Clean up a VDBE after execution but do not delete the VDBE just yet.
 ** Write any error messages into *pzErrMsg.  Return the result code.
@@ -1433,18 +1469,20 @@ int sqlite3VdbeHalt(Vdbe *p){
 ** VDBE_MAGIC_INIT.
 */
 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
   ** error, then it might not have been halted properly.  So halt
   ** it now.
   */
-  sqlite3SafetyOn(p->db);
+  sqlite3SafetyOn(db);
   sqlite3VdbeHalt(p);
-  sqlite3SafetyOff(p->db);
+  sqlite3SafetyOff(db);
 
   /* If the VDBE has be run even partially, then transfer the error code
   ** and error message from the VDBE into the main database structure.  But
@@ -1453,21 +1491,20 @@ int sqlite3VdbeReset(Vdbe *p){
   */
   if( p->pc>=0 ){
     if( p->zErrMsg ){
-      sqlite3* db = p->db;
       sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX);
       db->errCode = p->rc;
       p->zErrMsg = 0;
     }else if( p->rc ){
-      sqlite3Error(p->db, p->rc, 0);
+      sqlite3Error(db, p->rc, 0);
     }else{
-      sqlite3Error(p->db, SQLITE_OK, 0);
+      sqlite3Error(db, SQLITE_OK, 0);
     }
   }else if( p->rc && p->expired ){
     /* The expired flag was set on the VDBE before the first call
     ** to sqlite3_step(). For consistency (since sqlite3_step() was
     ** called), set the database error in this case as well.
     */
-    sqlite3Error(p->db, p->rc, 0);
+    sqlite3Error(db, p->rc, 0);
   }
 
   /* Reclaim all memory used by the VDBE
@@ -1502,9 +1539,9 @@ int sqlite3VdbeReset(Vdbe *p){
   p->magic = VDBE_MAGIC_INIT;
   p->aborted = 0;
   if( p->rc==SQLITE_SCHEMA ){
-    sqlite3ResetInternalSchema(p->db, 0);
+    sqlite3ResetInternalSchema(db, 0);
   }
-  return p->rc;
+  return p->rc & db->errMask;
 }
  
 /*
@@ -1515,6 +1552,7 @@ int sqlite3VdbeFinalize(Vdbe *p){
   int rc = SQLITE_OK;
   if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
     rc = sqlite3VdbeReset(p);
+    assert( (rc & p->db->errMask)==rc );
   }else if( p->magic!=VDBE_MAGIC_INIT ){
     return SQLITE_MISUSE;
   }
@@ -1569,6 +1607,7 @@ void sqlite3VdbeDelete(Vdbe *p){
   sqliteFree(p->aStack);
   releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
   sqliteFree(p->aColName);
+  sqliteFree(p->zSql);
   p->magic = VDBE_MAGIC_DEAD;
   sqliteFree(p);
 }
@@ -1887,14 +1926,13 @@ int sqlite3VdbeRecordCompare(
     idx2 += GetVarint( aKey2+idx2, serial_type2 );
     if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
 
-    /* Assert that there is enough space left in each key for the blob of
-    ** data to go with the serial type just read. This assert may fail if
-    ** the file is corrupted.  Then read the value from each key into mem1
-    ** and mem2 respectively.
+    /* Extract the values to be compared.
     */
     d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
     d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
 
+    /* Do the comparison
+    */
     rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
     if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
     if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
index 51cd6827faffd3c46580c9a7432574417b40c519..18aef149b629a7714b5bd628df92fc89bd7fb4a8 100644 (file)
@@ -50,14 +50,6 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
   assert(rc==SQLITE_OK    || rc==SQLITE_NOMEM);
   assert(rc==SQLITE_OK    || pMem->enc!=desiredEnc);
   assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
-
-  if( rc==SQLITE_NOMEM ){
-/*
-    sqlite3VdbeMemRelease(pMem);
-    pMem->flags = MEM_Null;
-    pMem->z = 0;
-*/
-  }
   return rc;
 #endif
 }
@@ -127,22 +119,9 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
 ** Make sure the given Mem is \u0000 terminated.
 */
 int sqlite3VdbeMemNulTerminate(Mem *pMem){
-  /* In SQLite, a string without a nul terminator occurs when a string
-  ** is loaded from disk (in this case the memory management is ephemeral),
-  ** or when it is supplied by the user as a bound variable or function
-  ** return value. Therefore, the memory management of the string must be
-  ** either ephemeral, static or controlled by a user-supplied destructor.
-  */
-  assert(                         
-    !(pMem->flags&MEM_Str) ||                /* it's not a string, or      */
-    (pMem->flags&MEM_Term) ||                /* it's nul term. already, or */
-    (pMem->flags&(MEM_Ephem|MEM_Static)) ||  /* it's static or ephem, or   */
-    (pMem->flags&MEM_Dyn && pMem->xDel)      /* external management        */
-  );
   if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
     return SQLITE_OK;   /* Nothing to do */
   }
-
   if( pMem->flags & (MEM_Static|MEM_Ephem) ){
     return sqlite3VdbeMemMakeWriteable(pMem);
   }else{
@@ -151,7 +130,11 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
     memcpy(z, pMem->z, pMem->n);
     z[pMem->n] = 0;
     z[pMem->n+1] = 0;
-    pMem->xDel(pMem->z);
+    if( pMem->xDel ){
+      pMem->xDel(pMem->z);
+    }else{
+      sqliteFree(pMem->z);
+    }
     pMem->xDel = 0;
     pMem->z = z;
   }
@@ -782,7 +765,9 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
         return 0;
       }
     }
-  }else if( !(pVal->flags&MEM_Blob) ){
+    sqlite3VdbeMemNulTerminate(pVal);
+  }else{
+    assert( (pVal->flags&MEM_Blob)==0 );
     sqlite3VdbeMemStringify(pVal, enc);
     assert( 0==(1&(int)pVal->z) );
   }
index e00a1ebc69ea5c5f82298bc5f9084016c8844b61..5f1d5602734c437a24ddfa9be609db6e465da9b0 100644 (file)
@@ -40,6 +40,29 @@ int sqlite3_create_module(
   return sqlite3ApiExit(db, SQLITE_OK);
 }
 
+/*
+** Lock the virtual table so that it cannot be disconnected.
+** Locks nest.  Every lock should have a corresponding unlock.
+** If an unlock is omitted, resources leaks will occur.  
+**
+** If a disconnect is attempted while a virtual table is locked,
+** the disconnect is deferred until all locks have been removed.
+*/
+void sqlite3VtabLock(sqlite3_vtab *pVtab){
+  pVtab->nRef++;
+}
+
+/*
+** Unlock a virtual table.  When the last lock is removed,
+** disconnect the virtual table.
+*/
+void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
+  pVtab->nRef--;
+  if( pVtab->nRef==0 ){
+    pVtab->pModule->xDisconnect(pVtab);
+  }
+}
+
 /*
 ** Clear any and all virtual-table information from the Table record.
 ** This routine is called, for example, just before deleting the Table
@@ -49,10 +72,7 @@ void sqlite3VtabClear(Table *p){
   sqlite3_vtab *pVtab = p->pVtab;
   if( pVtab ){
     assert( p->pMod && p->pMod->pModule );
-    pVtab->nRef--;
-    if( pVtab->nRef==0 ){
-      pVtab->pModule->xDisconnect(pVtab);
-    }
+    sqlite3VtabUnlock(pVtab);
     p->pVtab = 0;
   }
   if( p->azModuleArg ){
@@ -139,7 +159,7 @@ void sqlite3VtabBeginParse(
 */
 static void addArgumentToVtab(Parse *pParse){
   if( pParse->sArg.z && pParse->pNewTable ){
-    const char *z = pParse->sArg.z;
+    const char *z = (const char*)pParse->sArg.z;
     int n = pParse->sArg.n;
     addModuleArgument(pParse->pNewTable, sqliteStrNDup(z, n));
   }
@@ -210,7 +230,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
 
     sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
     zWhere = sqlite3MPrintf("name='%q'", pTab->zName);
-    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
+    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 1, zWhere, P3_DYNAMIC);
     sqlite3VdbeOp3(v, OP_VCreate, iDb, 0, pTab->zName, strlen(pTab->zName) + 1);
   }
 
@@ -266,14 +286,16 @@ static int vtabCallConstructor(
   sqlite3 *db, 
   Table *pTab,
   Module *pMod,
-  int (*xConstruct)(sqlite3*, void *, int, char **, sqlite3_vtab **),
+  int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
   char **pzErr
 ){
   int rc;
   int rc2;
-  char **azArg = pTab->azModuleArg;
+  sqlite3_vtab *pVtab;
+  const char *const*azArg = (const char *const*)pTab->azModuleArg;
   int nArg = pTab->nModuleArg;
-  char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);
+  char *zErr = 0;
+  char *zModuleName = sqlite3MPrintf("%s", pTab->zName);
 
   assert( !db->pVTab );
   assert( xConstruct );
@@ -281,17 +303,22 @@ static int vtabCallConstructor(
   db->pVTab = pTab;
   rc = sqlite3SafetyOff(db);
   assert( rc==SQLITE_OK );
-  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
+  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab, &zErr);
   rc2 = sqlite3SafetyOn(db);
-  if( rc==SQLITE_OK && pTab->pVtab ){
-    pTab->pVtab->pModule = pMod->pModule;
-    pTab->pVtab->nRef = 1;
+  pVtab = pTab->pVtab;
+  if( rc==SQLITE_OK && pVtab ){
+    pVtab->pModule = pMod->pModule;
+    pVtab->nRef = 1;
   }
 
   if( SQLITE_OK!=rc ){
-    *pzErr = zErr;
-    zErr = 0;
-  } else if( db->pVTab ){
+    if( zErr==0 ){
+      *pzErr = sqlite3MPrintf("vtable constructor failed: %s", zModuleName);
+    }else {
+      *pzErr = sqlite3MPrintf("%s", zErr);
+      sqlite3_free(zErr);
+    }
+  }else if( db->pVTab ){
     const char *zFormat = "vtable constructor did not declare schema: %s";
     *pzErr = sqlite3MPrintf(zFormat, pTab->zName);
     rc = SQLITE_ERROR;
@@ -300,7 +327,7 @@ static int vtabCallConstructor(
     rc = rc2;
   }
   db->pVTab = 0;
-  sqliteFree(zErr);
+  sqliteFree(zModuleName);
   return rc;
 }
 
@@ -313,7 +340,6 @@ static int vtabCallConstructor(
 */
 int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
   Module *pMod;
-  const char *zModule;
   int rc = SQLITE_OK;
 
   if( !pTab || !pTab->isVirtual || pTab->pVtab ){
@@ -321,7 +347,6 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
   }
 
   pMod = pTab->pMod;
-  zModule = pTab->azModuleArg[0];
   if( !pMod ){
     const char *zModule = pTab->azModuleArg[0];
     sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
@@ -359,7 +384,7 @@ static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
 
   /* Add pVtab to the end of sqlite3.aVTrans */
   db->aVTrans[db->nVTrans++] = pVtab;
-  pVtab->nRef++;
+  sqlite3VtabLock(pVtab);
   return SQLITE_OK;
 }
 
@@ -444,6 +469,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
   sParse.pNewTable = 0;
   db->pVTab = 0;
 
+  assert( (rc&0xff)==rc );
   return rc;
 }
 
@@ -492,10 +518,7 @@ static void callFinaliser(sqlite3 *db, int offset){
     int (*x)(sqlite3_vtab *);
     x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
     if( x ) x(pVtab);
-    pVtab->nRef--;
-    if( pVtab->nRef==0 ){
-      pVtab->pModule->xDisconnect(pVtab);
-    }
+    sqlite3VtabUnlock(pVtab);
   }
   sqliteFree(db->aVTrans);
   db->nVTrans = 0;
@@ -623,6 +646,10 @@ FuncDef *sqlite3VtabOverloadFunction(
   void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
   void *pArg;
   FuncDef *pNew;
+  int rc;
+  char *zLowerName;
+  unsigned char *z;
+
 
   /* Check to see the left operand is a column in a virtual table */
   if( pExpr==0 ) return pDef;
@@ -637,8 +664,15 @@ FuncDef *sqlite3VtabOverloadFunction(
   if( pMod->xFindFunction==0 ) return pDef;
  
   /* Call the xFuncFunction method on the virtual table implementation
-  ** to see if the implementation wants to overload this function */
-  if( pMod->xFindFunction(pVtab, nArg, pDef->zName, &xFunc, &pArg)==0 ){
+  ** to see if the implementation wants to overload this function 
+  */
+  zLowerName = sqlite3StrDup(pDef->zName);
+  for(z=(unsigned char*)zLowerName; *z; z++){
+    *z = sqlite3UpperToLower[*z];
+  }
+  rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
+  sqliteFree(zLowerName);
+  if( rc==0 ){
     return pDef;
   }
 
index bdbac8112c67cf1f7232ad75515badc2f83b675a..d783a115523502e650a2effdea5e5e1bf0ceb85a 100644 (file)
@@ -157,22 +157,31 @@ struct ExprMaskSet {
 #define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
 #define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))
 #define WO_MATCH  64
+#define WO_ISNULL 128
 
 /*
-** Value for flags returned by bestIndex()
+** Value for flags returned by bestIndex().  
+**
+** The least significant byte is reserved as a mask for WO_ values above.
+** The WhereLevel.flags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
+** But if the table is the right table of a left join, WhereLevel.flags
+** is set to WO_IN|WO_EQ.  The WhereLevel.flags field can then be used as
+** the "op" parameter to findTerm when we are resolving equality constraints.
+** ISNULL constraints will then not be used on the right table of a left
+** join.  Tickets #2177 and #2189.
 */
-#define WHERE_ROWID_EQ       0x0001   /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE    0x0002   /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_COLUMN_EQ      0x0010   /* x=EXPR or x IN (...) */
-#define WHERE_COLUMN_RANGE   0x0020   /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN      0x0040   /* x IN (...) */
-#define WHERE_TOP_LIMIT      0x0100   /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT      0x0200   /* x>EXPR or x>=EXPR constraint */
-#define WHERE_IDX_ONLY       0x0800   /* Use index only - omit table */
-#define WHERE_ORDERBY        0x1000   /* Output will appear in correct order */
-#define WHERE_REVERSE        0x2000   /* Scan in reverse order */
-#define WHERE_UNIQUE         0x4000   /* Selects no more than one row */
-#define WHERE_VIRTUALTABLE   0x8000   /* Use virtual-table processing */
+#define WHERE_ROWID_EQ     0x000100   /* rowid=EXPR or rowid IN (...) */
+#define WHERE_ROWID_RANGE  0x000200   /* rowid<EXPR and/or rowid>EXPR */
+#define WHERE_COLUMN_EQ    0x001000   /* x=EXPR or x IN (...) */
+#define WHERE_COLUMN_RANGE 0x002000   /* x<EXPR and/or x>EXPR */
+#define WHERE_COLUMN_IN    0x004000   /* x IN (...) */
+#define WHERE_TOP_LIMIT    0x010000   /* x<EXPR or x<=EXPR constraint */
+#define WHERE_BTM_LIMIT    0x020000   /* x>EXPR or x>=EXPR constraint */
+#define WHERE_IDX_ONLY     0x080000   /* Use index only - omit table */
+#define WHERE_ORDERBY      0x100000   /* Output will appear in correct order */
+#define WHERE_REVERSE      0x200000   /* Scan in reverse order */
+#define WHERE_UNIQUE       0x400000   /* Selects no more than one row */
+#define WHERE_VIRTUALTABLE 0x800000   /* Use virtual-table processing */
 
 /*
 ** Initialize a preallocated WhereClause structure.
@@ -354,7 +363,7 @@ static int allowedOp(int op){
   assert( TK_LT>TK_EQ && TK_LT<TK_GE );
   assert( TK_LE>TK_EQ && TK_LE<TK_GE );
   assert( TK_GE==TK_EQ+4 );
-  return op==TK_IN || (op>=TK_EQ && op<=TK_GE);
+  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
 }
 
 /*
@@ -388,9 +397,12 @@ static int operatorMask(int op){
   assert( allowedOp(op) );
   if( op==TK_IN ){
     c = WO_IN;
+  }else if( op==TK_ISNULL ){
+    c = WO_ISNULL;
   }else{
     c = WO_EQ<<(op-TK_EQ);
   }
+  assert( op!=TK_ISNULL || c==WO_ISNULL );
   assert( op!=TK_IN || c==WO_IN );
   assert( op!=TK_EQ || c==WO_EQ );
   assert( op!=TK_LT || c==WO_LT );
@@ -422,7 +434,7 @@ static WhereTerm *findTerm(
        && pTerm->leftColumn==iColumn
        && (pTerm->eOperator & op)!=0
     ){
-      if( iCur>=0 && pIdx ){
+      if( iCur>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
         Expr *pX = pTerm->pExpr;
         CollSeq *pColl;
         char idxaff;
@@ -590,13 +602,17 @@ static void exprAnalyze(
   Bitmask prereqAll;
   int nPattern;
   int isComplete;
+  int op;
 
   if( sqlite3MallocFailed() ) return;
   prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
-  if( pExpr->op==TK_IN ){
+  op = pExpr->op;
+  if( op==TK_IN ){
     assert( pExpr->pRight==0 );
     pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList)
                           | exprSelectTableUsage(pMaskSet, pExpr->pSelect);
+  }else if( op==TK_ISNULL ){
+    pTerm->prereqRight = 0;
   }else{
     pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
   }
@@ -608,13 +624,13 @@ static void exprAnalyze(
   pTerm->leftCursor = -1;
   pTerm->iParent = -1;
   pTerm->eOperator = 0;
-  if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){
+  if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
     Expr *pLeft = pExpr->pLeft;
     Expr *pRight = pExpr->pRight;
     if( pLeft->op==TK_COLUMN ){
       pTerm->leftCursor = pLeft->iTable;
       pTerm->leftColumn = pLeft->iColumn;
-      pTerm->eOperator = operatorMask(pExpr->op);
+      pTerm->eOperator = operatorMask(op);
     }
     if( pRight && pRight->op==TK_COLUMN ){
       WhereTerm *pNew;
@@ -622,6 +638,10 @@ static void exprAnalyze(
       if( pTerm->leftCursor>=0 ){
         int idxNew;
         pDup = sqlite3ExprDup(pExpr);
+        if( sqlite3MallocFailed() ){
+          sqliteFree(pDup);
+          return;
+        }
         idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
         if( idxNew==0 ) return;
         pNew = &pWC->a[idxNew];
@@ -715,16 +735,15 @@ static void exprAnalyze(
     if( ok ){
       ExprList *pList = 0;
       Expr *pNew, *pDup;
+      Expr *pLeft = 0;
       for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){
         if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue;
         pDup = sqlite3ExprDup(pOrTerm->pExpr->pRight);
         pList = sqlite3ExprListAppend(pList, pDup, 0);
+        pLeft = pOrTerm->pExpr->pLeft;
       }
-      pDup = sqlite3Expr(TK_COLUMN, 0, 0, 0);
-      if( pDup ){
-        pDup->iTable = iCursor;
-        pDup->iColumn = iColumn;
-      }
+      assert( pLeft!=0 );
+      pDup = sqlite3ExprDup(pLeft);
       pNew = sqlite3Expr(TK_IN, pDup, 0, 0);
       if( pNew ){
         int idxNew;
@@ -857,11 +876,19 @@ static int isSortingIndex(
 
   /* Match terms of the ORDER BY clause against columns of
   ** the index.
+  **
+  ** Note that indices have pIdx->nColumn regular columns plus
+  ** one additional column containing the rowid.  The rowid column
+  ** of the index is also allowed to match against the ORDER BY
+  ** clause.
   */
-  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){
+  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){
     Expr *pExpr;       /* The expression of the ORDER BY pTerm */
     CollSeq *pColl;    /* The collating sequence of pExpr */
     int termSortOrder; /* Sort order for this term */
+    int iColumn;       /* The i-th column of the index.  -1 for rowid */
+    int iSortOrder;    /* 1 for DESC, 0 for ASC on the i-th index term */
+    const char *zColl; /* Name of the collating sequence for i-th index term */
 
     pExpr = pTerm->pExpr;
     if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
@@ -870,9 +897,22 @@ static int isSortingIndex(
       return 0;
     }
     pColl = sqlite3ExprCollSeq(pParse, pExpr);
-    if( !pColl ) pColl = db->pDfltColl;
-    if( pExpr->iColumn!=pIdx->aiColumn[i] || 
-        sqlite3StrICmp(pColl->zName, pIdx->azColl[i]) ){
+    if( !pColl ){
+      pColl = db->pDfltColl;
+    }
+    if( i<pIdx->nColumn ){
+      iColumn = pIdx->aiColumn[i];
+      if( iColumn==pIdx->pTable->iPKey ){
+        iColumn = -1;
+      }
+      iSortOrder = pIdx->aSortOrder[i];
+      zColl = pIdx->azColl[i];
+    }else{
+      iColumn = -1;
+      iSortOrder = 0;
+      zColl = pColl->zName;
+    }
+    if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){
       /* Term j of the ORDER BY clause does not match column i of the index */
       if( i<nEqCol ){
         /* If an index column that is constrained by == fails to match an
@@ -888,8 +928,8 @@ static int isSortingIndex(
     }
     assert( pIdx->aSortOrder!=0 );
     assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
-    assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 );
-    termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder;
+    assert( iSortOrder==0 || iSortOrder==1 );
+    termSortOrder = iSortOrder ^ pTerm->sortOrder;
     if( i>nEqCol ){
       if( termSortOrder!=sortOrder ){
         /* Indices can only be used if all ORDER BY terms past the
@@ -901,13 +941,25 @@ static int isSortingIndex(
     }
     j++;
     pTerm++;
+    if( iColumn<0 ){
+      /* If the indexed column is the primary key and everything matches
+      ** so far, then we are assured that the index can be used to sort
+      ** because the primary key is unique and so none of the other columns
+      ** will make any difference
+      */
+      j = nTerm;
+    }
   }
 
-  /* The index can be used for sorting if all terms of the ORDER BY clause
-  ** are covered.
-  */
+  *pbRev = sortOrder!=0;
   if( j>=nTerm ){
-    *pbRev = sortOrder!=0;
+    /* All terms of the ORDER BY clause are covered by this index so
+    ** this index can be used for sorting. */
+    return 1;
+  }
+  if( j==pIdx->nColumn && pIdx->onError!=OE_None ){
+    /* All terms of this index match some prefix of the ORDER BY clause
+    ** and this index is UNIQUE, so this index can be used for sorting. */
     return 1;
   }
   return 0;
@@ -928,8 +980,7 @@ static int sortableByRowid(
   assert( pOrderBy!=0 );
   assert( pOrderBy->nExpr>0 );
   p = pOrderBy->a[0].pExpr;
-  if( pOrderBy->nExpr==1 && p->op==TK_COLUMN && p->iTable==base
-          && p->iColumn==-1 ){
+  if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 ){
     *pbRev = pOrderBy->a[0].sortOrder;
     return 1;
   }
@@ -1232,6 +1283,7 @@ static double bestIndex(
   int rev;                    /* True to scan in reverse order */
   int flags;                  /* Flags associated with pProbe */
   int nEq;                    /* Number of == or IN constraints */
+  int eqTermMask;             /* Mask of valid equality operators */
   double cost;                /* Cost of using pProbe */
 
   TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
@@ -1323,6 +1375,17 @@ static double bestIndex(
     bestFlags = flags;
   }
 
+  /* If the pSrc table is the right table of a LEFT JOIN then we may not
+  ** use an index to satisfy IS NULL constraints on that table.  This is
+  ** because columns might end up being NULL if the table does not match -
+  ** a circumstance which the index cannot help us discover.  Ticket #2177.
+  */
+  if( (pSrc->jointype & JT_LEFT)!=0 ){
+    eqTermMask = WO_EQ|WO_IN;
+  }else{
+    eqTermMask = WO_EQ|WO_IN|WO_ISNULL;
+  }
+
   /* Look at each index.
   */
   for(; pProbe; pProbe=pProbe->pNext){
@@ -1337,7 +1400,7 @@ static double bestIndex(
     flags = 0;
     for(i=0; i<pProbe->nColumn; i++){
       int j = pProbe->aiColumn[i];
-      pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe);
+      pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe);
       if( pTerm==0 ) break;
       flags |= WHERE_COLUMN_EQ;
       if( pTerm->eOperator & WO_IN ){
@@ -1431,7 +1494,7 @@ static double bestIndex(
   *ppIndex = bestIdx;
   TRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
         bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq));
-  *pFlags = bestFlags;
+  *pFlags = bestFlags | eqTermMask;
   *pnEq = bestNEq;
   return lowestCost;
 }
@@ -1476,30 +1539,18 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
 }
 
 /*
-** Generate code that builds a probe for an index.  Details:
-**
-**    *  Check the top nColumn entries on the stack.  If any
-**       of those entries are NULL, jump immediately to brk,
-**       which is the loop exit, since no index entry will match
-**       if any part of the key is NULL. Pop (nColumn+nExtra) 
-**       elements from the stack.
-**
-**    *  Construct a probe entry from the top nColumn entries in
-**       the stack with affinities appropriate for index pIdx. 
-**       Only nColumn elements are popped from the stack in this case
-**       (by OP_MakeRecord).
+** Generate code that builds a probe for an index.
 **
+** There should be nColumn values on the stack.  The index
+** to be probed is pIdx.  Pop the values from the stack and
+** replace them all with a single record that is the index
+** problem.
 */
 static void buildIndexProbe(
-  Vdbe *v, 
-  int nColumn, 
-  int nExtra, 
-  int brk, 
-  Index *pIdx
+  Vdbe *v,        /* Generate code into this VM */
+  int nColumn,    /* The number of columns to check for NULL */
+  Index *pIdx     /* Index that we will be searching */
 ){
-  sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
-  sqlite3VdbeAddOp(v, OP_Pop, nColumn+nExtra, 0);
-  sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
   sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
   sqlite3IndexAffinityStr(v, pIdx);
 }
@@ -1523,15 +1574,17 @@ static void codeEqualityTerm(
   WhereLevel *pLevel  /* When level of the FROM clause we are working on */
 ){
   Expr *pX = pTerm->pExpr;
-  if( pX->op!=TK_IN ){
-    assert( pX->op==TK_EQ );
+  Vdbe *v = pParse->pVdbe;
+  if( pX->op==TK_EQ ){
     sqlite3ExprCode(pParse, pX->pRight);
+  }else if( pX->op==TK_ISNULL ){
+    sqlite3VdbeAddOp(v, OP_Null, 0, 0);
 #ifndef SQLITE_OMIT_SUBQUERY
   }else{
     int iTab;
     int *aIn;
-    Vdbe *v = pParse->pVdbe;
 
+    assert( pX->op==TK_IN );
     sqlite3CodeSubselect(pParse, pX);
     iTab = pX->iTable;
     sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
@@ -1603,17 +1656,20 @@ static void codeAllEqualityTerms(
 
   /* Evaluate the equality constraints
   */
-  for(j=0; j<pIdx->nColumn; j++){
+  assert( pIdx->nColumn>=nEq );
+  for(j=0; j<nEq; j++){
     int k = pIdx->aiColumn[j];
-    pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN, pIdx);
+    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);
+    }
     if( termsInMem ){
       sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1);
     }
   }
-  assert( j==nEq );
 
   /* Make sure all the constraint values are on the top of the stack
   */
@@ -1850,8 +1906,7 @@ WhereInfo *sqlite3WhereBegin(
     for(j=iFrom, pTabItem=&pTabList->a[j]; j<pTabList->nSrc; j++, pTabItem++){
       int doNotReorder;  /* True if this table should not be reordered */
 
-      doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
-                   || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0);
+      doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
       if( once && doNotReorder ) break;
       m = getMask(&maskSet, pTabItem->iCursor);
       if( (m & notReady)==0 ){
@@ -1986,7 +2041,9 @@ WhereInfo *sqlite3WhereBegin(
       sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
                      (char*)pKey, P3_KEYINFO_HANDOFF);
     }
-    if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){
+    if( (pLevel->flags & (WHERE_IDX_ONLY|WHERE_COLUMN_RANGE))!=0 ){
+      /* Only call OP_SetNumColumns on the index if we might later use
+      ** OP_Column on the index. */
       sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
     }
     sqlite3CodeVerifySchema(pParse, iDb);
@@ -2025,7 +2082,7 @@ WhereInfo *sqlite3WhereBegin(
     ** initialize a memory cell that records if this table matches any
     ** row of the left table of the join.
     */
-    if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){
+    if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
       if( !pParse->nMem ) pParse->nMem++;
       pLevel->iLeftJoin = pParse->nMem++;
       sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin);
@@ -2159,7 +2216,6 @@ WhereInfo *sqlite3WhereBegin(
       int btmEq=0;        /* True if btm limit uses ==. False if strictly > */
       int topOp, btmOp;   /* Operators for the top and bottom search bounds */
       int testOp;
-      int nNotNull;       /* Number of rows of index that must be non-NULL */
       int topLimit = (pLevel->flags & WHERE_TOP_LIMIT)!=0;
       int btmLimit = (pLevel->flags & WHERE_BTM_LIMIT)!=0;
 
@@ -2181,7 +2237,6 @@ WhereInfo *sqlite3WhereBegin(
       ** operator and the top bound is a < or <= operator.  For a descending
       ** index the operators are reversed.
       */
-      nNotNull = nEq + topLimit;
       if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){
         topOp = WO_LT|WO_LE;
         btmOp = WO_GT|WO_GE;
@@ -2206,6 +2261,7 @@ WhereInfo *sqlite3WhereBegin(
         pX = pTerm->pExpr;
         assert( (pTerm->flags & TERM_CODED)==0 );
         sqlite3ExprCode(pParse, pX->pRight);
+        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
         topEq = pTerm->eOperator & (WO_LE|WO_GE);
         disableTerm(pLevel, pTerm);
         testOp = OP_IdxGE;
@@ -2216,7 +2272,7 @@ WhereInfo *sqlite3WhereBegin(
       if( testOp!=OP_Noop ){
         int nCol = nEq + topLimit;
         pLevel->iMem = pParse->nMem++;
-        buildIndexProbe(v, nCol, nEq, brk, pIdx);
+        buildIndexProbe(v, nCol, pIdx);
         if( bRev ){
           int op = topEq ? OP_MoveLe : OP_MoveLt;
           sqlite3VdbeAddOp(v, op, iIdxCur, brk);
@@ -2244,6 +2300,7 @@ WhereInfo *sqlite3WhereBegin(
         pX = pTerm->pExpr;
         assert( (pTerm->flags & TERM_CODED)==0 );
         sqlite3ExprCode(pParse, pX->pRight);
+        sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
         btmEq = pTerm->eOperator & (WO_LE|WO_GE);
         disableTerm(pLevel, pTerm);
       }else{
@@ -2251,7 +2308,7 @@ WhereInfo *sqlite3WhereBegin(
       }
       if( nEq>0 || btmLimit ){
         int nCol = nEq + btmLimit;
-        buildIndexProbe(v, nCol, 0, brk, pIdx);
+        buildIndexProbe(v, nCol, pIdx);
         if( bRev ){
           pLevel->iMem = pParse->nMem++;
           sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
@@ -2278,8 +2335,10 @@ WhereInfo *sqlite3WhereBegin(
           sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
         }
       }
-      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
-      sqlite3VdbeAddOp(v, OP_IdxIsNull, nNotNull, cont);
+      if( topLimit | btmLimit ){
+        sqlite3VdbeAddOp(v, OP_Column, iIdxCur, nEq);
+        sqlite3VdbeAddOp(v, OP_IsNull, 1, cont);
+      }
       if( !omitTable ){
         sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
         sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
@@ -2305,7 +2364,7 @@ WhereInfo *sqlite3WhereBegin(
       /* Generate a single key that will be used to both start and terminate
       ** the search
       */
-      buildIndexProbe(v, nEq, 0, brk, pIdx);
+      buildIndexProbe(v, nEq, pIdx);
       sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
 
       /* Generate code (1) to move to the first matching element of the table.
@@ -2326,8 +2385,6 @@ WhereInfo *sqlite3WhereBegin(
         sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC);
         pLevel->op = OP_Next;
       }
-      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
-      sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq, cont);
       if( !omitTable ){
         sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
         sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);