From ca9627e70852f6b2e835660df870fe3ab405882d Mon Sep 17 00:00:00 2001
From: "Suren A. Chilingaryan" <csa@suren.me>
Date: Sun, 1 Sep 2019 00:00:32 +0200
Subject: Initial import

---
 dev-php/pecl-sqlite/files/sqlite-svn.patch | 12200 +++++++++++++++++++++++++++
 1 file changed, 12200 insertions(+)
 create mode 100644 dev-php/pecl-sqlite/files/sqlite-svn.patch

(limited to 'dev-php/pecl-sqlite/files/sqlite-svn.patch')

diff --git a/dev-php/pecl-sqlite/files/sqlite-svn.patch b/dev-php/pecl-sqlite/files/sqlite-svn.patch
new file mode 100644
index 0000000..95b111b
--- /dev/null
+++ b/dev-php/pecl-sqlite/files/sqlite-svn.patch
@@ -0,0 +1,12200 @@
+diff -dPNur sqlite-1.0.3/CREDITS sqlite-svn/CREDITS
+--- sqlite-1.0.3/CREDITS	2004-04-29 22:58:31.000000000 +0000
++++ sqlite-svn/CREDITS	2012-10-09 13:36:42.760063980 +0000
+@@ -1,2 +1,2 @@
+-sqlite
++SQLite
+ Wez Furlong, Tal Peer, Marcus Boerger, Ilia Alshanetsky
+diff -dPNur sqlite-1.0.3/Makefile.frag sqlite-svn/Makefile.frag
+--- sqlite-1.0.3/Makefile.frag	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/Makefile.frag	2012-10-09 13:36:42.760063980 +0000
+@@ -0,0 +1,2 @@
++$(srcdir)/libsqlite/src/parse.c: $(srcdir)/libsqlite/src/parse.y
++	@$(LEMON) $(srcdir)/libsqlite/src/parse.y 
+diff -dPNur sqlite-1.0.3/README sqlite-svn/README
+--- sqlite-1.0.3/README	2003-04-17 01:37:42.000000000 +0000
++++ sqlite-svn/README	2012-10-09 13:36:42.760063980 +0000
+@@ -1,4 +1,4 @@
+-This is an extension for the SQLite Embeddable SQL Database Engine.
++This is an extension for the SQLite 2 Embeddable SQL Database Engine.
+ http://www.sqlite.org/
+ 
+ SQLite is a C library that implements an embeddable SQL database engine.
+diff -dPNur sqlite-1.0.3/TODO sqlite-svn/TODO
+--- sqlite-1.0.3/TODO	2003-06-26 18:30:12.000000000 +0000
++++ sqlite-svn/TODO	2012-10-09 13:36:42.760063980 +0000
+@@ -1,3 +1,20 @@
++CURRENT
++--------------------------------------
++- Discuss the pdo_sqlite2 situation. Either split into two extensions,
++  or research/implement alternatives. Currently configure does not
++  implement this pdo driver. sqlite_*() should always exist/work
++
++- Update notes/changelog to reflect (or inform) users of php-src changes
++  since version 1.0.3
++
++- Clarify that this extension exists for BC reasons, and is barely maintained
++
++- Consider moving ext/sqlite bugs to the PECL bug tracker
++
++OLD
++--------------------------------------
++- Implement a PDO driver, called sqlite2
++
+ - Transparent binary encoding of return values from PHP callback functions.
+ 
+ - Add user-space callback for the authorizer function (this is potentially
+@@ -5,8 +22,6 @@
+ 
+ - Add user-space callback to handle busy databases.
+ 
+-- Test-suite
+-
+   o Test how robust we are when a user-space function is registered as
+     a callback for a persistent connection in script A, then script B is
+ 	called that doesn't register the callback but does make use of the
+@@ -14,9 +29,6 @@
+ 	--> Our test suite doesn't allow us to test persistent connections
+ 	    at this time :/
+ 
+-- If building a ZTS build, -DTHREADSAFE while compiling libsqlite
+-
+-- If building a non-debug build, -DNDEBUG will disable the expensive
+-  asserts in the inner loop. (and double performance)
++- Use later version of built-in library
+ 
+ vim:tw=78
+diff -dPNur sqlite-1.0.3/config.m4 sqlite-svn/config.m4
+--- sqlite-1.0.3/config.m4	2004-07-10 12:50:18.000000000 +0000
++++ sqlite-svn/config.m4	2012-10-09 13:36:42.760063980 +0000
+@@ -1,55 +1,96 @@
+-dnl $Id: config.m4,v 1.16.2.5 2004/07/10 12:50:18 wez Exp $
++dnl $Id: config.m4 291414 2009-11-29 06:13:22Z rasmus $
+ dnl config.m4 for extension sqlite
+ dnl vim:et:ts=2:sw=2
+ 
+ PHP_ARG_WITH(sqlite, for sqlite support,
+-[  --with-sqlite           Include sqlite support])
++[  --without-sqlite=DIR    Do not include sqlite support.  DIR is the sqlite base
++                          install directory [BUNDLED]], yes)
++
++PHP_ARG_ENABLE(sqlite-utf8, whether to enable UTF-8 support in sqlite (default: ISO-8859-1),
++[  --enable-sqlite-utf8      SQLite: Enable UTF-8 support for SQLite], no, no)
++
++
++
++dnl
++dnl PHP_PROG_LEMON
++dnl
++dnl Search for lemon binary and check its version
++dnl
++AC_DEFUN([PHP_PROG_LEMON],[
++  # we only support certain lemon versions
++  lemon_version_list="1.0"
++
++  AC_CHECK_PROG(LEMON, lemon, lemon)
++  if test "$LEMON"; then
++    AC_CACHE_CHECK([for lemon version], php_cv_lemon_version, [
++      lemon_version=`$LEMON -x 2>/dev/null | $SED -e 's/^.* //'`
++      php_cv_lemon_version=invalid
++      for lemon_check_version in $lemon_version_list; do
++        if test "$lemon_version" = "$lemon_check_version"; then
++          php_cv_lemon_version="$lemon_check_version (ok)"
++        fi
++      done
++    ])
++  else
++    lemon_version=none
++  fi
++  case $php_cv_lemon_version in
++    ""|invalid[)]
++      lemon_msg="lemon versions supported for regeneration of libsqlite parsers: $lemon_version_list (found: $lemon_version)."
++      AC_MSG_WARN([$lemon_msg])
++      LEMON="exit 0;"
++      ;;
++  esac
++  PHP_SUBST(LEMON)
++])
++
+ 
+ if test "$PHP_SQLITE" != "no"; then
++  if test "$PHP_PDO" != "no"; then
++    PHP_CHECK_PDO_INCLUDES([], [AC_MSG_WARN([Cannot find php_pdo_driver.h.])])
++    if test -n "$pdo_inc_path"; then
++      AC_DEFINE([PHP_SQLITE2_HAVE_PDO], [1], [Have PDO])
++      pdo_inc_path="-I$pdo_inc_path"
++    fi
++  fi  
+ 
+   if test "$PHP_SQLITE" != "yes"; then
+     SEARCH_PATH="/usr/local /usr"
+     SEARCH_FOR="/include/sqlite.h"
+     if test -r $PHP_SQLITE/; then # path given as parameter
+-        SQLITE_DIR=$PHP_SQLITE
++      SQLITE_DIR=$PHP_SQLITE
+     else # search default path list
+-        AC_MSG_CHECKING([for sqlite files in default path])
+-        for i in $SEARCH_PATH ; do
++      AC_MSG_CHECKING([for sqlite files in default path])
++      for i in $SEARCH_PATH ; do
+         if test -r $i/$SEARCH_FOR; then
+-            SQLITE_DIR=$i
+-            AC_MSG_RESULT(found in $i)
++          SQLITE_DIR=$i
++          AC_MSG_RESULT(found in $i)
+         fi
+-        done
++      done
+     fi
+   
+     if test -z "$SQLITE_DIR"; then
+-        AC_MSG_RESULT([not found])
+-        AC_MSG_ERROR([Please reinstall the sqlite distribution from http://www.sqlite.org])
++      AC_MSG_RESULT([not found])
++      AC_MSG_ERROR([Please reinstall the sqlite distribution from http://www.sqlite.org])
+     fi
+ 
+-    PHP_ADD_INCLUDE($SQLITE_DIR/include)
+-
+-    LIBNAME=sqlite
+-    LIBSYMBOL=sqlite_open
+-
+-    PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
+-    [
+-        PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $SQLITE_DIR/lib, SQLITE_SHARED_LIBADD)
+-        AC_DEFINE(HAVE_SQLITELIB,1,[ ])
++    PHP_CHECK_LIBRARY(sqlite, sqlite_open, [
++      PHP_ADD_LIBRARY_WITH_PATH(sqlite, $SQLITE_DIR/$PHP_LIBDIR, SQLITE_SHARED_LIBADD)
++      PHP_ADD_INCLUDE($SQLITE_DIR/include)
+     ],[
+-        AC_MSG_ERROR([wrong sqlite lib version or lib not found])
++      AC_MSG_ERROR([wrong sqlite lib version or lib not found])
+     ],[
+-        -L$SQLITE_DIR/lib -lm
++      -L$SQLITE_DIR/$PHP_LIBDIR -lm
+     ])
+- 
+-    PHP_SUBST(SQLITE_SHARED_LIBADD)
+-    PHP_NEW_EXTENSION(sqlite, sqlite.c libsqlite/src/encode.c, $ext_shared)
++    SQLITE_MODULE_TYPE=external
++    PHP_SQLITE_CFLAGS=$pdo_inc_path
++    sqlite_extra_sources="libsqlite/src/encode.c"
+   else
+     # use bundled library
+-
+-    PHP_SQLITE_CFLAGS="-I@ext_srcdir@/libsqlite/src"
+-
+-    sources="libsqlite/src/opcodes.c
++    PHP_PROG_LEMON
++    SQLITE_MODULE_TYPE=builtin
++    PHP_SQLITE_CFLAGS="-I@ext_srcdir@/libsqlite/src -I@ext_builddir@/libsqlite/src $pdo_inc_path"
++    sqlite_extra_sources="libsqlite/src/opcodes.c \
+         libsqlite/src/parse.c libsqlite/src/encode.c \
+         libsqlite/src/auth.c libsqlite/src/btree.c libsqlite/src/build.c \
+         libsqlite/src/delete.c libsqlite/src/expr.c libsqlite/src/func.c \
+@@ -62,35 +103,46 @@
+         libsqlite/src/vacuum.c libsqlite/src/copy.c \
+         libsqlite/src/vdbeaux.c libsqlite/src/date.c \
+         libsqlite/src/where.c libsqlite/src/trigger.c"
+-    
+-    PHP_NEW_EXTENSION(sqlite, sqlite.c $sources, $ext_shared,,$PHP_SQLITE_CFLAGS)
+-    PHP_ADD_BUILD_DIR($ext_builddir/libsqlite)
+-    PHP_ADD_BUILD_DIR($ext_builddir/libsqlite/src)
+-    AC_CHECK_SIZEOF(char *,4)
++  fi
++  dnl
++  dnl Common for both bundled/external
++  dnl
++  sqlite_sources="sqlite.c sess_sqlite.c pdo_sqlite2.c $sqlite_extra_sources" 
++  PHP_NEW_EXTENSION(sqlite, $sqlite_sources, $ext_shared,,$PHP_SQLITE_CFLAGS)
++  PHP_ADD_EXTENSION_DEP(sqlite, spl, true)
++  PHP_ADD_EXTENSION_DEP(sqlite, pdo, true)
++
++  PHP_ADD_MAKEFILE_FRAGMENT
++  PHP_SUBST(SQLITE_SHARED_LIBADD)
++  PHP_INSTALL_HEADERS([$ext_builddir/libsqlite/src/sqlite.h])
++  
++  if test "$SQLITE_MODULE_TYPE" = "builtin"; then
++    PHP_ADD_BUILD_DIR($ext_builddir/libsqlite/src, 1)
++    AC_CHECK_SIZEOF(char *, 4)
+     AC_DEFINE(SQLITE_PTR_SZ, SIZEOF_CHAR_P, [Size of a pointer])
+     dnl use latin 1 for SQLite older than 2.8.9; the utf-8 handling 
+     dnl in funcs.c uses assert(), which is a bit silly and something 
+     dnl we want to avoid. This assert() was removed in SQLite 2.8.9.
+     if test "$PHP_SQLITE_UTF8" = "yes"; then
+-        SQLITE_ENCODING="UTF8"
+-        AC_DEFINE(SQLITE_UTF8, 1, [ ])
++      SQLITE_ENCODING="UTF8"
++      AC_DEFINE(SQLITE_UTF8, 1, [ ])
+     else
+-        SQLITE_ENCODING="ISO8859"
++      SQLITE_ENCODING="ISO8859"
+     fi
+     PHP_SUBST(SQLITE_ENCODING)
+ 
+     SQLITE_VERSION=`cat $ext_srcdir/libsqlite/VERSION`
+     PHP_SUBST(SQLITE_VERSION)
+-    
+-    sed -e s/--VERS--/$SQLITE_VERSION/ -e s/--ENCODING--/$SQLITE_ENCODING/ $ext_srcdir/libsqlite/src/sqlite.h.in >$ext_srcdir/libsqlite/src/sqlite.h
+ 
+-    if test "$ext_shared" = "no"; then
+-      echo '#include "php_config.h"' > $ext_srcdir/libsqlite/src/config.h
++    sed -e s/--VERS--/$SQLITE_VERSION/ -e s/--ENCODING--/$SQLITE_ENCODING/ $ext_srcdir/libsqlite/src/sqlite.h.in > $ext_builddir/libsqlite/src/sqlite.h
++
++    if test "$ext_shared" = "no" || test "$ext_srcdir" != "$abs_srcdir"; then
++      echo '#include <php_config.h>' > $ext_builddir/libsqlite/src/config.h
+     else
+-      echo "#include \"$abs_builddir/config.h\"" > $ext_srcdir/libsqlite/src/config.h
++      echo "#include \"$abs_builddir/config.h\"" > $ext_builddir/libsqlite/src/config.h
+     fi
+     
+-    cat >> $ext_srcdir/libsqlite/src/config.h <<EOF
++    cat >> $ext_builddir/libsqlite/src/config.h <<EOF
+ #if ZTS
+ # define THREADSAFE 1
+ #endif
+@@ -98,9 +150,8 @@
+ # define NDEBUG
+ #endif
+ EOF
+-
+   fi
+-
++  
+   AC_CHECK_FUNCS(usleep nanosleep)
+   AC_CHECK_HEADERS(time.h)
+ fi
+diff -dPNur sqlite-1.0.3/config.w32 sqlite-svn/config.w32
+--- sqlite-1.0.3/config.w32	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/config.w32	2012-10-09 13:36:42.760063980 +0000
+@@ -0,0 +1,39 @@
++// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $
++// vim:ft=javascript
++
++ARG_WITH("sqlite", "SQLite support", "no");
++
++if (PHP_SQLITE != "no") {
++	copy_and_subst(configure_module_dirname + "\\libsqlite\\src\\sqlite.h.in",
++		configure_module_dirname + "\\libsqlite\\src\\sqlite.h", new Array(
++			"--VERS--", file_get_contents(configure_module_dirname + "\\libsqlite\\VERSION").replace(new RegExp("[\r\n]+", "g"), ""),
++			"--ENCODING--", "ISO8859"
++		));
++	
++	FSO.CopyFile(configure_module_dirname + "\\libsqlite\\src\\sqlite_config.w32.h",
++	   	configure_module_dirname + "\\libsqlite\\src\\config.h");
++
++	if (FSO.FileExists(configure_module_dirname + "\\..\\pdo\\php_pdo_driver.h")) {
++		PHP_SQLITE2_PDO_CFLAGS = " /DPHP_SQLITE2_HAVE_PDO=1 /I " + configure_module_dirname + "\\..";
++		ADD_EXTENSION_DEP('sqlite', 'pdo')
++	} else {
++		PHP_SQLITE2_PDO_CFLAGS = "";
++	}
++	
++	EXTENSION("sqlite", "sqlite.c sess_sqlite.c pdo_sqlite2.c", null,
++		"/D PHP_SQLITE_EXPORTS /I " + configure_module_dirname + "/libsqlite/src" +
++		PHP_SQLITE2_PDO_CFLAGS);
++		
++	
++	ADD_SOURCES(configure_module_dirname + "/libsqlite/src", "opcodes.c parse.c encode.c \
++		auth.c btree.c build.c delete.c expr.c func.c hash.c insert.c \
++		main.c os.c pager.c printf.c random.c select.c table.c tokenize.c \
++		update.c util.c vdbe.c attach.c btree_rb.c pragma.c vacuum.c \
++		copy.c where.c trigger.c vdbeaux.c date.c", "sqlite");
++
++	AC_DEFINE("HAVE_SQLITE", 1, "SQLite support");
++	if (!PHP_SQLITE_SHARED) {
++		ADD_DEF_FILE(configure_module_dirname + "\\php_sqlite.def");
++	}
++	ADD_EXTENSION_DEP('sqlite', 'spl')
++}
+diff -dPNur sqlite-1.0.3/libsqlite/VERSION sqlite-svn/libsqlite/VERSION
+--- sqlite-1.0.3/libsqlite/VERSION	2004-07-10 11:43:20.000000000 +0000
++++ sqlite-svn/libsqlite/VERSION	2012-10-09 13:36:42.661358144 +0000
+@@ -1 +1 @@
+-2.8.14
++2.8.17
+diff -dPNur sqlite-1.0.3/libsqlite/src/attach.c sqlite-svn/libsqlite/src/attach.c
+--- sqlite-1.0.3/libsqlite/src/attach.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/attach.c	2012-10-09 13:36:42.531952680 +0000
+@@ -11,7 +11,7 @@
+ *************************************************************************
+ ** This file contains code used to implement the ATTACH and DETACH commands.
+ **
+-** $Id: attach.c,v 1.2.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: attach.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+diff -dPNur sqlite-1.0.3/libsqlite/src/auth.c sqlite-svn/libsqlite/src/auth.c
+--- sqlite-1.0.3/libsqlite/src/auth.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/auth.c	2012-10-09 13:36:42.541252205 +0000
+@@ -14,7 +14,7 @@
+ ** systems that do not need this facility may omit it by recompiling
+ ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
+ **
+-** $Id: auth.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: auth.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+@@ -111,6 +111,7 @@
+   const char *zCol;     /* Name of the column of the table */
+   int iSrc;             /* Index in pTabList->a[] of table being read */
+   const char *zDBase;   /* Name of database being accessed */
++  TriggerStack *pStack; /* The stack of current triggers */
+ 
+   if( db->xAuth==0 ) return;
+   assert( pExpr->op==TK_COLUMN );
+@@ -119,15 +120,14 @@
+   }
+   if( iSrc>=0 && iSrc<pTabList->nSrc ){
+     pTab = pTabList->a[iSrc].pTab;
+-  }else{
++  }else if( (pStack = pParse->trigStack)!=0 ){
+     /* This must be an attempt to read the NEW or OLD pseudo-tables
+     ** of a trigger.
+     */
+-    TriggerStack *pStack; /* The stack of current triggers */
+-    pStack = pParse->trigStack;
+-    assert( pStack!=0 );
+     assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
+     pTab = pStack->pTab;
++  }else{
++    return;
+   }
+   if( pTab==0 ) return;
+   if( pExpr->iColumn>=0 ){
+diff -dPNur sqlite-1.0.3/libsqlite/src/btree.c sqlite-svn/libsqlite/src/btree.c
+--- sqlite-1.0.3/libsqlite/src/btree.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/btree.c	2012-10-09 13:36:42.531952680 +0000
+@@ -9,7 +9,7 @@
+ **    May you share freely, never taking more than you give.
+ **
+ *************************************************************************
+-** $Id: btree.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: btree.c 195361 2005-09-07 15:11:33Z iliaa $
+ **
+ ** This file implements a external (disk-based) database using BTrees.
+ ** For a detailed discussion of BTrees, refer to
+diff -dPNur sqlite-1.0.3/libsqlite/src/btree.h sqlite-svn/libsqlite/src/btree.h
+--- sqlite-1.0.3/libsqlite/src/btree.h	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/btree.h	2012-10-09 13:36:42.531952680 +0000
+@@ -13,7 +13,7 @@
+ ** subsystem.  See comments in the source code for a detailed description
+ ** of what each interface routine does.
+ **
+-** @(#) $Id: btree.h,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** @(#) $Id: btree.h 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #ifndef _BTREE_H_
+ #define _BTREE_H_
+diff -dPNur sqlite-1.0.3/libsqlite/src/btree_rb.c sqlite-svn/libsqlite/src/btree_rb.c
+--- sqlite-1.0.3/libsqlite/src/btree_rb.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/btree_rb.c	2012-10-09 13:36:42.551252050 +0000
+@@ -9,7 +9,7 @@
+ **    May you share freely, never taking more than you give.
+ **
+ *************************************************************************
+-** $Id: btree_rb.c,v 1.2.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: btree_rb.c 195361 2005-09-07 15:11:33Z iliaa $
+ **
+ ** This file implements an in-core database using Red-Black balanced
+ ** binary trees.
+@@ -259,17 +259,16 @@
+  * concatenation of orig and val is returned. The original orig is deleted
+  * (using sqliteFree()).
+  */
+-static char *append_val(char * orig, char const * val)
+-{
++static char *append_val(char * orig, char const * val){
++  char *z;
+   if( !orig ){
+-    return sqliteStrDup( val );
++    z = sqliteStrDup( val );
+   } else{
+-    char * ret = 0;
+-    sqliteSetString(&ret, orig, val, (char*)0);
++    z = 0;
++    sqliteSetString(&z, orig, val, (char*)0);
+     sqliteFree( orig );
+-    return ret;
+   }
+-  assert(0);
++  return z;
+ }
+ 
+ /*
+@@ -723,13 +722,13 @@
+   pCur = *ppCur = sqliteMalloc(sizeof(RbtCursor));
+   if( sqlite_malloc_failed ) return SQLITE_NOMEM;
+   pCur->pTree  = sqliteHashFind(&tree->tblHash, 0, iTable);
++  assert( pCur->pTree );
+   pCur->pRbtree = tree;
+   pCur->iTree  = iTable;
+   pCur->pOps = &sqliteRbtreeCursorOps;
+   pCur->wrFlag = wrFlag;
+   pCur->pShared = pCur->pTree->pCursors;
+   pCur->pTree->pCursors = pCur;
+-  
+ 
+   assert( (*ppCur)->pTree );
+   return SQLITE_OK;
+@@ -1178,12 +1177,11 @@
+   if( !pCur->pNode ) return 0;
+   if( !pCur->pNode->pKey || ((amt + offset) <= pCur->pNode->nKey) ){
+     memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, amt);
+-    return amt;
+   }else{
+     memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, pCur->pNode->nKey-offset);
+-    return pCur->pNode->nKey-offset;
++    amt = pCur->pNode->nKey-offset;
+   }
+-  assert(0);
++  return amt;
+ }
+ 
+ static int memRbtreeDataSize(RbtCursor* pCur, int *pSize)
+@@ -1201,12 +1199,11 @@
+   if( !pCur->pNode ) return 0;
+   if( (amt + offset) <= pCur->pNode->nData ){
+     memcpy(zBuf, ((char*)pCur->pNode->pData)+offset, amt);
+-    return amt;
+   }else{
+     memcpy(zBuf, ((char*)pCur->pNode->pData)+offset ,pCur->pNode->nData-offset);
+-    return pCur->pNode->nData-offset;
++    amt = pCur->pNode->nData-offset;
+   }
+-  assert(0);
++  return amt;
+ }
+ 
+ static int memRbtreeCloseCursor(RbtCursor* pCur)
+@@ -1421,13 +1418,12 @@
+   assert(!"Cannot call sqliteRbtreeCursorDump");
+   return SQLITE_OK;
+ }
++#endif
+ 
+ static struct Pager *memRbtreePager(Rbtree* tree)
+ {
+-  assert(!"Cannot call sqliteRbtreePager");
+-  return SQLITE_OK;
++  return 0;
+ }
+-#endif
+ 
+ /*
+ ** Return the full pathname of the underlying database file.
+@@ -1463,10 +1459,9 @@
+     (char*(*)(Btree*,int*,int)) memRbtreeIntegrityCheck,
+     (const char*(*)(Btree*)) memRbtreeGetFilename,
+     (int(*)(Btree*,Btree*)) memRbtreeCopyFile,
+-
++    (struct Pager*(*)(Btree*)) memRbtreePager,
+ #ifdef SQLITE_TEST
+     (int(*)(Btree*,int,int)) memRbtreePageDump,
+-    (struct Pager*(*)(Btree*)) memRbtreePager
+ #endif
+ };
+ 
+diff -dPNur sqlite-1.0.3/libsqlite/src/build.c sqlite-svn/libsqlite/src/build.c
+--- sqlite-1.0.3/libsqlite/src/build.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/build.c	2012-10-09 13:36:42.520091164 +0000
+@@ -23,7 +23,7 @@
+ **     ROLLBACK
+ **     PRAGMA
+ **
+-** $Id: build.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: build.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include <ctype.h>
+@@ -1537,7 +1537,7 @@
+   if( pName && !db->init.busy ){
+     Index *pISameName;    /* Another index with the same name */
+     Table *pTSameName;    /* A table with same name as the index */
+-    zName = sqliteStrNDup(pName->z, pName->n);
++    zName = sqliteTableNameFromToken(pName);
+     if( zName==0 ) goto exit_create_index;
+     if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
+       sqliteErrorMsg(pParse, "index %s already exists", zName);
+@@ -1557,7 +1557,7 @@
+     sqliteSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
+     if( zName==0 ) goto exit_create_index;
+   }else{
+-    zName = sqliteStrNDup(pName->z, pName->n);
++    zName = sqliteTableNameFromToken(pName);
+   }
+ 
+   /* Check for authorization to create an index.
+diff -dPNur sqlite-1.0.3/libsqlite/src/config_static.w32.h sqlite-svn/libsqlite/src/config_static.w32.h
+--- sqlite-1.0.3/libsqlite/src/config_static.w32.h	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/libsqlite/src/config_static.w32.h	2012-10-09 13:36:42.551252050 +0000
+@@ -0,0 +1 @@
++#define SQLITE_PTR_SZ 4
+\ No newline at end of file
+diff -dPNur sqlite-1.0.3/libsqlite/src/copy.c sqlite-svn/libsqlite/src/copy.c
+--- sqlite-1.0.3/libsqlite/src/copy.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/copy.c	2012-10-09 13:36:42.541252205 +0000
+@@ -11,7 +11,7 @@
+ *************************************************************************
+ ** This file contains code used to implement the COPY command.
+ **
+-** $Id: copy.c,v 1.2.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: copy.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+diff -dPNur sqlite-1.0.3/libsqlite/src/date.c sqlite-svn/libsqlite/src/date.c
+--- sqlite-1.0.3/libsqlite/src/date.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/date.c	2012-10-09 13:36:42.541252205 +0000
+@@ -16,7 +16,7 @@
+ ** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
+ ** All other code has file scope.
+ **
+-** $Id: date.c,v 1.2.2.2 2004/07/10 12:25:34 wez Exp $
++** $Id: date.c 278363 2009-04-07 11:45:13Z kalle $
+ **
+ ** NOTES:
+ **
+@@ -53,6 +53,9 @@
+ #include <stdlib.h>
+ #include <assert.h>
+ #include <time.h>
++#ifndef PHP_WIN32
++#include "main/php_reentrancy.h"
++#endif
+ 
+ #ifndef SQLITE_OMIT_DATETIME_FUNCS
+ 
+@@ -397,7 +400,7 @@
+ static double localtimeOffset(DateTime *p){
+   DateTime x, y;
+   time_t t;
+-  struct tm *pTm;
++  struct tm *pTm, tmbuf;
+   x = *p;
+   computeYMD_HMS(&x);
+   if( x.Y<1971 || x.Y>=2038 ){
+@@ -416,7 +419,10 @@
+   computeJD(&x);
+   t = (x.rJD-2440587.5)*86400.0 + 0.5;
+   sqliteOsEnterMutex();
+-  pTm = localtime(&t);
++  pTm = php_localtime_r(&t, &tmbuf);
++  if (!pTm) {
++	  return 0;
++  }
+   y.Y = pTm->tm_year + 1900;
+   y.M = pTm->tm_mon + 1;
+   y.D = pTm->tm_mday;
+@@ -800,18 +806,20 @@
+         case 'H':  sprintf(&z[j],"%02d",x.h); j+=2; break;
+         case 'W': /* Fall thru */
+         case 'j': {
+-          int n;
++          int n;             /* Number of days since 1st day of year */
+           DateTime y = x;
+           y.validJD = 0;
+           y.M = 1;
+           y.D = 1;
+           computeJD(&y);
+-          n = x.rJD - y.rJD + 1;
++          n = x.rJD - y.rJD;
+           if( zFmt[i]=='W' ){
+-            sprintf(&z[j],"%02d",(n+6)/7);
++            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
++            wd = ((int)(x.rJD+0.5)) % 7;
++            sprintf(&z[j],"%02d",(n+7-wd)/7);
+             j += 2;
+           }else{
+-            sprintf(&z[j],"%03d",n);
++            sprintf(&z[j],"%03d",n+1);
+             j += 3;
+           }
+           break;
+@@ -847,19 +855,18 @@
+ ** external linkage.
+ */
+ void sqliteRegisterDateTimeFunctions(sqlite *db){
++#ifndef SQLITE_OMIT_DATETIME_FUNCS
+   static struct {
+      char *zName;
+      int nArg;
+      int dataType;
+      void (*xFunc)(sqlite_func*,int,const char**);
+   } aFuncs[] = {
+-#ifndef SQLITE_OMIT_DATETIME_FUNCS
+     { "julianday", -1, SQLITE_NUMERIC, juliandayFunc   },
+     { "date",      -1, SQLITE_TEXT,    dateFunc        },
+     { "time",      -1, SQLITE_TEXT,    timeFunc        },
+     { "datetime",  -1, SQLITE_TEXT,    datetimeFunc    },
+     { "strftime",  -1, SQLITE_TEXT,    strftimeFunc    },
+-#endif
+   };
+   int i;
+ 
+@@ -870,4 +877,5 @@
+       sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
+     }
+   }
++#endif
+ }
+diff -dPNur sqlite-1.0.3/libsqlite/src/delete.c sqlite-svn/libsqlite/src/delete.c
+--- sqlite-1.0.3/libsqlite/src/delete.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/delete.c	2012-10-09 13:36:42.531952680 +0000
+@@ -12,7 +12,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** to handle DELETE FROM statements.
+ **
+-** $Id: delete.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: delete.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+diff -dPNur sqlite-1.0.3/libsqlite/src/encode.c sqlite-svn/libsqlite/src/encode.c
+--- sqlite-1.0.3/libsqlite/src/encode.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/encode.c	2012-10-09 13:36:42.551252050 +0000
+@@ -15,7 +15,7 @@
+ ** data in an SQLite database.  The code in this file is not used by any other
+ ** part of the SQLite library.
+ **
+-** $Id: encode.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: encode.c 225725 2006-12-24 20:50:02Z iliaa $
+ */
+ #include <string.h>
+ #include <assert.h>
+@@ -176,9 +176,12 @@
+   int i, e;
+   unsigned char c;
+   e = *(in++);
++  if (e == 0) {
++    return 0;
++  }
+   i = 0;
+   while( (c = *(in++))!=0 ){
+-    if( c==1 ){
++    if (c == 1) {
+       c = *(in++) - 1;
+     }
+     out[i++] = c + e;
+diff -dPNur sqlite-1.0.3/libsqlite/src/expr.c sqlite-svn/libsqlite/src/expr.c
+--- sqlite-1.0.3/libsqlite/src/expr.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/expr.c	2012-10-09 13:36:42.551252050 +0000
+@@ -12,7 +12,7 @@
+ ** This file contains routines used for analyzing expressions and
+ ** for generating VDBE code that evaluates expressions in SQLite.
+ **
+-** $Id: expr.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: expr.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include <ctype.h>
+@@ -124,7 +124,7 @@
+   if( pNew==0 ) return 0;
+   memcpy(pNew, p, sizeof(*pNew));
+   if( p->token.z!=0 ){
+-    pNew->token.z = sqliteStrDup(p->token.z);
++    pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
+     pNew->token.dyn = 1;
+   }else{
+     assert( pNew->token.z==0 );
+@@ -155,7 +155,10 @@
+   if( pNew==0 ) return 0;
+   pNew->nExpr = pNew->nAlloc = p->nExpr;
+   pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
+-  if( pItem==0 ) return 0;  /* Leaks memory after a malloc failure */
++  if( pItem==0 ){
++    sqliteFree(pNew);
++    return 0;
++  }
+   for(i=0; i<p->nExpr; i++, pItem++){
+     Expr *pNewExpr, *pOldExpr;
+     pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
+diff -dPNur sqlite-1.0.3/libsqlite/src/func.c sqlite-svn/libsqlite/src/func.c
+--- sqlite-1.0.3/libsqlite/src/func.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/func.c	2012-10-09 13:36:42.551252050 +0000
+@@ -16,7 +16,7 @@
+ ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
+ ** All other code has file scope.
+ **
+-** $Id: func.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: func.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include <ctype.h>
+ #include <math.h>
+@@ -157,20 +157,20 @@
+ ** Implementation of the upper() and lower() SQL functions.
+ */
+ static void upperFunc(sqlite_func *context, int argc, const char **argv){
+-  char *z;
++  unsigned char *z;
+   int i;
+   if( argc<1 || argv[0]==0 ) return;
+-  z = sqlite_set_result_string(context, argv[0], -1);
++  z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
+   if( z==0 ) return;
+   for(i=0; z[i]; i++){
+     if( islower(z[i]) ) z[i] = toupper(z[i]);
+   }
+ }
+ static void lowerFunc(sqlite_func *context, int argc, const char **argv){
+-  char *z;
++  unsigned char *z;
+   int i;
+   if( argc<1 || argv[0]==0 ) return;
+-  z = sqlite_set_result_string(context, argv[0], -1);
++  z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
+   if( z==0 ) return;
+   for(i=0; z[i]; i++){
+     if( isupper(z[i]) ) z[i] = tolower(z[i]);
+@@ -517,26 +517,28 @@
+   int mask;    /* 0 for min() or 0xffffffff for max() */
+ 
+   assert( argc==2 );
++  if( argv[0]==0 ) return;  /* Ignore NULL values */
+   if( argv[1][0]=='n' ){
+     xCompare = sqliteCompare;
+   }else{
+     xCompare = strcmp;
+   }
+   mask = (int)sqlite_user_data(context);
++  assert( mask==0 || mask==-1 );
+   p = sqlite_aggregate_context(context, sizeof(*p));
+-  if( p==0 || argc<1 || argv[0]==0 ) return;
++  if( p==0 || argc<1 ) return;
+   if( p->z==0 || (xCompare(argv[0],p->z)^mask)<0 ){
+     int len;
+-    if( !p->zBuf[0] ){
++    if( p->zBuf[0] ){
+       sqliteFree(p->z);
+     }
+     len = strlen(argv[0]);
+     if( len < sizeof(p->zBuf)-1 ){
+       p->z = &p->zBuf[1];
+-      p->zBuf[0] = 1;
++      p->zBuf[0] = 0;
+     }else{
+       p->z = sqliteMalloc( len+1 );
+-      p->zBuf[0] = 0;
++      p->zBuf[0] = 1;
+       if( p->z==0 ) return;
+     }
+     strcpy(p->z, argv[0]);
+@@ -545,10 +547,10 @@
+ static void minMaxFinalize(sqlite_func *context){
+   MinMaxCtx *p;
+   p = sqlite_aggregate_context(context, sizeof(*p));
+-  if( p && p->z ){
++  if( p && p->z && p->zBuf[0]<2 ){
+     sqlite_set_result_string(context, p->z, strlen(p->z));
+   }
+-  if( p && !p->zBuf[0] ){
++  if( p && p->zBuf[0] ){
+     sqliteFree(p->z);
+   }
+ }
+@@ -621,7 +623,12 @@
+   int i;
+ 
+   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
+-    void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
++    void *pArg;
++    switch( aFuncs[i].argType ){
++      case 0:  pArg = 0;           break;
++      case 1:  pArg = db;          break;
++      case 2:  pArg = (void*)(-1); break;
++    }
+     sqlite_create_function(db, aFuncs[i].zName,
+            aFuncs[i].nArg, aFuncs[i].xFunc, pArg);
+     if( aFuncs[i].xFunc ){
+@@ -629,7 +636,12 @@
+     }
+   }
+   for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
+-    void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
++    void *pArg;
++    switch( aAggs[i].argType ){
++      case 0:  pArg = 0;           break;
++      case 1:  pArg = db;          break;
++      case 2:  pArg = (void*)(-1); break;
++    }
+     sqlite_create_aggregate(db, aAggs[i].zName,
+            aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);
+     sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);
+diff -dPNur sqlite-1.0.3/libsqlite/src/hash.c sqlite-svn/libsqlite/src/hash.c
+--- sqlite-1.0.3/libsqlite/src/hash.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/hash.c	2012-10-09 13:36:42.541252205 +0000
+@@ -12,7 +12,7 @@
+ ** This is the implementation of generic hash-tables
+ ** used in SQLite.
+ **
+-** $Id: hash.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: hash.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include <assert.h>
+diff -dPNur sqlite-1.0.3/libsqlite/src/hash.h sqlite-svn/libsqlite/src/hash.h
+--- sqlite-1.0.3/libsqlite/src/hash.h	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/hash.h	2012-10-09 13:36:42.541252205 +0000
+@@ -12,7 +12,7 @@
+ ** This is the header file for the generic hash-table implemenation
+ ** used in SQLite.
+ **
+-** $Id: hash.h,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: hash.h 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #ifndef _SQLITE_HASH_H_
+ #define _SQLITE_HASH_H_
+diff -dPNur sqlite-1.0.3/libsqlite/src/insert.c sqlite-svn/libsqlite/src/insert.c
+--- sqlite-1.0.3/libsqlite/src/insert.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/insert.c	2012-10-09 13:36:42.541252205 +0000
+@@ -12,7 +12,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** to handle INSERT statements in SQLite.
+ **
+-** $Id: insert.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: insert.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+diff -dPNur sqlite-1.0.3/libsqlite/src/libsqlite.dsp sqlite-svn/libsqlite/src/libsqlite.dsp
+--- sqlite-1.0.3/libsqlite/src/libsqlite.dsp	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/libsqlite/src/libsqlite.dsp	2012-10-09 13:36:42.541252205 +0000
+@@ -0,0 +1,353 @@
++# Microsoft Developer Studio Project File - Name="libsqlite" - Package Owner=<4>
++# Microsoft Developer Studio Generated Build File, Format Version 6.00
++# ** DO NOT EDIT **
++
++# TARGTYPE "Win32 (x86) Static Library" 0x0104
++
++CFG=libsqlite - Win32 Debug_TS
++!MESSAGE This is not a valid makefile. To build this project using NMAKE,
++!MESSAGE use the Export Makefile command and run
++!MESSAGE 
++!MESSAGE NMAKE /f "libsqlite.mak".
++!MESSAGE 
++!MESSAGE You can specify a configuration when running NMAKE
++!MESSAGE by defining the macro CFG on the command line. For example:
++!MESSAGE 
++!MESSAGE NMAKE /f "libsqlite.mak" CFG="libsqlite - Win32 Debug_TS"
++!MESSAGE 
++!MESSAGE Possible choices for configuration are:
++!MESSAGE 
++!MESSAGE "libsqlite - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
++!MESSAGE "libsqlite - Win32 Release_TS" (based on "Win32 (x86) Static Library")
++!MESSAGE "libsqlite - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")
++!MESSAGE 
++
++# Begin Project
++# PROP AllowPerConfigDependencies 0
++# PROP Scc_ProjName ""
++# PROP Scc_LocalPath ""
++CPP=cl.exe
++RSC=rc.exe
++
++!IF  "$(CFG)" == "libsqlite - Win32 Debug_TS"
++
++# PROP BASE Use_MFC 0
++# PROP BASE Use_Debug_Libraries 1
++# PROP BASE Output_Dir "Debug_TS"
++# PROP BASE Intermediate_Dir "Debug_TS"
++# PROP BASE Target_Dir ""
++# PROP Use_MFC 0
++# PROP Use_Debug_Libraries 1
++# PROP Output_Dir "..\..\Debug_TS"
++# PROP Intermediate_Dir "..\..\Debug_TS"
++# PROP Target_Dir ""
++# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
++# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /GZ /c
++# ADD BASE RSC /l 0x406 /d "_DEBUG"
++# ADD RSC /l 0x406 /d "_DEBUG"
++BSC32=bscmake.exe
++# ADD BASE BSC32 /nologo
++# ADD BSC32 /nologo
++LIB32=link.exe -lib
++# ADD BASE LIB32 /nologo
++# ADD LIB32 /nologo
++
++!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TS"
++
++# PROP BASE Use_MFC 0
++# PROP BASE Use_Debug_Libraries 0
++# PROP BASE Output_Dir "Release_TS"
++# PROP BASE Intermediate_Dir "Release_TS"
++# PROP BASE Target_Dir ""
++# PROP Use_MFC 0
++# PROP Use_Debug_Libraries 0
++# PROP Output_Dir "..\..\Release_TS"
++# PROP Intermediate_Dir "..\..\Release_TS"
++# PROP Target_Dir ""
++# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
++# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /c
++# ADD BASE RSC /l 0x406 /d "NDEBUG"
++# ADD RSC /l 0x406 /d "NDEBUG"
++BSC32=bscmake.exe
++# ADD BASE BSC32 /nologo
++# ADD BSC32 /nologo
++LIB32=link.exe -lib
++# ADD BASE LIB32 /nologo
++# ADD LIB32 /nologo
++
++!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TSDbg"
++
++# PROP BASE Use_MFC 0
++# PROP BASE Use_Debug_Libraries 0
++# PROP BASE Output_Dir "libsqlite___Win32_Release_TSDbg"
++# PROP BASE Intermediate_Dir "libsqlite___Win32_Release_TSDbg"
++# PROP BASE Target_Dir ""
++# PROP Use_MFC 0
++# PROP Use_Debug_Libraries 0
++# PROP Output_Dir "..\..\Release_TSDbg"
++# PROP Intermediate_Dir "..\..\Release_TSDbg"
++# PROP Target_Dir ""
++# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /c
++# ADD CPP /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /c
++# ADD BASE RSC /l 0x406 /d "NDEBUG"
++# ADD RSC /l 0x406 /d "NDEBUG"
++BSC32=bscmake.exe
++# ADD BASE BSC32 /nologo
++# ADD BSC32 /nologo
++LIB32=link.exe -lib
++# ADD BASE LIB32 /nologo /out:"Release_TS\libsqlite.lib"
++# ADD LIB32 /nologo
++
++!ENDIF 
++
++# Begin Target
++
++# Name "libsqlite - Win32 Debug_TS"
++# Name "libsqlite - Win32 Release_TS"
++# Name "libsqlite - Win32 Release_TSDbg"
++# Begin Group "Source Files"
++
++# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
++# Begin Source File
++
++SOURCE=attach.c
++# End Source File
++# Begin Source File
++
++SOURCE=auth.c
++# End Source File
++# Begin Source File
++
++SOURCE=btree.c
++# End Source File
++# Begin Source File
++
++SOURCE=btree_rb.c
++# End Source File
++# Begin Source File
++
++SOURCE=build.c
++# End Source File
++# Begin Source File
++
++SOURCE=copy.c
++# End Source File
++# Begin Source File
++
++SOURCE=.\date.c
++# End Source File
++# Begin Source File
++
++SOURCE=delete.c
++# End Source File
++# Begin Source File
++
++SOURCE=encode.c
++# End Source File
++# Begin Source File
++
++SOURCE=expr.c
++# End Source File
++# Begin Source File
++
++SOURCE=func.c
++# End Source File
++# Begin Source File
++
++SOURCE=hash.c
++# End Source File
++# Begin Source File
++
++SOURCE=insert.c
++# End Source File
++# Begin Source File
++
++SOURCE=main.c
++# End Source File
++# Begin Source File
++
++SOURCE=opcodes.c
++# End Source File
++# Begin Source File
++
++SOURCE=os.c
++# End Source File
++# Begin Source File
++
++SOURCE=pager.c
++# End Source File
++# Begin Source File
++
++SOURCE=parse.c
++# End Source File
++# Begin Source File
++
++SOURCE=pragma.c
++# End Source File
++# Begin Source File
++
++SOURCE=printf.c
++# End Source File
++# Begin Source File
++
++SOURCE=random.c
++# End Source File
++# Begin Source File
++
++SOURCE=select.c
++# End Source File
++# Begin Source File
++
++SOURCE=table.c
++# End Source File
++# Begin Source File
++
++SOURCE=tokenize.c
++# End Source File
++# Begin Source File
++
++SOURCE=trigger.c
++# End Source File
++# Begin Source File
++
++SOURCE=update.c
++# End Source File
++# Begin Source File
++
++SOURCE=util.c
++# End Source File
++# Begin Source File
++
++SOURCE=vacuum.c
++# End Source File
++# Begin Source File
++
++SOURCE=vdbe.c
++# End Source File
++# Begin Source File
++
++SOURCE=.\vdbeaux.c
++# End Source File
++# Begin Source File
++
++SOURCE=where.c
++# End Source File
++# End Group
++# Begin Group "Header Files"
++
++# PROP Default_Filter "h;hpp;hxx;hm;inl"
++# Begin Source File
++
++SOURCE=btree.h
++# End Source File
++# Begin Source File
++
++SOURCE=config_static.w32.h
++
++!IF  "$(CFG)" == "libsqlite - Win32 Debug_TS"
++
++# Begin Custom Build
++InputDir=.
++InputPath=config_static.w32.h
++
++"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
++	copy $(InputPath) $(InputDir)\config.h
++
++# End Custom Build
++
++!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TS"
++
++# Begin Custom Build
++InputDir=.
++InputPath=config_static.w32.h
++
++"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
++	copy $(InputPath) $(InputDir)\config.h
++
++# End Custom Build
++
++!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TSDbg"
++
++# Begin Custom Build
++InputDir=.
++InputPath=config_static.w32.h
++
++"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
++	copy $(InputPath) $(InputDir)\config.h
++
++# End Custom Build
++
++!ENDIF 
++
++# End Source File
++# Begin Source File
++
++SOURCE=hash.h
++# End Source File
++# Begin Source File
++
++SOURCE=opcodes.h
++# End Source File
++# Begin Source File
++
++SOURCE=os.h
++# End Source File
++# Begin Source File
++
++SOURCE=pager.h
++# End Source File
++# Begin Source File
++
++SOURCE=parse.h
++# End Source File
++# Begin Source File
++
++SOURCE=sqlite.w32.h
++
++!IF  "$(CFG)" == "libsqlite - Win32 Debug_TS"
++
++# Begin Custom Build
++InputDir=.
++InputPath=sqlite.w32.h
++
++"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
++	copy $(InputPath) $(InputDir)\sqlite.h
++
++# End Custom Build
++
++!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TS"
++
++# Begin Custom Build
++InputDir=.
++InputPath=sqlite.w32.h
++
++"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
++	copy $(InputPath) $(InputDir)\sqlite.h
++
++# End Custom Build
++
++!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TSDbg"
++
++# Begin Custom Build
++InputDir=.
++InputPath=sqlite.w32.h
++
++"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
++	copy $(InputPath) $(InputDir)\sqlite.h
++
++# End Custom Build
++
++!ENDIF 
++
++# End Source File
++# Begin Source File
++
++SOURCE=sqliteInt.h
++# End Source File
++# Begin Source File
++
++SOURCE=vdbe.h
++# End Source File
++# End Group
++# End Target
++# End Project
+diff -dPNur sqlite-1.0.3/libsqlite/src/main.c sqlite-svn/libsqlite/src/main.c
+--- sqlite-1.0.3/libsqlite/src/main.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/main.c	2012-10-09 13:36:42.551252050 +0000
+@@ -14,7 +14,7 @@
+ ** other files are for internal use by SQLite and should not be
+ ** accessed by users of the library.
+ **
+-** $Id: main.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: main.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include "os.h"
+@@ -189,10 +189,13 @@
+   BtCursor *curMain;
+   int size;
+   Table *pTab;
+-  char *azArg[6];
++  char const *azArg[6];
+   char zDbNum[30];
+   int meta[SQLITE_N_BTREE_META];
+   InitData initData;
++  char const *zMasterSchema;
++  char const *zMasterName;
++  char *zSql = 0;
+ 
+   /*
+   ** The master database table has a structure like this
+@@ -216,62 +219,38 @@
+      ")"
+   ;
+ 
+-  /* The following SQL will read the schema from the master tables.
+-  ** The first version works with SQLite file formats 2 or greater.
+-  ** The second version is for format 1 files.
+-  **
+-  ** Beginning with file format 2, the rowid for new table entries
+-  ** (including entries in sqlite_master) is an increasing integer.
+-  ** So for file format 2 and later, we can play back sqlite_master
+-  ** and all the CREATE statements will appear in the right order.
+-  ** But with file format 1, table entries were random and so we
+-  ** have to make sure the CREATE TABLEs occur before their corresponding
+-  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
+-  ** CREATE TRIGGER in file format 1 because those constructs did
+-  ** not exist then.) 
+-  */
+-  static char init_script[] = 
+-     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
+-     "UNION ALL "
+-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
+-  static char older_init_script[] = 
+-     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
+-     "UNION ALL "
+-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
+-     "WHERE type='table' "
+-     "UNION ALL "
+-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
+-     "WHERE type='index'";
+-
++  assert( iDb>=0 && iDb<db->nDb );
+ 
+-  assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
++  /* zMasterSchema and zInitScript are set to point at the master schema
++  ** and initialisation script appropriate for the database being
++  ** initialised. zMasterName is the name of the master table.
++  */
++  if( iDb==1 ){
++    zMasterSchema = temp_master_schema;
++    zMasterName = TEMP_MASTER_NAME;
++  }else{
++    zMasterSchema = master_schema;
++    zMasterName = MASTER_NAME;
++  }
+ 
+-  /* Construct the schema tables: sqlite_master and sqlite_temp_master
++  /* Construct the schema table.
+   */
+   sqliteSafetyOff(db);
+   azArg[0] = "table";
+-  azArg[1] = MASTER_NAME;
++  azArg[1] = zMasterName;
+   azArg[2] = "2";
+-  azArg[3] = master_schema;
++  azArg[3] = zMasterSchema;
+   sprintf(zDbNum, "%d", iDb);
+   azArg[4] = zDbNum;
+   azArg[5] = 0;
+   initData.db = db;
+   initData.pzErrMsg = pzErrMsg;
+-  sqliteInitCallback(&initData, 5, azArg, 0);
+-  pTab = sqliteFindTable(db, MASTER_NAME, "main");
++  sqliteInitCallback(&initData, 5, (char **)azArg, 0);
++  pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName);
+   if( pTab ){
+     pTab->readOnly = 1;
+-  }
+-  if( iDb==0 ){
+-    azArg[1] = TEMP_MASTER_NAME;
+-    azArg[3] = temp_master_schema;
+-    azArg[4] = "1";
+-    sqliteInitCallback(&initData, 5, azArg, 0);
+-    pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
+-    if( pTab ){
+-      pTab->readOnly = 1;
+-    }
++  }else{
++    return SQLITE_NOMEM;
+   }
+   sqliteSafetyOn(db);
+ 
+@@ -320,7 +299,7 @@
+       sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
+       return SQLITE_ERROR;
+     }
+-  }else if( db->file_format!=meta[2] || db->file_format<4 ){
++  }else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){
+     assert( db->file_format>=4 );
+     if( meta[2]==0 ){
+       sqliteSetString(pzErrMsg, "cannot attach empty database: ",
+@@ -340,18 +319,35 @@
+   */
+   assert( db->init.busy );
+   sqliteSafetyOff(db);
+-  if( iDb==0 ){
+-    rc = sqlite_exec(db, 
+-        db->file_format>=2 ? init_script : older_init_script,
+-        sqliteInitCallback, &initData, 0);
++
++  /* The following SQL will read the schema from the master tables.
++  ** The first version works with SQLite file formats 2 or greater.
++  ** The second version is for format 1 files.
++  **
++  ** Beginning with file format 2, the rowid for new table entries
++  ** (including entries in sqlite_master) is an increasing integer.
++  ** So for file format 2 and later, we can play back sqlite_master
++  ** and all the CREATE statements will appear in the right order.
++  ** But with file format 1, table entries were random and so we
++  ** have to make sure the CREATE TABLEs occur before their corresponding
++  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
++  ** CREATE TRIGGER in file format 1 because those constructs did
++  ** not exist then.) 
++  */
++  if( db->file_format>=2 ){
++    sqliteSetString(&zSql, 
++        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
++       db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
+   }else{
+-    char *zSql = 0;
+     sqliteSetString(&zSql, 
+-       "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
+-       db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
+-    rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
+-    sqliteFree(zSql);
++        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
++       db->aDb[iDb].zName, "\".", zMasterName, 
++       " WHERE type IN ('table', 'index')"
++       " ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0);
+   }
++  rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
++
++  sqliteFree(zSql);
+   sqliteSafetyOn(db);
+   sqliteBtreeCloseCursor(curMain);
+   if( sqlite_malloc_failed ){
+@@ -361,9 +357,6 @@
+   }
+   if( rc==SQLITE_OK ){
+     DbSetProperty(db, iDb, DB_SchemaLoaded);
+-    if( iDb==0 ){
+-      DbSetProperty(db, 1, DB_SchemaLoaded);
+-    }
+   }else{
+     sqliteResetInternalSchema(db, iDb);
+   }
+@@ -391,13 +384,24 @@
+   rc = SQLITE_OK;
+   db->init.busy = 1;
+   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+-    if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
+-    assert( i!=1 );  /* Should have been initialized together with 0 */
++    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
+     rc = sqliteInitOne(db, i, pzErrMsg);
+     if( rc ){
+       sqliteResetInternalSchema(db, i);
+     }
+   }
++
++  /* Once all the other databases have been initialised, load the schema
++  ** for the TEMP database. This is loaded last, as the TEMP database
++  ** schema may contain references to objects in other databases.
++  */
++  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
++    rc = sqliteInitOne(db, 1, pzErrMsg);
++    if( rc ){
++      sqliteResetInternalSchema(db, 1);
++    }
++  }
++
+   db->init.busy = 0;
+   if( rc==SQLITE_OK ){
+     db->flags |= SQLITE_Initialized;
+diff -dPNur sqlite-1.0.3/libsqlite/src/os.c sqlite-svn/libsqlite/src/os.c
+--- sqlite-1.0.3/libsqlite/src/os.c	2004-07-10 11:47:26.000000000 +0000
++++ sqlite-svn/libsqlite/src/os.c	2012-10-09 13:36:42.541252205 +0000
+@@ -830,7 +830,7 @@
+     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+     "0123456789";
+   int i, j;
+-  char *zDir;
++  const char *zDir;
+   char zTempPath[SQLITE_TEMPNAME_SIZE];
+   if( sqlite_temp_directory==0 ){
+     GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
+@@ -1116,6 +1116,10 @@
+ #endif
+ }
+ 
++#ifdef SQLITE_NOSYNC
++# define fsync(X) 0
++#endif
++
+ /*
+ ** Make sure all writes to a particular file are committed to disk.
+ **
+@@ -1774,6 +1778,7 @@
+     sqliteSetString(&zFull, zRelative, (char*)0);
+   }else{
+     char zBuf[5000];
++    zBuf[0] = 0;
+     sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
+                     (char*)0);
+   }
+diff -dPNur sqlite-1.0.3/libsqlite/src/pager.c sqlite-svn/libsqlite/src/pager.c
+--- sqlite-1.0.3/libsqlite/src/pager.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/pager.c	2012-10-09 13:36:42.541252205 +0000
+@@ -18,7 +18,7 @@
+ ** file simultaneously, or one process from reading the database while
+ ** another is writing.
+ **
+-** @(#) $Id: pager.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** @(#) $Id: pager.c 203289 2005-12-20 15:26:26Z iliaa $
+ */
+ #include "os.h"         /* Must be first to enable large file support */
+ #include "sqliteInt.h"
+@@ -1929,7 +1929,7 @@
+ 
+   pPg = pager_lookup(pPager, pgno);
+   pPg->alwaysRollback = 1;
+-  if( pPg && pPg->dirty ){
++  if( pPg && pPg->dirty && !pPager->ckptInUse ){
+     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.
+diff -dPNur sqlite-1.0.3/libsqlite/src/pager.h sqlite-svn/libsqlite/src/pager.h
+--- sqlite-1.0.3/libsqlite/src/pager.h	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/pager.h	2012-10-09 13:36:42.541252205 +0000
+@@ -13,7 +13,7 @@
+ ** subsystem.  The page cache subsystem reads and writes a file a page
+ ** at a time and provides a journal for rollback.
+ **
+-** @(#) $Id: pager.h,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** @(#) $Id: pager.h 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ 
+ /*
+diff -dPNur sqlite-1.0.3/libsqlite/src/parse.c sqlite-svn/libsqlite/src/parse.c
+--- sqlite-1.0.3/libsqlite/src/parse.c	2004-07-18 10:29:42.000000000 +0000
++++ sqlite-svn/libsqlite/src/parse.c	2012-10-09 13:36:42.541252205 +0000
+@@ -4,7 +4,7 @@
+ /* First off, code is include which follows the "include" declaration
+ ** in the input file. */
+ #include <stdio.h>
+-#line 33 "parse.y"
++#line 33 "ext/sqlite/libsqlite/src/parse.y"
+ 
+ #include "sqliteInt.h"
+ #include "parse.h"
+@@ -29,8 +29,7 @@
+ */
+ struct TrigEvent { int a; IdList * b; };
+ 
+-
+-#line 34 "parse.c"
++#line 34 "ext/sqlite/libsqlite/src/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.
+ */
+@@ -79,7 +78,6 @@
+ **    YYERRORSYMBOL      is the code number of the error symbol.  If not
+ **                       defined, then do no error processing.
+ */
+-/*  */
+ #define YYCODETYPE unsigned char
+ #define YYNOCODE 221
+ #define YYACTIONTYPE unsigned short int
+@@ -161,7 +159,7 @@
+ **                     shifting non-terminals after a reduce.
+ **  yy_default[]       Default action for each state.
+ */
+-static YYACTIONTYPE yy_action[] = {
++static const YYACTIONTYPE yy_action[] = {
+  /*     0 */   264,    5,  262,  119,  123,  117,  121,  129,  131,  133,
+  /*    10 */   135,  144,  146,  148,  150,  152,  154,  568,  106,  106,
+  /*    20 */   143,  857,    1,  562,    3,  142,  129,  131,  133,  135,
+@@ -292,7 +290,7 @@
+  /*  1270 */   556,  550,  850,  547,  549,  851,  555,  558,  551,  855,
+  /*  1280 */   553,  559,
+ };
+-static YYCODETYPE yy_lookahead[] = {
++static const YYCODETYPE yy_lookahead[] = {
+  /*     0 */    21,    9,   23,   70,   71,   72,   73,   74,   75,   76,
+  /*    10 */    77,   78,   79,   80,   81,   82,   83,    9,  140,  140,
+  /*    20 */    41,  132,  133,  134,  135,   46,   74,   75,   76,   77,
+@@ -424,7 +422,7 @@
+  /*  1280 */   219,  140,
+ };
+ #define YY_SHIFT_USE_DFLT (-68)
+-static short yy_shift_ofst[] = {
++static const short yy_shift_ofst[] = {
+  /*     0 */   170,  113,  -68,  746,   -8,  -68,    8,  127,  288,  239,
+  /*    10 */   348,  167,  -68,  -68,  -68,  -68,  -68,  -68,  547,  -68,
+  /*    20 */   -68,  -68,  -68,  115,  613,  115,  723,  115,  761,   44,
+@@ -484,7 +482,7 @@
+  /*   560 */   -68,  -68,  -68,
+ };
+ #define YY_REDUCE_USE_DFLT (-123)
+-static short yy_reduce_ofst[] = {
++static const short yy_reduce_ofst[] = {
+  /*     0 */  -111,   55, -123,  643, -123, -123, -123, -100,   82, -123,
+  /*    10 */  -123,  233, -123, -123, -123, -123, -123, -123,  310, -123,
+  /*    20 */  -123, -123, -123,  442, -123,  448, -123,  542, -123,  540,
+@@ -543,7 +541,7 @@
+  /*   550 */  -123, 1129, 1061, -123, 1124, -123, -123, 1059, 1141, -123,
+  /*   560 */  -123, -123, -123,
+ };
+-static YYACTIONTYPE yy_default[] = {
++static const YYACTIONTYPE yy_default[] = {
+  /*     0 */   570,  570,  564,  856,  856,  566,  856,  572,  856,  856,
+  /*    10 */   856,  856,  652,  655,  656,  657,  658,  659,  573,  574,
+  /*    20 */   591,  592,  593,  856,  856,  856,  856,  856,  856,  856,
+@@ -816,7 +814,7 @@
+ #ifndef NDEBUG
+ /* For tracing shifts, the names of all terminals and nonterminals
+ ** are required.  The following table supplies these names */
+-static const char *yyTokenName[] = { 
++static const char *const yyTokenName[] = { 
+   "$",             "END_OF_FILE",   "ILLEGAL",       "SPACE",       
+   "UNCLOSED_STRING",  "COMMENT",       "FUNCTION",      "COLUMN",      
+   "AGG_FUNCTION",  "SEMI",          "EXPLAIN",       "BEGIN",       
+@@ -878,7 +876,7 @@
+ #ifndef NDEBUG
+ /* For tracing reduce actions, the names of all rules are required.
+ */
+-static const char *yyRuleName[] = {
++static const char *const yyRuleName[] = {
+  /*   0 */ "input ::= cmdlist",
+  /*   1 */ "cmdlist ::= cmdlist ecmd",
+  /*   2 */ "cmdlist ::= ecmd",
+@@ -1230,149 +1228,61 @@
+     ** inside the C code.
+     */
+     case 146:
+-#line 286 "parse.y"
++    case 171:
++    case 189:
++#line 286 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteSelectDelete((yypminor->yy179));}
+-#line 1235 "parse.c"
++#line 1237 "ext/sqlite/libsqlite/src/parse.c"
+       break;
+     case 158:
+-#line 533 "parse.y"
++    case 176:
++    case 178:
++    case 187:
++    case 192:
++    case 204:
++#line 533 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteExprDelete((yypminor->yy242));}
+-#line 1240 "parse.c"
++#line 1247 "ext/sqlite/libsqlite/src/parse.c"
+       break;
+     case 159:
+-#line 746 "parse.y"
+-{sqliteIdListDelete((yypminor->yy320));}
+-#line 1245 "parse.c"
+-      break;
+     case 167:
+-#line 744 "parse.y"
++    case 188:
++    case 197:
++    case 199:
++#line 746 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteIdListDelete((yypminor->yy320));}
+-#line 1250 "parse.c"
+-      break;
+-    case 171:
+-#line 288 "parse.y"
+-{sqliteSelectDelete((yypminor->yy179));}
+-#line 1255 "parse.c"
++#line 1256 "ext/sqlite/libsqlite/src/parse.c"
+       break;
+     case 174:
+-#line 322 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1260 "parse.c"
+-      break;
+-    case 175:
+-#line 353 "parse.y"
+-{sqliteSrcListDelete((yypminor->yy307));}
+-#line 1265 "parse.c"
+-      break;
+-    case 176:
+-#line 483 "parse.y"
+-{sqliteExprDelete((yypminor->yy242));}
+-#line 1270 "parse.c"
+-      break;
+     case 177:
+-#line 459 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1275 "parse.c"
+-      break;
+-    case 178:
+-#line 464 "parse.y"
+-{sqliteExprDelete((yypminor->yy242));}
+-#line 1280 "parse.c"
+-      break;
+     case 179:
+-#line 431 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1285 "parse.c"
+-      break;
+     case 181:
+-#line 324 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1290 "parse.c"
+-      break;
+-    case 183:
+-#line 349 "parse.y"
+-{sqliteSrcListDelete((yypminor->yy307));}
+-#line 1295 "parse.c"
+-      break;
+-    case 184:
+-#line 351 "parse.y"
+-{sqliteSrcListDelete((yypminor->yy307));}
+-#line 1300 "parse.c"
+-      break;
+-    case 187:
+-#line 420 "parse.y"
+-{sqliteExprDelete((yypminor->yy242));}
+-#line 1305 "parse.c"
+-      break;
+-    case 188:
+-#line 425 "parse.y"
+-{sqliteIdListDelete((yypminor->yy320));}
+-#line 1310 "parse.c"
+-      break;
+-    case 189:
+-#line 400 "parse.y"
+-{sqliteSelectDelete((yypminor->yy179));}
+-#line 1315 "parse.c"
+-      break;
+     case 191:
+-#line 433 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1320 "parse.c"
+-      break;
+-    case 192:
+-#line 435 "parse.y"
+-{sqliteExprDelete((yypminor->yy242));}
+-#line 1325 "parse.c"
+-      break;
+     case 194:
+-#line 719 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1330 "parse.c"
+-      break;
+     case 195:
+-#line 489 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1335 "parse.c"
+-      break;
+-    case 197:
+-#line 520 "parse.y"
+-{sqliteIdListDelete((yypminor->yy320));}
+-#line 1340 "parse.c"
+-      break;
+     case 198:
+-#line 514 "parse.y"
+-{sqliteExprListDelete((yypminor->yy322));}
+-#line 1345 "parse.c"
+-      break;
+-    case 199:
+-#line 522 "parse.y"
+-{sqliteIdListDelete((yypminor->yy320));}
+-#line 1350 "parse.c"
+-      break;
+     case 202:
+-#line 702 "parse.y"
++#line 322 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteExprListDelete((yypminor->yy322));}
+-#line 1355 "parse.c"
++#line 1269 "ext/sqlite/libsqlite/src/parse.c"
+       break;
+-    case 204:
+-#line 721 "parse.y"
+-{sqliteExprDelete((yypminor->yy242));}
+-#line 1360 "parse.c"
++    case 175:
++    case 183:
++    case 184:
++#line 353 "ext/sqlite/libsqlite/src/parse.y"
++{sqliteSrcListDelete((yypminor->yy307));}
++#line 1276 "ext/sqlite/libsqlite/src/parse.c"
+       break;
+     case 212:
+-#line 828 "parse.y"
++    case 217:
++#line 828 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteDeleteTriggerStep((yypminor->yy19));}
+-#line 1365 "parse.c"
++#line 1282 "ext/sqlite/libsqlite/src/parse.c"
+       break;
+     case 214:
+-#line 812 "parse.y"
++#line 812 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteIdListDelete((yypminor->yy290).b);}
+-#line 1370 "parse.c"
+-      break;
+-    case 217:
+-#line 836 "parse.y"
+-{sqliteDeleteTriggerStep((yypminor->yy19));}
+-#line 1375 "parse.c"
++#line 1287 "ext/sqlite/libsqlite/src/parse.c"
+       break;
+     default:  break;   /* If no destructor action specified: do nothing */
+   }
+@@ -1479,11 +1389,11 @@
+ ** return YY_NO_ACTION.
+ */
+ static int yy_find_reduce_action(
+-  yyParser *pParser,        /* The parser */
++  int stateno,              /* Current state number */
+   int iLookAhead            /* The look-ahead token */
+ ){
+   int i;
+-  int stateno = pParser->yystack[pParser->yyidx].stateno;
++  /* int stateno = pParser->yystack[pParser->yyidx].stateno; */
+  
+   i = yy_reduce_ofst[stateno];
+   if( i==YY_REDUCE_USE_DFLT ){
+@@ -1544,7 +1454,7 @@
+ /* The following table contains information about every rule that
+ ** is used during the reduce.
+ */
+-static struct {
++static const struct {
+   YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
+   unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
+ } yyRuleInfo[] = {
+@@ -1868,6 +1778,18 @@
+   }
+ #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
++  ** not set the value of its left-hand side nonterminal.  Leaving the
++  ** 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.  
++  */
++  memset(&yygotominor, 0, sizeof(yygotominor));
++#endif
++
+   switch( yyruleno ){
+   /* Beginning here are the reduction cases.  A typical example
+   ** follows:
+@@ -1877,596 +1799,330 @@
+   **  #line <lineno> <thisfile>
+   **     break;
+   */
+-      case 0:
+-        /* No destructor defined for cmdlist */
+-        break;
+-      case 1:
+-        /* No destructor defined for cmdlist */
+-        /* No destructor defined for ecmd */
+-        break;
+-      case 2:
+-        /* No destructor defined for ecmd */
+-        break;
+-      case 3:
+-        /* No destructor defined for explain */
+-        /* No destructor defined for cmdx */
+-        /* No destructor defined for SEMI */
+-        break;
+-      case 4:
+-        /* No destructor defined for SEMI */
+-        break;
+       case 5:
+-#line 72 "parse.y"
++#line 72 "ext/sqlite/libsqlite/src/parse.y"
+ { sqliteExec(pParse); }
+-#line 1901 "parse.c"
+-        /* No destructor defined for cmd */
++#line 1807 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 6:
+-#line 73 "parse.y"
++#line 73 "ext/sqlite/libsqlite/src/parse.y"
+ { sqliteBeginParse(pParse, 1); }
+-#line 1907 "parse.c"
+-        /* No destructor defined for EXPLAIN */
++#line 1812 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 7:
+-#line 74 "parse.y"
++#line 74 "ext/sqlite/libsqlite/src/parse.y"
+ { sqliteBeginParse(pParse, 0); }
+-#line 1913 "parse.c"
++#line 1817 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 8:
+-#line 79 "parse.y"
++#line 79 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteBeginTransaction(pParse,yymsp[0].minor.yy372);}
+-#line 1918 "parse.c"
+-        /* No destructor defined for BEGIN */
+-        /* No destructor defined for trans_opt */
+-        break;
+-      case 9:
+-        break;
+-      case 10:
+-        /* No destructor defined for TRANSACTION */
+-        break;
+-      case 11:
+-        /* No destructor defined for TRANSACTION */
+-        /* No destructor defined for nm */
++#line 1822 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 12:
+-#line 83 "parse.y"
+-{sqliteCommitTransaction(pParse);}
+-#line 1934 "parse.c"
+-        /* No destructor defined for COMMIT */
+-        /* No destructor defined for trans_opt */
+-        break;
+       case 13:
+-#line 84 "parse.y"
++#line 83 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteCommitTransaction(pParse);}
+-#line 1941 "parse.c"
+-        /* No destructor defined for END */
+-        /* No destructor defined for trans_opt */
++#line 1828 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 14:
+-#line 85 "parse.y"
++#line 85 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteRollbackTransaction(pParse);}
+-#line 1948 "parse.c"
+-        /* No destructor defined for ROLLBACK */
+-        /* No destructor defined for trans_opt */
+-        break;
+-      case 15:
+-        /* No destructor defined for create_table */
+-        /* No destructor defined for create_table_args */
++#line 1833 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 16:
+-#line 90 "parse.y"
++#line 90 "ext/sqlite/libsqlite/src/parse.y"
+ {
+    sqliteStartTable(pParse,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy298,yymsp[-2].minor.yy372,0);
+ }
+-#line 1961 "parse.c"
+-        /* No destructor defined for TABLE */
++#line 1840 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 17:
+-#line 94 "parse.y"
++      case 74:
++      case 108:
++#line 94 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = 1;}
+-#line 1967 "parse.c"
+-        /* No destructor defined for TEMP */
++#line 1847 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 18:
+-#line 95 "parse.y"
++      case 73:
++      case 75:
++      case 86:
++      case 109:
++      case 110:
++#line 95 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = 0;}
+-#line 1973 "parse.c"
++#line 1857 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 19:
+-#line 96 "parse.y"
++#line 96 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteEndTable(pParse,&yymsp[0].minor.yy0,0);
+ }
+-#line 1980 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for columnlist */
+-        /* No destructor defined for conslist_opt */
++#line 1864 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 20:
+-#line 99 "parse.y"
++#line 99 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteEndTable(pParse,0,yymsp[0].minor.yy179);
+   sqliteSelectDelete(yymsp[0].minor.yy179);
+ }
+-#line 1991 "parse.c"
+-        /* No destructor defined for AS */
+-        break;
+-      case 21:
+-        /* No destructor defined for columnlist */
+-        /* No destructor defined for COMMA */
+-        /* No destructor defined for column */
+-        break;
+-      case 22:
+-        /* No destructor defined for column */
+-        break;
+-      case 23:
+-        /* No destructor defined for columnid */
+-        /* No destructor defined for type */
+-        /* No destructor defined for carglist */
++#line 1872 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 24:
+-#line 111 "parse.y"
++#line 111 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddColumn(pParse,&yymsp[0].minor.yy298);}
+-#line 2010 "parse.c"
++#line 1877 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 25:
+-#line 117 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 2015 "parse.c"
+-        break;
+       case 26:
+-#line 149 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 2020 "parse.c"
+-        break;
+       case 27:
+-#line 150 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 2025 "parse.c"
+-        break;
+       case 28:
+-#line 155 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 2030 "parse.c"
+-        break;
+       case 29:
+-#line 156 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 2035 "parse.c"
+-        break;
+       case 30:
+-#line 157 "parse.y"
++      case 256:
++      case 257:
++#line 117 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 2040 "parse.c"
+-        break;
+-      case 31:
++#line 1889 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 32:
+-#line 160 "parse.y"
++#line 160 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddColumnType(pParse,&yymsp[0].minor.yy298,&yymsp[0].minor.yy298);}
+-#line 2047 "parse.c"
++#line 1894 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 33:
+-#line 161 "parse.y"
++#line 161 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddColumnType(pParse,&yymsp[-3].minor.yy298,&yymsp[0].minor.yy0);}
+-#line 2052 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for signed */
++#line 1899 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 34:
+-#line 163 "parse.y"
++#line 163 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddColumnType(pParse,&yymsp[-5].minor.yy298,&yymsp[0].minor.yy0);}
+-#line 2059 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for signed */
+-        /* No destructor defined for COMMA */
+-        /* No destructor defined for signed */
++#line 1904 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 35:
+-#line 165 "parse.y"
++      case 128:
++      case 254:
++      case 255:
++#line 165 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy298 = yymsp[0].minor.yy298;}
+-#line 2068 "parse.c"
++#line 1912 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 36:
+-#line 166 "parse.y"
++      case 242:
++#line 166 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy298 = yymsp[-1].minor.yy298;}
+-#line 2073 "parse.c"
+-        /* No destructor defined for ids */
++#line 1918 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 37:
+-#line 168 "parse.y"
+-{ yygotominor.yy372 = atoi(yymsp[0].minor.yy0.z); }
+-#line 2079 "parse.c"
+-        break;
+       case 38:
+-#line 169 "parse.y"
++#line 168 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = atoi(yymsp[0].minor.yy0.z); }
+-#line 2084 "parse.c"
+-        /* No destructor defined for PLUS */
++#line 1924 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 39:
+-#line 170 "parse.y"
++#line 170 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = -atoi(yymsp[0].minor.yy0.z); }
+-#line 2090 "parse.c"
+-        /* No destructor defined for MINUS */
+-        break;
+-      case 40:
+-        /* No destructor defined for carglist */
+-        /* No destructor defined for carg */
+-        break;
+-      case 41:
+-        break;
+-      case 42:
+-        /* No destructor defined for CONSTRAINT */
+-        /* No destructor defined for nm */
+-        /* No destructor defined for ccons */
+-        break;
+-      case 43:
+-        /* No destructor defined for ccons */
++#line 1929 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 44:
+-#line 175 "parse.y"
+-{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+-#line 2110 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        break;
+       case 45:
+-#line 176 "parse.y"
+-{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+-#line 2116 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        break;
+       case 46:
+-#line 177 "parse.y"
+-{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+-#line 2122 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        break;
+       case 47:
+-#line 178 "parse.y"
+-{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+-#line 2128 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        /* No destructor defined for PLUS */
+-        break;
+-      case 48:
+-#line 179 "parse.y"
+-{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,1);}
+-#line 2135 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        /* No destructor defined for MINUS */
+-        break;
+       case 49:
+-#line 180 "parse.y"
+-{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+-#line 2142 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        break;
+       case 50:
+-#line 181 "parse.y"
++#line 175 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+-#line 2148 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        /* No destructor defined for PLUS */
++#line 1939 "ext/sqlite/libsqlite/src/parse.c"
+         break;
++      case 48:
+       case 51:
+-#line 182 "parse.y"
++#line 179 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,1);}
+-#line 2155 "parse.c"
+-        /* No destructor defined for DEFAULT */
+-        /* No destructor defined for MINUS */
+-        break;
+-      case 52:
+-        /* No destructor defined for DEFAULT */
+-        /* No destructor defined for NULL */
+-        break;
+-      case 53:
+-        /* No destructor defined for NULL */
+-        /* No destructor defined for onconf */
++#line 1945 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 54:
+-#line 189 "parse.y"
++#line 189 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddNotNull(pParse, yymsp[0].minor.yy372);}
+-#line 2170 "parse.c"
+-        /* No destructor defined for NOT */
+-        /* No destructor defined for NULL */
++#line 1950 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 55:
+-#line 190 "parse.y"
++#line 190 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddPrimaryKey(pParse,0,yymsp[0].minor.yy372);}
+-#line 2177 "parse.c"
+-        /* No destructor defined for PRIMARY */
+-        /* No destructor defined for KEY */
+-        /* No destructor defined for sortorder */
++#line 1955 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 56:
+-#line 191 "parse.y"
++#line 191 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteCreateIndex(pParse,0,0,0,yymsp[0].minor.yy372,0,0);}
+-#line 2185 "parse.c"
+-        /* No destructor defined for UNIQUE */
+-        break;
+-      case 57:
+-        /* No destructor defined for CHECK */
+-        /* No destructor defined for LP */
+-  yy_destructor(158,&yymsp[-2].minor);
+-        /* No destructor defined for RP */
+-        /* No destructor defined for onconf */
++#line 1960 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 58:
+-#line 194 "parse.y"
++#line 194 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteCreateForeignKey(pParse,0,&yymsp[-2].minor.yy298,yymsp[-1].minor.yy320,yymsp[0].minor.yy372);}
+-#line 2198 "parse.c"
+-        /* No destructor defined for REFERENCES */
++#line 1965 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 59:
+-#line 195 "parse.y"
++#line 195 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteDeferForeignKey(pParse,yymsp[0].minor.yy372);}
+-#line 2204 "parse.c"
++#line 1970 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 60:
+-#line 196 "parse.y"
++#line 196 "ext/sqlite/libsqlite/src/parse.y"
+ {
+    sqliteAddCollateType(pParse, sqliteCollateType(yymsp[0].minor.yy298.z, yymsp[0].minor.yy298.n));
+ }
+-#line 2211 "parse.c"
+-        /* No destructor defined for COLLATE */
++#line 1977 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 61:
+-#line 206 "parse.y"
++#line 206 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Restrict * 0x010101; }
+-#line 2217 "parse.c"
++#line 1982 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 62:
+-#line 207 "parse.y"
++#line 207 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = (yymsp[-1].minor.yy372 & yymsp[0].minor.yy407.mask) | yymsp[0].minor.yy407.value; }
+-#line 2222 "parse.c"
++#line 1987 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 63:
+-#line 209 "parse.y"
++#line 209 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy407.value = 0;     yygotominor.yy407.mask = 0x000000; }
+-#line 2227 "parse.c"
+-        /* No destructor defined for MATCH */
+-        /* No destructor defined for nm */
++#line 1992 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 64:
+-#line 210 "parse.y"
++#line 210 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy407.value = yymsp[0].minor.yy372;     yygotominor.yy407.mask = 0x0000ff; }
+-#line 2234 "parse.c"
+-        /* No destructor defined for ON */
+-        /* No destructor defined for DELETE */
++#line 1997 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 65:
+-#line 211 "parse.y"
++#line 211 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy407.value = yymsp[0].minor.yy372<<8;  yygotominor.yy407.mask = 0x00ff00; }
+-#line 2241 "parse.c"
+-        /* No destructor defined for ON */
+-        /* No destructor defined for UPDATE */
++#line 2002 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 66:
+-#line 212 "parse.y"
++#line 212 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy407.value = yymsp[0].minor.yy372<<16; yygotominor.yy407.mask = 0xff0000; }
+-#line 2248 "parse.c"
+-        /* No destructor defined for ON */
+-        /* No destructor defined for INSERT */
++#line 2007 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 67:
+-#line 214 "parse.y"
++#line 214 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_SetNull; }
+-#line 2255 "parse.c"
+-        /* No destructor defined for SET */
+-        /* No destructor defined for NULL */
++#line 2012 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 68:
+-#line 215 "parse.y"
++#line 215 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_SetDflt; }
+-#line 2262 "parse.c"
+-        /* No destructor defined for SET */
+-        /* No destructor defined for DEFAULT */
++#line 2017 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 69:
+-#line 216 "parse.y"
++#line 216 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Cascade; }
+-#line 2269 "parse.c"
+-        /* No destructor defined for CASCADE */
++#line 2022 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 70:
+-#line 217 "parse.y"
++#line 217 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Restrict; }
+-#line 2275 "parse.c"
+-        /* No destructor defined for RESTRICT */
++#line 2027 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 71:
+-#line 219 "parse.y"
+-{yygotominor.yy372 = yymsp[0].minor.yy372;}
+-#line 2281 "parse.c"
+-        /* No destructor defined for NOT */
+-        /* No destructor defined for DEFERRABLE */
+-        break;
+       case 72:
+-#line 220 "parse.y"
++      case 87:
++      case 164:
++#line 219 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = yymsp[0].minor.yy372;}
+-#line 2288 "parse.c"
+-        /* No destructor defined for DEFERRABLE */
+-        break;
+-      case 73:
+-#line 222 "parse.y"
+-{yygotominor.yy372 = 0;}
+-#line 2294 "parse.c"
+-        break;
+-      case 74:
+-#line 223 "parse.y"
+-{yygotominor.yy372 = 1;}
+-#line 2299 "parse.c"
+-        /* No destructor defined for INITIALLY */
+-        /* No destructor defined for DEFERRED */
+-        break;
+-      case 75:
+-#line 224 "parse.y"
+-{yygotominor.yy372 = 0;}
+-#line 2306 "parse.c"
+-        /* No destructor defined for INITIALLY */
+-        /* No destructor defined for IMMEDIATE */
+-        break;
+-      case 76:
+-        break;
+-      case 77:
+-        /* No destructor defined for COMMA */
+-        /* No destructor defined for conslist */
+-        break;
+-      case 78:
+-        /* No destructor defined for conslist */
+-        /* No destructor defined for COMMA */
+-        /* No destructor defined for tcons */
+-        break;
+-      case 79:
+-        /* No destructor defined for conslist */
+-        /* No destructor defined for tcons */
+-        break;
+-      case 80:
+-        /* No destructor defined for tcons */
+-        break;
+-      case 81:
+-        /* No destructor defined for CONSTRAINT */
+-        /* No destructor defined for nm */
++#line 2035 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 82:
+-#line 236 "parse.y"
++#line 236 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteAddPrimaryKey(pParse,yymsp[-2].minor.yy320,yymsp[0].minor.yy372);}
+-#line 2335 "parse.c"
+-        /* No destructor defined for PRIMARY */
+-        /* No destructor defined for KEY */
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
++#line 2040 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 83:
+-#line 238 "parse.y"
++#line 238 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteCreateIndex(pParse,0,0,yymsp[-2].minor.yy320,yymsp[0].minor.yy372,0,0);}
+-#line 2344 "parse.c"
+-        /* No destructor defined for UNIQUE */
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
+-        break;
+-      case 84:
+-        /* No destructor defined for CHECK */
+-  yy_destructor(158,&yymsp[-1].minor);
+-        /* No destructor defined for onconf */
++#line 2045 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 85:
+-#line 241 "parse.y"
++#line 241 "ext/sqlite/libsqlite/src/parse.y"
+ {
+     sqliteCreateForeignKey(pParse, yymsp[-6].minor.yy320, &yymsp[-3].minor.yy298, yymsp[-2].minor.yy320, yymsp[-1].minor.yy372);
+     sqliteDeferForeignKey(pParse, yymsp[0].minor.yy372);
+ }
+-#line 2360 "parse.c"
+-        /* No destructor defined for FOREIGN */
+-        /* No destructor defined for KEY */
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
+-        /* No destructor defined for REFERENCES */
+-        break;
+-      case 86:
+-#line 246 "parse.y"
+-{yygotominor.yy372 = 0;}
+-#line 2370 "parse.c"
+-        break;
+-      case 87:
+-#line 247 "parse.y"
+-{yygotominor.yy372 = yymsp[0].minor.yy372;}
+-#line 2375 "parse.c"
++#line 2053 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 88:
+-#line 255 "parse.y"
+-{ yygotominor.yy372 = OE_Default; }
+-#line 2380 "parse.c"
+-        break;
+-      case 89:
+-#line 256 "parse.y"
+-{ yygotominor.yy372 = yymsp[0].minor.yy372; }
+-#line 2385 "parse.c"
+-        /* No destructor defined for ON */
+-        /* No destructor defined for CONFLICT */
+-        break;
+       case 90:
+-#line 257 "parse.y"
++#line 255 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Default; }
+-#line 2392 "parse.c"
++#line 2059 "ext/sqlite/libsqlite/src/parse.c"
+         break;
++      case 89:
+       case 91:
+-#line 258 "parse.y"
++#line 256 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = yymsp[0].minor.yy372; }
+-#line 2397 "parse.c"
+-        /* No destructor defined for OR */
++#line 2065 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 92:
+-#line 259 "parse.y"
++#line 259 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Rollback; }
+-#line 2403 "parse.c"
+-        /* No destructor defined for ROLLBACK */
++#line 2070 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 93:
+-#line 260 "parse.y"
++      case 236:
++#line 260 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Abort; }
+-#line 2409 "parse.c"
+-        /* No destructor defined for ABORT */
++#line 2076 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 94:
+-#line 261 "parse.y"
++#line 261 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Fail; }
+-#line 2415 "parse.c"
+-        /* No destructor defined for FAIL */
++#line 2081 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 95:
+-#line 262 "parse.y"
++#line 262 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Ignore; }
+-#line 2421 "parse.c"
+-        /* No destructor defined for IGNORE */
++#line 2086 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 96:
+-#line 263 "parse.y"
++#line 263 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_Replace; }
+-#line 2427 "parse.c"
+-        /* No destructor defined for REPLACE */
++#line 2091 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 97:
+-#line 267 "parse.y"
++#line 267 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteDropTable(pParse,&yymsp[0].minor.yy298,0);}
+-#line 2433 "parse.c"
+-        /* No destructor defined for DROP */
+-        /* No destructor defined for TABLE */
++#line 2096 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 98:
+-#line 271 "parse.y"
++#line 271 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteCreateView(pParse, &yymsp[-5].minor.yy0, &yymsp[-2].minor.yy298, yymsp[0].minor.yy179, yymsp[-4].minor.yy372);
+ }
+-#line 2442 "parse.c"
+-        /* No destructor defined for VIEW */
+-        /* No destructor defined for AS */
++#line 2103 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 99:
+-#line 274 "parse.y"
++#line 274 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteDropTable(pParse, &yymsp[0].minor.yy298, 1);
+ }
+-#line 2451 "parse.c"
+-        /* No destructor defined for DROP */
+-        /* No destructor defined for VIEW */
++#line 2110 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 100:
+-#line 280 "parse.y"
++#line 280 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteSelect(pParse, yymsp[0].minor.yy179, SRT_Callback, 0, 0, 0, 0);
+   sqliteSelectDelete(yymsp[0].minor.yy179);
+ }
+-#line 2461 "parse.c"
++#line 2118 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 101:
+-#line 290 "parse.y"
++      case 125:
++#line 290 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy179 = yymsp[0].minor.yy179;}
+-#line 2466 "parse.c"
++#line 2124 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 102:
+-#line 291 "parse.y"
++#line 291 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   if( yymsp[0].minor.yy179 ){
+     yymsp[0].minor.yy179->op = yymsp[-1].minor.yy372;
+@@ -2474,137 +2130,107 @@
+   }
+   yygotominor.yy179 = yymsp[0].minor.yy179;
+ }
+-#line 2477 "parse.c"
++#line 2135 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 103:
+-#line 299 "parse.y"
++#line 299 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = TK_UNION;}
+-#line 2482 "parse.c"
+-        /* No destructor defined for UNION */
++#line 2140 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 104:
+-#line 300 "parse.y"
++#line 300 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = TK_ALL;}
+-#line 2488 "parse.c"
+-        /* No destructor defined for UNION */
+-        /* No destructor defined for ALL */
++#line 2145 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 105:
+-#line 301 "parse.y"
++#line 301 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = TK_INTERSECT;}
+-#line 2495 "parse.c"
+-        /* No destructor defined for INTERSECT */
++#line 2150 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 106:
+-#line 302 "parse.y"
++#line 302 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = TK_EXCEPT;}
+-#line 2501 "parse.c"
+-        /* No destructor defined for EXCEPT */
++#line 2155 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 107:
+-#line 304 "parse.y"
++#line 304 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy179 = sqliteSelectNew(yymsp[-6].minor.yy322,yymsp[-5].minor.yy307,yymsp[-4].minor.yy242,yymsp[-3].minor.yy322,yymsp[-2].minor.yy242,yymsp[-1].minor.yy322,yymsp[-7].minor.yy372,yymsp[0].minor.yy124.limit,yymsp[0].minor.yy124.offset);
+ }
+-#line 2509 "parse.c"
+-        /* No destructor defined for SELECT */
+-        break;
+-      case 108:
+-#line 312 "parse.y"
+-{yygotominor.yy372 = 1;}
+-#line 2515 "parse.c"
+-        /* No destructor defined for DISTINCT */
+-        break;
+-      case 109:
+-#line 313 "parse.y"
+-{yygotominor.yy372 = 0;}
+-#line 2521 "parse.c"
+-        /* No destructor defined for ALL */
+-        break;
+-      case 110:
+-#line 314 "parse.y"
+-{yygotominor.yy372 = 0;}
+-#line 2527 "parse.c"
++#line 2162 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 111:
+-#line 325 "parse.y"
++#line 325 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy322 = yymsp[-1].minor.yy322;}
+-#line 2532 "parse.c"
+-        /* No destructor defined for COMMA */
++#line 2167 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 112:
+-#line 326 "parse.y"
++      case 138:
++      case 148:
++#line 326 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy322 = 0;}
+-#line 2538 "parse.c"
++#line 2174 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 113:
+-#line 327 "parse.y"
++#line 327 "ext/sqlite/libsqlite/src/parse.y"
+ {
+    yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[-1].minor.yy242,yymsp[0].minor.yy298.n?&yymsp[0].minor.yy298:0);
+ }
+-#line 2545 "parse.c"
++#line 2181 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 114:
+-#line 330 "parse.y"
++#line 330 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy322 = sqliteExprListAppend(yymsp[-1].minor.yy322, sqliteExpr(TK_ALL, 0, 0, 0), 0);
+ }
+-#line 2552 "parse.c"
+-        /* No destructor defined for STAR */
++#line 2188 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 115:
+-#line 333 "parse.y"
++#line 333 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   Expr *pRight = sqliteExpr(TK_ALL, 0, 0, 0);
+   Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy298);
+   yygotominor.yy322 = sqliteExprListAppend(yymsp[-3].minor.yy322, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
+ }
+-#line 2562 "parse.c"
+-        /* No destructor defined for DOT */
+-        /* No destructor defined for STAR */
++#line 2197 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 116:
+-#line 343 "parse.y"
+-{ yygotominor.yy298 = yymsp[0].minor.yy298; }
+-#line 2569 "parse.c"
+-        /* No destructor defined for AS */
+-        break;
+       case 117:
+-#line 344 "parse.y"
++      case 288:
++#line 343 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy298 = yymsp[0].minor.yy298; }
+-#line 2575 "parse.c"
++#line 2204 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 118:
+-#line 345 "parse.y"
++#line 345 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy298.n = 0; }
+-#line 2580 "parse.c"
++#line 2209 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 119:
+-#line 357 "parse.y"
++#line 357 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy307 = sqliteMalloc(sizeof(*yygotominor.yy307));}
+-#line 2585 "parse.c"
++#line 2214 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 120:
+-#line 358 "parse.y"
++#line 358 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy307 = yymsp[0].minor.yy307;}
+-#line 2590 "parse.c"
+-        /* No destructor defined for FROM */
++#line 2219 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 121:
+-#line 363 "parse.y"
++#line 363 "ext/sqlite/libsqlite/src/parse.y"
+ {
+    yygotominor.yy307 = yymsp[-1].minor.yy307;
+    if( yygotominor.yy307 && yygotominor.yy307->nSrc>0 ) yygotominor.yy307->a[yygotominor.yy307->nSrc-1].jointype = yymsp[0].minor.yy372;
+ }
+-#line 2599 "parse.c"
++#line 2227 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 122:
+-#line 367 "parse.y"
++#line 367 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy307 = 0;}
+-#line 2604 "parse.c"
++#line 2232 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 123:
+-#line 368 "parse.y"
++#line 368 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy307 = sqliteSrcListAppend(yymsp[-5].minor.yy307,&yymsp[-4].minor.yy298,&yymsp[-3].minor.yy298);
+   if( yymsp[-2].minor.yy298.n ) sqliteSrcListAddAlias(yygotominor.yy307,&yymsp[-2].minor.yy298);
+@@ -2617,10 +2243,10 @@
+     else { sqliteIdListDelete(yymsp[0].minor.yy320); }
+   }
+ }
+-#line 2620 "parse.c"
++#line 2248 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 124:
+-#line 381 "parse.y"
++#line 381 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy307 = sqliteSrcListAppend(yymsp[-6].minor.yy307,0,0);
+   yygotominor.yy307->a[yygotominor.yy307->nSrc-1].pSelect = yymsp[-4].minor.yy179;
+@@ -2634,330 +2260,227 @@
+     else { sqliteIdListDelete(yymsp[0].minor.yy320); }
+   }
+ }
+-#line 2637 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
+-        break;
+-      case 125:
+-#line 401 "parse.y"
+-{yygotominor.yy179 = yymsp[0].minor.yy179;}
+-#line 2644 "parse.c"
++#line 2265 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 126:
+-#line 402 "parse.y"
++#line 402 "ext/sqlite/libsqlite/src/parse.y"
+ {
+    yygotominor.yy179 = sqliteSelectNew(0,yymsp[0].minor.yy307,0,0,0,0,0,-1,0);
+ }
+-#line 2651 "parse.c"
++#line 2272 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 127:
+-#line 407 "parse.y"
++#line 407 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy298.z=0; yygotominor.yy298.n=0;}
+-#line 2656 "parse.c"
+-        break;
+-      case 128:
+-#line 408 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy298;}
+-#line 2661 "parse.c"
+-        /* No destructor defined for DOT */
++#line 2277 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 129:
+-#line 412 "parse.y"
+-{ yygotominor.yy372 = JT_INNER; }
+-#line 2667 "parse.c"
+-        /* No destructor defined for COMMA */
+-        break;
+       case 130:
+-#line 413 "parse.y"
++#line 412 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = JT_INNER; }
+-#line 2673 "parse.c"
+-        /* No destructor defined for JOIN */
++#line 2283 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 131:
+-#line 414 "parse.y"
++#line 414 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+-#line 2679 "parse.c"
+-        /* No destructor defined for JOIN */
++#line 2288 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 132:
+-#line 415 "parse.y"
++#line 415 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy298,0); }
+-#line 2685 "parse.c"
+-        /* No destructor defined for JOIN */
++#line 2293 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 133:
+-#line 417 "parse.y"
++#line 417 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy298,&yymsp[-1].minor.yy298); }
+-#line 2691 "parse.c"
+-        /* No destructor defined for JOIN */
++#line 2298 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 134:
+-#line 421 "parse.y"
++      case 142:
++      case 151:
++      case 158:
++      case 227:
++      case 229:
++      case 233:
++#line 421 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = yymsp[0].minor.yy242;}
+-#line 2697 "parse.c"
+-        /* No destructor defined for ON */
++#line 2309 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 135:
+-#line 422 "parse.y"
++      case 150:
++      case 157:
++      case 228:
++      case 230:
++      case 234:
++#line 422 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = 0;}
+-#line 2703 "parse.c"
++#line 2319 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 136:
+-#line 426 "parse.y"
++      case 169:
++      case 239:
++#line 426 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy320 = yymsp[-1].minor.yy320;}
+-#line 2708 "parse.c"
+-        /* No destructor defined for USING */
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
++#line 2326 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 137:
+-#line 427 "parse.y"
++      case 168:
++      case 238:
++#line 427 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy320 = 0;}
+-#line 2716 "parse.c"
+-        break;
+-      case 138:
+-#line 437 "parse.y"
+-{yygotominor.yy322 = 0;}
+-#line 2721 "parse.c"
++#line 2333 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 139:
+-#line 438 "parse.y"
++      case 149:
++#line 438 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy322 = yymsp[0].minor.yy322;}
+-#line 2726 "parse.c"
+-        /* No destructor defined for ORDER */
+-        /* No destructor defined for BY */
++#line 2339 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 140:
+-#line 439 "parse.y"
++#line 439 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322,yymsp[-2].minor.yy242,0);
+   if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = yymsp[-1].minor.yy372+yymsp[0].minor.yy372;
+ }
+-#line 2736 "parse.c"
+-        /* No destructor defined for COMMA */
++#line 2347 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 141:
+-#line 443 "parse.y"
++#line 443 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy322 = sqliteExprListAppend(0,yymsp[-2].minor.yy242,0);
+   if( yygotominor.yy322 ) yygotominor.yy322->a[0].sortOrder = yymsp[-1].minor.yy372+yymsp[0].minor.yy372;
+ }
+-#line 2745 "parse.c"
+-        break;
+-      case 142:
+-#line 447 "parse.y"
+-{yygotominor.yy242 = yymsp[0].minor.yy242;}
+-#line 2750 "parse.c"
++#line 2355 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 143:
+-#line 452 "parse.y"
++      case 145:
++#line 452 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = SQLITE_SO_ASC;}
+-#line 2755 "parse.c"
+-        /* No destructor defined for ASC */
++#line 2361 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 144:
+-#line 453 "parse.y"
++#line 453 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = SQLITE_SO_DESC;}
+-#line 2761 "parse.c"
+-        /* No destructor defined for DESC */
+-        break;
+-      case 145:
+-#line 454 "parse.y"
+-{yygotominor.yy372 = SQLITE_SO_ASC;}
+-#line 2767 "parse.c"
++#line 2366 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 146:
+-#line 455 "parse.y"
++#line 455 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = SQLITE_SO_UNK;}
+-#line 2772 "parse.c"
++#line 2371 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 147:
+-#line 456 "parse.y"
++#line 456 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = sqliteCollateType(yymsp[0].minor.yy298.z, yymsp[0].minor.yy298.n);}
+-#line 2777 "parse.c"
+-        /* No destructor defined for COLLATE */
+-        break;
+-      case 148:
+-#line 460 "parse.y"
+-{yygotominor.yy322 = 0;}
+-#line 2783 "parse.c"
+-        break;
+-      case 149:
+-#line 461 "parse.y"
+-{yygotominor.yy322 = yymsp[0].minor.yy322;}
+-#line 2788 "parse.c"
+-        /* No destructor defined for GROUP */
+-        /* No destructor defined for BY */
+-        break;
+-      case 150:
+-#line 465 "parse.y"
+-{yygotominor.yy242 = 0;}
+-#line 2795 "parse.c"
+-        break;
+-      case 151:
+-#line 466 "parse.y"
+-{yygotominor.yy242 = yymsp[0].minor.yy242;}
+-#line 2800 "parse.c"
+-        /* No destructor defined for HAVING */
++#line 2376 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 152:
+-#line 469 "parse.y"
++#line 469 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy124.limit = -1; yygotominor.yy124.offset = 0;}
+-#line 2806 "parse.c"
++#line 2381 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 153:
+-#line 470 "parse.y"
++#line 470 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy124.limit = yymsp[0].minor.yy372; yygotominor.yy124.offset = 0;}
+-#line 2811 "parse.c"
+-        /* No destructor defined for LIMIT */
++#line 2386 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 154:
+-#line 472 "parse.y"
++#line 472 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy124.limit = yymsp[-2].minor.yy372; yygotominor.yy124.offset = yymsp[0].minor.yy372;}
+-#line 2817 "parse.c"
+-        /* No destructor defined for LIMIT */
+-        /* No destructor defined for OFFSET */
++#line 2391 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 155:
+-#line 474 "parse.y"
++#line 474 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy124.limit = yymsp[0].minor.yy372; yygotominor.yy124.offset = yymsp[-2].minor.yy372;}
+-#line 2824 "parse.c"
+-        /* No destructor defined for LIMIT */
+-        /* No destructor defined for COMMA */
++#line 2396 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 156:
+-#line 478 "parse.y"
++#line 478 "ext/sqlite/libsqlite/src/parse.y"
+ {
+    sqliteDeleteFrom(pParse, sqliteSrcListAppend(0,&yymsp[-2].minor.yy298,&yymsp[-1].minor.yy298), yymsp[0].minor.yy242);
+ }
+-#line 2833 "parse.c"
+-        /* No destructor defined for DELETE */
+-        /* No destructor defined for FROM */
+-        break;
+-      case 157:
+-#line 485 "parse.y"
+-{yygotominor.yy242 = 0;}
+-#line 2840 "parse.c"
+-        break;
+-      case 158:
+-#line 486 "parse.y"
+-{yygotominor.yy242 = yymsp[0].minor.yy242;}
+-#line 2845 "parse.c"
+-        /* No destructor defined for WHERE */
++#line 2403 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 159:
+-#line 494 "parse.y"
++#line 494 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteUpdate(pParse,sqliteSrcListAppend(0,&yymsp[-4].minor.yy298,&yymsp[-3].minor.yy298),yymsp[-1].minor.yy322,yymsp[0].minor.yy242,yymsp[-5].minor.yy372);}
+-#line 2851 "parse.c"
+-        /* No destructor defined for UPDATE */
+-        /* No destructor defined for SET */
++#line 2408 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 160:
+-#line 497 "parse.y"
++#line 497 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322,yymsp[0].minor.yy242,&yymsp[-2].minor.yy298);}
+-#line 2858 "parse.c"
+-        /* No destructor defined for COMMA */
+-        /* No destructor defined for EQ */
++#line 2413 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 161:
+-#line 498 "parse.y"
++#line 498 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,&yymsp[-2].minor.yy298);}
+-#line 2865 "parse.c"
+-        /* No destructor defined for EQ */
++#line 2418 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 162:
+-#line 504 "parse.y"
++#line 504 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteInsert(pParse, sqliteSrcListAppend(0,&yymsp[-6].minor.yy298,&yymsp[-5].minor.yy298), yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy320, yymsp[-8].minor.yy372);}
+-#line 2871 "parse.c"
+-        /* No destructor defined for INTO */
+-        /* No destructor defined for VALUES */
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
++#line 2423 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 163:
+-#line 506 "parse.y"
++#line 506 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteInsert(pParse, sqliteSrcListAppend(0,&yymsp[-3].minor.yy298,&yymsp[-2].minor.yy298), 0, yymsp[0].minor.yy179, yymsp[-1].minor.yy320, yymsp[-5].minor.yy372);}
+-#line 2880 "parse.c"
+-        /* No destructor defined for INTO */
+-        break;
+-      case 164:
+-#line 509 "parse.y"
+-{yygotominor.yy372 = yymsp[0].minor.yy372;}
+-#line 2886 "parse.c"
+-        /* No destructor defined for INSERT */
++#line 2428 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 165:
+-#line 510 "parse.y"
++#line 510 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = OE_Replace;}
+-#line 2892 "parse.c"
+-        /* No destructor defined for REPLACE */
++#line 2433 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 166:
+-#line 516 "parse.y"
++      case 231:
++#line 516 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[0].minor.yy242,0);}
+-#line 2898 "parse.c"
+-        /* No destructor defined for COMMA */
++#line 2439 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 167:
+-#line 517 "parse.y"
++      case 232:
++#line 517 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,0);}
+-#line 2904 "parse.c"
+-        break;
+-      case 168:
+-#line 524 "parse.y"
+-{yygotominor.yy320 = 0;}
+-#line 2909 "parse.c"
+-        break;
+-      case 169:
+-#line 525 "parse.y"
+-{yygotominor.yy320 = yymsp[-1].minor.yy320;}
+-#line 2914 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
++#line 2445 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 170:
+-#line 526 "parse.y"
++      case 240:
++#line 526 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy320 = sqliteIdListAppend(yymsp[-2].minor.yy320,&yymsp[0].minor.yy298);}
+-#line 2921 "parse.c"
+-        /* No destructor defined for COMMA */
++#line 2451 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 171:
+-#line 527 "parse.y"
++      case 241:
++#line 527 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy320 = sqliteIdListAppend(0,&yymsp[0].minor.yy298);}
+-#line 2927 "parse.c"
++#line 2457 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 172:
+-#line 535 "parse.y"
++#line 535 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = yymsp[-1].minor.yy242; sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+-#line 2932 "parse.c"
++#line 2462 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 173:
+-#line 536 "parse.y"
++#line 536 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_NULL, 0, 0, &yymsp[0].minor.yy0);}
+-#line 2937 "parse.c"
++#line 2467 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 174:
+-#line 537 "parse.y"
+-{yygotominor.yy242 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+-#line 2942 "parse.c"
+-        break;
+       case 175:
+-#line 538 "parse.y"
++#line 537 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+-#line 2947 "parse.c"
++#line 2473 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 176:
+-#line 539 "parse.y"
++#line 539 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy298);
+   Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy298);
+   yygotominor.yy242 = sqliteExpr(TK_DOT, temp1, temp2, 0);
+ }
+-#line 2956 "parse.c"
+-        /* No destructor defined for DOT */
++#line 2482 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 177:
+-#line 544 "parse.y"
++#line 544 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &yymsp[-4].minor.yy298);
+   Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy298);
+@@ -2965,126 +2488,109 @@
+   Expr *temp4 = sqliteExpr(TK_DOT, temp2, temp3, 0);
+   yygotominor.yy242 = sqliteExpr(TK_DOT, temp1, temp4, 0);
+ }
+-#line 2968 "parse.c"
+-        /* No destructor defined for DOT */
+-        /* No destructor defined for DOT */
++#line 2493 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 178:
+-#line 551 "parse.y"
++#line 551 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_INTEGER, 0, 0, &yymsp[0].minor.yy0);}
+-#line 2975 "parse.c"
++#line 2498 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 179:
+-#line 552 "parse.y"
++#line 552 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_FLOAT, 0, 0, &yymsp[0].minor.yy0);}
+-#line 2980 "parse.c"
++#line 2503 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 180:
+-#line 553 "parse.y"
++#line 553 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_STRING, 0, 0, &yymsp[0].minor.yy0);}
+-#line 2985 "parse.c"
++#line 2508 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 181:
+-#line 554 "parse.y"
++#line 554 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_VARIABLE, 0, 0, &yymsp[0].minor.yy0);
+   if( yygotominor.yy242 ) yygotominor.yy242->iTable = ++pParse->nVar;
+ }
+-#line 2993 "parse.c"
++#line 2516 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 182:
+-#line 558 "parse.y"
++#line 558 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExprFunction(yymsp[-1].minor.yy322, &yymsp[-3].minor.yy0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ }
+-#line 3001 "parse.c"
+-        /* No destructor defined for LP */
++#line 2524 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 183:
+-#line 562 "parse.y"
++#line 562 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExprFunction(0, &yymsp[-3].minor.yy0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ }
+-#line 3010 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for STAR */
++#line 2532 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 184:
+-#line 566 "parse.y"
++#line 566 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_AND, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3017 "parse.c"
+-        /* No destructor defined for AND */
++#line 2537 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 185:
+-#line 567 "parse.y"
++#line 567 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_OR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3023 "parse.c"
+-        /* No destructor defined for OR */
++#line 2542 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 186:
+-#line 568 "parse.y"
++#line 568 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_LT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3029 "parse.c"
+-        /* No destructor defined for LT */
++#line 2547 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 187:
+-#line 569 "parse.y"
++#line 569 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_GT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3035 "parse.c"
+-        /* No destructor defined for GT */
++#line 2552 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 188:
+-#line 570 "parse.y"
++#line 570 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_LE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3041 "parse.c"
+-        /* No destructor defined for LE */
++#line 2557 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 189:
+-#line 571 "parse.y"
++#line 571 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_GE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3047 "parse.c"
+-        /* No destructor defined for GE */
++#line 2562 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 190:
+-#line 572 "parse.y"
++#line 572 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_NE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3053 "parse.c"
+-        /* No destructor defined for NE */
++#line 2567 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 191:
+-#line 573 "parse.y"
++#line 573 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_EQ, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3059 "parse.c"
+-        /* No destructor defined for EQ */
++#line 2572 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 192:
+-#line 574 "parse.y"
++#line 574 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_BITAND, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3065 "parse.c"
+-        /* No destructor defined for BITAND */
++#line 2577 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 193:
+-#line 575 "parse.y"
++#line 575 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_BITOR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3071 "parse.c"
+-        /* No destructor defined for BITOR */
++#line 2582 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 194:
+-#line 576 "parse.y"
++#line 576 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_LSHIFT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3077 "parse.c"
+-        /* No destructor defined for LSHIFT */
++#line 2587 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 195:
+-#line 577 "parse.y"
++#line 577 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_RSHIFT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3083 "parse.c"
+-        /* No destructor defined for RSHIFT */
++#line 2592 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 196:
+-#line 578 "parse.y"
++#line 578 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   ExprList *pList = sqliteExprListAppend(0, yymsp[0].minor.yy242, 0);
+   pList = sqliteExprListAppend(pList, yymsp[-2].minor.yy242, 0);
+@@ -3092,10 +2598,10 @@
+   if( yygotominor.yy242 ) yygotominor.yy242->op = yymsp[-1].minor.yy372;
+   sqliteExprSpan(yygotominor.yy242, &yymsp[-2].minor.yy242->span, &yymsp[0].minor.yy242->span);
+ }
+-#line 3095 "parse.c"
++#line 2603 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 197:
+-#line 585 "parse.y"
++#line 585 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   ExprList *pList = sqliteExprListAppend(0, yymsp[0].minor.yy242, 0);
+   pList = sqliteExprListAppend(pList, yymsp[-3].minor.yy242, 0);
+@@ -3104,144 +2610,131 @@
+   yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,&yymsp[0].minor.yy242->span);
+ }
+-#line 3107 "parse.c"
+-        /* No destructor defined for NOT */
++#line 2615 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 198:
+-#line 594 "parse.y"
++#line 594 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = TK_LIKE;}
+-#line 3113 "parse.c"
+-        /* No destructor defined for LIKE */
++#line 2620 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 199:
+-#line 595 "parse.y"
++#line 595 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy372 = TK_GLOB;}
+-#line 3119 "parse.c"
+-        /* No destructor defined for GLOB */
++#line 2625 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 200:
+-#line 596 "parse.y"
++#line 596 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_PLUS, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3125 "parse.c"
+-        /* No destructor defined for PLUS */
++#line 2630 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 201:
+-#line 597 "parse.y"
++#line 597 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_MINUS, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3131 "parse.c"
+-        /* No destructor defined for MINUS */
++#line 2635 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 202:
+-#line 598 "parse.y"
++#line 598 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_STAR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3137 "parse.c"
+-        /* No destructor defined for STAR */
++#line 2640 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 203:
+-#line 599 "parse.y"
++#line 599 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_SLASH, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3143 "parse.c"
+-        /* No destructor defined for SLASH */
++#line 2645 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 204:
+-#line 600 "parse.y"
++#line 600 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_REM, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3149 "parse.c"
+-        /* No destructor defined for REM */
++#line 2650 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 205:
+-#line 601 "parse.y"
++#line 601 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy242 = sqliteExpr(TK_CONCAT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+-#line 3155 "parse.c"
+-        /* No destructor defined for CONCAT */
++#line 2655 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 206:
+-#line 602 "parse.y"
++#line 602 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_ISNULL, yymsp[-1].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3164 "parse.c"
++#line 2663 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 207:
+-#line 606 "parse.y"
++#line 606 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_ISNULL, yymsp[-2].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3172 "parse.c"
+-        /* No destructor defined for IS */
++#line 2671 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 208:
+-#line 610 "parse.y"
++#line 610 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-1].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3181 "parse.c"
++#line 2679 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 209:
+-#line 614 "parse.y"
++#line 614 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-2].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3189 "parse.c"
+-        /* No destructor defined for NOT */
++#line 2687 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 210:
+-#line 618 "parse.y"
++#line 618 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-3].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3198 "parse.c"
+-        /* No destructor defined for IS */
+-        /* No destructor defined for NOT */
++#line 2695 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 211:
+-#line 622 "parse.y"
++#line 622 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_NOT, yymsp[0].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+ }
+-#line 3208 "parse.c"
++#line 2703 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 212:
+-#line 626 "parse.y"
++#line 626 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_BITNOT, yymsp[0].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+ }
+-#line 3216 "parse.c"
++#line 2711 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 213:
+-#line 630 "parse.y"
++#line 630 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_UMINUS, yymsp[0].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+ }
+-#line 3224 "parse.c"
++#line 2719 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 214:
+-#line 634 "parse.y"
++#line 634 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_UPLUS, yymsp[0].minor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+ }
+-#line 3232 "parse.c"
++#line 2727 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 215:
+-#line 638 "parse.y"
++#line 638 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_SELECT, 0, 0, 0);
+   if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ }
+-#line 3241 "parse.c"
++#line 2736 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 216:
+-#line 643 "parse.y"
++#line 643 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   ExprList *pList = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
+   pList = sqliteExprListAppend(pList, yymsp[0].minor.yy242, 0);
+@@ -3249,12 +2742,10 @@
+   if( yygotominor.yy242 ) yygotominor.yy242->pList = pList;
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy242->span);
+ }
+-#line 3252 "parse.c"
+-        /* No destructor defined for BETWEEN */
+-        /* No destructor defined for AND */
++#line 2747 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 217:
+-#line 650 "parse.y"
++#line 650 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   ExprList *pList = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
+   pList = sqliteExprListAppend(pList, yymsp[0].minor.yy242, 0);
+@@ -3263,72 +2754,58 @@
+   yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy242->span);
+ }
+-#line 3266 "parse.c"
+-        /* No destructor defined for NOT */
+-        /* No destructor defined for BETWEEN */
+-        /* No destructor defined for AND */
++#line 2759 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 218:
+-#line 658 "parse.y"
++#line 658 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
+   if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-1].minor.yy322;
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3278 "parse.c"
+-        /* No destructor defined for IN */
+-        /* No destructor defined for LP */
++#line 2768 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 219:
+-#line 663 "parse.y"
++#line 663 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
+   if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3289 "parse.c"
+-        /* No destructor defined for IN */
+-        /* No destructor defined for LP */
++#line 2777 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 220:
+-#line 668 "parse.y"
++#line 668 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-5].minor.yy242, 0, 0);
+   if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-1].minor.yy322;
+   yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3301 "parse.c"
+-        /* No destructor defined for NOT */
+-        /* No destructor defined for IN */
+-        /* No destructor defined for LP */
++#line 2787 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 221:
+-#line 674 "parse.y"
++#line 674 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-5].minor.yy242, 0, 0);
+   if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
+   yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy0);
+ }
+-#line 3314 "parse.c"
+-        /* No destructor defined for NOT */
+-        /* No destructor defined for IN */
+-        /* No destructor defined for LP */
++#line 2797 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 222:
+-#line 680 "parse.y"
++#line 680 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-1].minor.yy298, &yymsp[0].minor.yy298);
+   yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-3].minor.yy242, 0, 0);
+   if( yygotominor.yy242 ) yygotominor.yy242->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,yymsp[0].minor.yy298.z?&yymsp[0].minor.yy298:&yymsp[-1].minor.yy298);
+ }
+-#line 3327 "parse.c"
+-        /* No destructor defined for IN */
++#line 2807 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 223:
+-#line 686 "parse.y"
++#line 686 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-1].minor.yy298, &yymsp[0].minor.yy298);
+   yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
+@@ -3336,489 +2813,298 @@
+   yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+   sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,yymsp[0].minor.yy298.z?&yymsp[0].minor.yy298:&yymsp[-1].minor.yy298);
+ }
+-#line 3339 "parse.c"
+-        /* No destructor defined for NOT */
+-        /* No destructor defined for IN */
++#line 2818 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 224:
+-#line 696 "parse.y"
++#line 696 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_CASE, yymsp[-3].minor.yy242, yymsp[-1].minor.yy242, 0);
+   if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-2].minor.yy322;
+   sqliteExprSpan(yygotominor.yy242, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+ }
+-#line 3350 "parse.c"
++#line 2827 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 225:
+-#line 703 "parse.y"
++#line 703 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322, yymsp[-2].minor.yy242, 0);
+   yygotominor.yy322 = sqliteExprListAppend(yygotominor.yy322, yymsp[0].minor.yy242, 0);
+ }
+-#line 3358 "parse.c"
+-        /* No destructor defined for WHEN */
+-        /* No destructor defined for THEN */
++#line 2835 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 226:
+-#line 707 "parse.y"
++#line 707 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy322 = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
+   yygotominor.yy322 = sqliteExprListAppend(yygotominor.yy322, yymsp[0].minor.yy242, 0);
+ }
+-#line 3368 "parse.c"
+-        /* No destructor defined for WHEN */
+-        /* No destructor defined for THEN */
+-        break;
+-      case 227:
+-#line 712 "parse.y"
+-{yygotominor.yy242 = yymsp[0].minor.yy242;}
+-#line 3375 "parse.c"
+-        /* No destructor defined for ELSE */
+-        break;
+-      case 228:
+-#line 713 "parse.y"
+-{yygotominor.yy242 = 0;}
+-#line 3381 "parse.c"
+-        break;
+-      case 229:
+-#line 715 "parse.y"
+-{yygotominor.yy242 = yymsp[0].minor.yy242;}
+-#line 3386 "parse.c"
+-        break;
+-      case 230:
+-#line 716 "parse.y"
+-{yygotominor.yy242 = 0;}
+-#line 3391 "parse.c"
+-        break;
+-      case 231:
+-#line 724 "parse.y"
+-{yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[0].minor.yy242,0);}
+-#line 3396 "parse.c"
+-        /* No destructor defined for COMMA */
+-        break;
+-      case 232:
+-#line 725 "parse.y"
+-{yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,0);}
+-#line 3402 "parse.c"
+-        break;
+-      case 233:
+-#line 726 "parse.y"
+-{yygotominor.yy242 = yymsp[0].minor.yy242;}
+-#line 3407 "parse.c"
+-        break;
+-      case 234:
+-#line 727 "parse.y"
+-{yygotominor.yy242 = 0;}
+-#line 3412 "parse.c"
++#line 2843 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 235:
+-#line 732 "parse.y"
++#line 732 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-5].minor.yy298, &yymsp[-4].minor.yy298);
+   if( yymsp[-9].minor.yy372!=OE_None ) yymsp[-9].minor.yy372 = yymsp[0].minor.yy372;
+   if( yymsp[-9].minor.yy372==OE_Default) yymsp[-9].minor.yy372 = OE_Abort;
+   sqliteCreateIndex(pParse, &yymsp[-7].minor.yy298, pSrc, yymsp[-2].minor.yy320, yymsp[-9].minor.yy372, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0);
+ }
+-#line 3422 "parse.c"
+-        /* No destructor defined for INDEX */
+-        /* No destructor defined for ON */
+-        /* No destructor defined for LP */
+-        break;
+-      case 236:
+-#line 740 "parse.y"
+-{ yygotominor.yy372 = OE_Abort; }
+-#line 3430 "parse.c"
+-        /* No destructor defined for UNIQUE */
++#line 2853 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 237:
+-#line 741 "parse.y"
++#line 741 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = OE_None; }
+-#line 3436 "parse.c"
+-        break;
+-      case 238:
+-#line 749 "parse.y"
+-{yygotominor.yy320 = 0;}
+-#line 3441 "parse.c"
+-        break;
+-      case 239:
+-#line 750 "parse.y"
+-{yygotominor.yy320 = yymsp[-1].minor.yy320;}
+-#line 3446 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
+-        break;
+-      case 240:
+-#line 751 "parse.y"
+-{yygotominor.yy320 = sqliteIdListAppend(yymsp[-2].minor.yy320,&yymsp[0].minor.yy298);}
+-#line 3453 "parse.c"
+-        /* No destructor defined for COMMA */
+-        break;
+-      case 241:
+-#line 752 "parse.y"
+-{yygotominor.yy320 = sqliteIdListAppend(0,&yymsp[0].minor.yy298);}
+-#line 3459 "parse.c"
+-        break;
+-      case 242:
+-#line 753 "parse.y"
+-{yygotominor.yy298 = yymsp[-1].minor.yy298;}
+-#line 3464 "parse.c"
+-        /* No destructor defined for sortorder */
++#line 2858 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 243:
+-#line 758 "parse.y"
++#line 758 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteDropIndex(pParse, sqliteSrcListAppend(0,&yymsp[-1].minor.yy298,&yymsp[0].minor.yy298));
+ }
+-#line 3472 "parse.c"
+-        /* No destructor defined for DROP */
+-        /* No destructor defined for INDEX */
++#line 2865 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 244:
+-#line 766 "parse.y"
++#line 766 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteCopy(pParse,sqliteSrcListAppend(0,&yymsp[-6].minor.yy298,&yymsp[-5].minor.yy298),&yymsp[-3].minor.yy298,&yymsp[0].minor.yy0,yymsp[-7].minor.yy372);}
+-#line 3479 "parse.c"
+-        /* No destructor defined for COPY */
+-        /* No destructor defined for FROM */
+-        /* No destructor defined for USING */
+-        /* No destructor defined for DELIMITERS */
++#line 2870 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 245:
+-#line 768 "parse.y"
++#line 768 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteCopy(pParse,sqliteSrcListAppend(0,&yymsp[-3].minor.yy298,&yymsp[-2].minor.yy298),&yymsp[0].minor.yy298,0,yymsp[-4].minor.yy372);}
+-#line 3488 "parse.c"
+-        /* No destructor defined for COPY */
+-        /* No destructor defined for FROM */
++#line 2875 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 246:
+-#line 772 "parse.y"
++#line 772 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteVacuum(pParse,0);}
+-#line 3495 "parse.c"
+-        /* No destructor defined for VACUUM */
++#line 2880 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 247:
+-#line 773 "parse.y"
++#line 773 "ext/sqlite/libsqlite/src/parse.y"
+ {sqliteVacuum(pParse,&yymsp[0].minor.yy298);}
+-#line 3501 "parse.c"
+-        /* No destructor defined for VACUUM */
++#line 2885 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 248:
+-#line 777 "parse.y"
++      case 250:
++#line 777 "ext/sqlite/libsqlite/src/parse.y"
+ {sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy298,0);}
+-#line 3507 "parse.c"
+-        /* No destructor defined for PRAGMA */
+-        /* No destructor defined for EQ */
++#line 2891 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 249:
+-#line 778 "parse.y"
++#line 778 "ext/sqlite/libsqlite/src/parse.y"
+ {sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy0,0);}
+-#line 3514 "parse.c"
+-        /* No destructor defined for PRAGMA */
+-        /* No destructor defined for EQ */
+-        break;
+-      case 250:
+-#line 779 "parse.y"
+-{sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy298,0);}
+-#line 3521 "parse.c"
+-        /* No destructor defined for PRAGMA */
+-        /* No destructor defined for EQ */
++#line 2896 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 251:
+-#line 780 "parse.y"
++#line 780 "ext/sqlite/libsqlite/src/parse.y"
+ {sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy298,1);}
+-#line 3528 "parse.c"
+-        /* No destructor defined for PRAGMA */
+-        /* No destructor defined for EQ */
++#line 2901 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 252:
+-#line 781 "parse.y"
++#line 781 "ext/sqlite/libsqlite/src/parse.y"
+ {sqlitePragma(pParse,&yymsp[-3].minor.yy298,&yymsp[-1].minor.yy298,0);}
+-#line 3535 "parse.c"
+-        /* No destructor defined for PRAGMA */
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
++#line 2906 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 253:
+-#line 782 "parse.y"
++#line 782 "ext/sqlite/libsqlite/src/parse.y"
+ {sqlitePragma(pParse,&yymsp[0].minor.yy298,&yymsp[0].minor.yy298,0);}
+-#line 3543 "parse.c"
+-        /* No destructor defined for PRAGMA */
+-        break;
+-      case 254:
+-#line 783 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy298;}
+-#line 3549 "parse.c"
+-        /* No destructor defined for plus_opt */
+-        break;
+-      case 255:
+-#line 784 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy298;}
+-#line 3555 "parse.c"
+-        /* No destructor defined for MINUS */
+-        break;
+-      case 256:
+-#line 785 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 3561 "parse.c"
+-        break;
+-      case 257:
+-#line 786 "parse.y"
+-{yygotominor.yy298 = yymsp[0].minor.yy0;}
+-#line 3566 "parse.c"
+-        break;
+-      case 258:
+-        /* No destructor defined for PLUS */
+-        break;
+-      case 259:
++#line 2911 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 260:
+-#line 792 "parse.y"
++#line 792 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   Token all;
+   all.z = yymsp[-4].minor.yy0.z;
+   all.n = (yymsp[0].minor.yy0.z - yymsp[-4].minor.yy0.z) + yymsp[0].minor.yy0.n;
+   sqliteFinishTrigger(pParse, yymsp[-1].minor.yy19, &all);
+ }
+-#line 3581 "parse.c"
+-        /* No destructor defined for trigger_decl */
+-        /* No destructor defined for BEGIN */
++#line 2921 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 261:
+-#line 800 "parse.y"
++#line 800 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   SrcList *pTab = sqliteSrcListAppend(0, &yymsp[-3].minor.yy298, &yymsp[-2].minor.yy298);
+   sqliteBeginTrigger(pParse, &yymsp[-7].minor.yy298, yymsp[-6].minor.yy372, yymsp[-5].minor.yy290.a, yymsp[-5].minor.yy290.b, pTab, yymsp[-1].minor.yy372, yymsp[0].minor.yy182, yymsp[-9].minor.yy372);
+ }
+-#line 3591 "parse.c"
+-        /* No destructor defined for TRIGGER */
+-        /* No destructor defined for ON */
++#line 2929 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 262:
+-#line 806 "parse.y"
++      case 265:
++#line 806 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = TK_BEFORE; }
+-#line 3598 "parse.c"
+-        /* No destructor defined for BEFORE */
++#line 2935 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 263:
+-#line 807 "parse.y"
++#line 807 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = TK_AFTER;  }
+-#line 3604 "parse.c"
+-        /* No destructor defined for AFTER */
++#line 2940 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 264:
+-#line 808 "parse.y"
++#line 808 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = TK_INSTEAD;}
+-#line 3610 "parse.c"
+-        /* No destructor defined for INSTEAD */
+-        /* No destructor defined for OF */
+-        break;
+-      case 265:
+-#line 809 "parse.y"
+-{ yygotominor.yy372 = TK_BEFORE; }
+-#line 3617 "parse.c"
++#line 2945 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 266:
+-#line 813 "parse.y"
++#line 813 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy290.a = TK_DELETE; yygotominor.yy290.b = 0; }
+-#line 3622 "parse.c"
+-        /* No destructor defined for DELETE */
++#line 2950 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 267:
+-#line 814 "parse.y"
++#line 814 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy290.a = TK_INSERT; yygotominor.yy290.b = 0; }
+-#line 3628 "parse.c"
+-        /* No destructor defined for INSERT */
++#line 2955 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 268:
+-#line 815 "parse.y"
++#line 815 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy290.a = TK_UPDATE; yygotominor.yy290.b = 0;}
+-#line 3634 "parse.c"
+-        /* No destructor defined for UPDATE */
++#line 2960 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 269:
+-#line 816 "parse.y"
++#line 816 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy290.a = TK_UPDATE; yygotominor.yy290.b = yymsp[0].minor.yy320; }
+-#line 3640 "parse.c"
+-        /* No destructor defined for UPDATE */
+-        /* No destructor defined for OF */
++#line 2965 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 270:
+-#line 819 "parse.y"
+-{ yygotominor.yy372 = TK_ROW; }
+-#line 3647 "parse.c"
+-        break;
+       case 271:
+-#line 820 "parse.y"
++#line 819 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = TK_ROW; }
+-#line 3652 "parse.c"
+-        /* No destructor defined for FOR */
+-        /* No destructor defined for EACH */
+-        /* No destructor defined for ROW */
++#line 2971 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 272:
+-#line 821 "parse.y"
++#line 821 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy372 = TK_STATEMENT; }
+-#line 3660 "parse.c"
+-        /* No destructor defined for FOR */
+-        /* No destructor defined for EACH */
+-        /* No destructor defined for STATEMENT */
++#line 2976 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 273:
+-#line 824 "parse.y"
++#line 824 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy182 = 0; }
+-#line 3668 "parse.c"
++#line 2981 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 274:
+-#line 825 "parse.y"
++#line 825 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy182 = yymsp[0].minor.yy242; }
+-#line 3673 "parse.c"
+-        /* No destructor defined for WHEN */
++#line 2986 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 275:
+-#line 829 "parse.y"
++#line 829 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yymsp[-2].minor.yy19->pNext = yymsp[0].minor.yy19;
+   yygotominor.yy19 = yymsp[-2].minor.yy19;
+ }
+-#line 3682 "parse.c"
+-        /* No destructor defined for SEMI */
++#line 2994 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 276:
+-#line 833 "parse.y"
++#line 833 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy19 = 0; }
+-#line 3688 "parse.c"
++#line 2999 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 277:
+-#line 839 "parse.y"
++#line 839 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy19 = sqliteTriggerUpdateStep(&yymsp[-3].minor.yy298, yymsp[-1].minor.yy322, yymsp[0].minor.yy242, yymsp[-4].minor.yy372); }
+-#line 3693 "parse.c"
+-        /* No destructor defined for UPDATE */
+-        /* No destructor defined for SET */
++#line 3004 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 278:
+-#line 844 "parse.y"
++#line 844 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy19 = sqliteTriggerInsertStep(&yymsp[-5].minor.yy298, yymsp[-4].minor.yy320, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy372);}
+-#line 3700 "parse.c"
+-        /* No destructor defined for INTO */
+-        /* No destructor defined for VALUES */
+-        /* No destructor defined for LP */
+-        /* No destructor defined for RP */
++#line 3009 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 279:
+-#line 847 "parse.y"
++#line 847 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy19 = sqliteTriggerInsertStep(&yymsp[-2].minor.yy298, yymsp[-1].minor.yy320, 0, yymsp[0].minor.yy179, yymsp[-4].minor.yy372);}
+-#line 3709 "parse.c"
+-        /* No destructor defined for INTO */
++#line 3014 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 280:
+-#line 851 "parse.y"
++#line 851 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy19 = sqliteTriggerDeleteStep(&yymsp[-1].minor.yy298, yymsp[0].minor.yy242);}
+-#line 3715 "parse.c"
+-        /* No destructor defined for DELETE */
+-        /* No destructor defined for FROM */
++#line 3019 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 281:
+-#line 854 "parse.y"
++#line 854 "ext/sqlite/libsqlite/src/parse.y"
+ {yygotominor.yy19 = sqliteTriggerSelectStep(yymsp[0].minor.yy179); }
+-#line 3722 "parse.c"
++#line 3024 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 282:
+-#line 857 "parse.y"
++#line 857 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, 0); 
+   yygotominor.yy242->iColumn = OE_Ignore;
+   sqliteExprSpan(yygotominor.yy242, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+ }
+-#line 3731 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for IGNORE */
++#line 3033 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 283:
+-#line 862 "parse.y"
++#line 862 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy298); 
+   yygotominor.yy242->iColumn = OE_Rollback;
+   sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+ }
+-#line 3742 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for ROLLBACK */
+-        /* No destructor defined for COMMA */
++#line 3042 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 284:
+-#line 867 "parse.y"
++#line 867 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy298); 
+   yygotominor.yy242->iColumn = OE_Abort;
+   sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+ }
+-#line 3754 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for ABORT */
+-        /* No destructor defined for COMMA */
++#line 3051 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 285:
+-#line 872 "parse.y"
++#line 872 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy298); 
+   yygotominor.yy242->iColumn = OE_Fail;
+   sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+ }
+-#line 3766 "parse.c"
+-        /* No destructor defined for LP */
+-        /* No destructor defined for FAIL */
+-        /* No destructor defined for COMMA */
++#line 3060 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 286:
+-#line 879 "parse.y"
++#line 879 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&yymsp[-1].minor.yy298,&yymsp[0].minor.yy298));
+ }
+-#line 3776 "parse.c"
+-        /* No destructor defined for DROP */
+-        /* No destructor defined for TRIGGER */
++#line 3067 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 287:
+-#line 884 "parse.y"
++#line 884 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteAttach(pParse, &yymsp[-3].minor.yy298, &yymsp[-1].minor.yy298, &yymsp[0].minor.yy298);
+ }
+-#line 3785 "parse.c"
+-        /* No destructor defined for ATTACH */
+-        /* No destructor defined for database_kw_opt */
+-        /* No destructor defined for AS */
+-        break;
+-      case 288:
+-#line 888 "parse.y"
+-{ yygotominor.yy298 = yymsp[0].minor.yy298; }
+-#line 3793 "parse.c"
+-        /* No destructor defined for USING */
++#line 3074 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 289:
+-#line 889 "parse.y"
++#line 889 "ext/sqlite/libsqlite/src/parse.y"
+ { yygotominor.yy298.z = 0; yygotominor.yy298.n = 0; }
+-#line 3799 "parse.c"
+-        break;
+-      case 290:
+-        /* No destructor defined for DATABASE */
+-        break;
+-      case 291:
++#line 3079 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+       case 292:
+-#line 895 "parse.y"
++#line 895 "ext/sqlite/libsqlite/src/parse.y"
+ {
+   sqliteDetach(pParse, &yymsp[0].minor.yy298);
+ }
+-#line 3811 "parse.c"
+-        /* No destructor defined for DETACH */
+-        /* No destructor defined for database_kw_opt */
++#line 3086 "ext/sqlite/libsqlite/src/parse.c"
+         break;
+   };
+   yygoto = yyRuleInfo[yyruleno].lhs;
+   yysize = yyRuleInfo[yyruleno].nrhs;
+   yypParser->yyidx -= yysize;
+-  yyact = yy_find_reduce_action(yypParser,yygoto);
++  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
+   if( yyact < YYNSTATE ){
+-    yy_shift(yypParser,yyact,yygoto,&yygotominor);
++#ifdef NDEBUG
++    /* If we are not debugging and the reduce action popped at least
++    ** one element off the stack, then we can push the new element back
++    ** onto the stack here, and skip the stack overflow test in yy_shift().
++    ** That gives a significant speed improvement. */
++    if( yysize ){
++      yypParser->yyidx++;
++      yymsp -= yysize-1;
++      yymsp->stateno = yyact;
++      yymsp->major = yygoto;
++      yymsp->minor = yygotominor;
++    }else
++#endif
++    {
++      yy_shift(yypParser,yyact,yygoto,&yygotominor);
++    }
+   }else if( yyact == YYNSTATE + YYNRULE + 1 ){
+     yy_accept(yypParser);
+   }
+@@ -3852,7 +3138,7 @@
+ ){
+   sqliteParserARG_FETCH;
+ #define TOKEN (yyminor.yy0)
+-#line 23 "parse.y"
++#line 23 "ext/sqlite/libsqlite/src/parse.y"
+ 
+   if( pParse->zErrMsg==0 ){
+     if( TOKEN.z[0] ){
+@@ -3861,8 +3147,7 @@
+       sqliteErrorMsg(pParse, "incomplete SQL statement");
+     }
+   }
+-
+-#line 3865 "parse.c"
++#line 3153 "ext/sqlite/libsqlite/src/parse.c"
+   sqliteParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ }
+ 
+@@ -3918,7 +3203,7 @@
+   /* (re)initialize the parser, if necessary */
+   yypParser = (yyParser*)yyp;
+   if( yypParser->yyidx<0 ){
+-    if( yymajor==0 ) return;
++    /* if( yymajor==0 ) return; // not sure why this was here... */
+     yypParser->yyidx = 0;
+     yypParser->yyerrcnt = -1;
+     yypParser->yystack[0].stateno = 0;
+diff -dPNur sqlite-1.0.3/libsqlite/src/parse.y sqlite-svn/libsqlite/src/parse.y
+--- sqlite-1.0.3/libsqlite/src/parse.y	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/parse.y	2012-10-09 13:36:42.531952680 +0000
+@@ -14,7 +14,7 @@
+ ** the parser.  Lemon will also generate a header file containing
+ ** numeric codes for all of the tokens.
+ **
+-** @(#) $Id: parse.y,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** @(#) $Id: parse.y 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ %token_prefix TK_
+ %token_type {Token}
+diff -dPNur sqlite-1.0.3/libsqlite/src/pragma.c sqlite-svn/libsqlite/src/pragma.c
+--- sqlite-1.0.3/libsqlite/src/pragma.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/pragma.c	2012-10-09 13:36:42.531952680 +0000
+@@ -11,7 +11,7 @@
+ *************************************************************************
+ ** This file contains code used to implement the PRAGMA command.
+ **
+-** $Id: pragma.c,v 1.2.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: pragma.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include <ctype.h>
+diff -dPNur sqlite-1.0.3/libsqlite/src/printf.c sqlite-svn/libsqlite/src/printf.c
+--- sqlite-1.0.3/libsqlite/src/printf.c	2004-07-10 11:47:26.000000000 +0000
++++ sqlite-svn/libsqlite/src/printf.c	2012-10-09 13:36:42.531952680 +0000
+@@ -227,6 +227,7 @@
+   int nsd;                   /* Number of significant digits returned */
+ #endif
+ 
++  func(arg,"",0);
+   count = length = 0;
+   bufpt = 0;
+   for(; (c=(*fmt))!=0; ++fmt){
+@@ -673,9 +674,11 @@
+       }
+     }
+   }
+-  if( pM->zText && nNewChar>0 ){
+-    memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
+-    pM->nChar += nNewChar;
++  if( pM->zText ){
++    if( nNewChar>0 ){
++      memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
++      pM->nChar += nNewChar;
++    }
+     pM->zText[pM->nChar] = 0;
+   }
+ }
+diff -dPNur sqlite-1.0.3/libsqlite/src/random.c sqlite-svn/libsqlite/src/random.c
+--- sqlite-1.0.3/libsqlite/src/random.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/random.c	2012-10-09 13:36:42.551252050 +0000
+@@ -15,7 +15,7 @@
+ ** Random numbers are used by some of the database backends in order
+ ** to generate random integer keys for tables or random filenames.
+ **
+-** $Id: random.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: random.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include "os.h"
+diff -dPNur sqlite-1.0.3/libsqlite/src/select.c sqlite-svn/libsqlite/src/select.c
+--- sqlite-1.0.3/libsqlite/src/select.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/select.c	2012-10-09 13:36:42.531952680 +0000
+@@ -12,7 +12,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** to handle SELECT statements in SQLite.
+ **
+-** $Id: select.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: select.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+@@ -365,6 +365,30 @@
+ }
+ 
+ /*
++** Add code to implement the OFFSET and LIMIT
++*/
++static void codeLimiter(
++  Vdbe *v,          /* Generate code into this VM */
++  Select *p,        /* The SELECT statement being coded */
++  int iContinue,    /* Jump here to skip the current record */
++  int iBreak,       /* Jump here to end the loop */
++  int nPop          /* Number of times to pop stack when jumping */
++){
++  if( p->iOffset>=0 ){
++    int addr = sqliteVdbeCurrentAddr(v) + 2;
++    if( nPop>0 ) addr++;
++    sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
++    if( nPop>0 ){
++      sqliteVdbeAddOp(v, OP_Pop, nPop, 0);
++    }
++    sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
++  }
++  if( p->iLimit>=0 ){
++    sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
++  }
++}
++
++/*
+ ** This routine generates the code for the inside of the inner loop
+ ** of a SELECT.
+ **
+@@ -388,6 +412,7 @@
+ ){
+   Vdbe *v = pParse->pVdbe;
+   int i;
++  int hasDistinct;        /* True if the DISTINCT keyword is present */
+ 
+   if( v==0 ) return 0;
+   assert( pEList!=0 );
+@@ -395,15 +420,9 @@
+   /* If there was a LIMIT clause on the SELECT statement, then do the check
+   ** to see if this row should be output.
+   */
+-  if( pOrderBy==0 ){
+-    if( p->iOffset>=0 ){
+-      int addr = sqliteVdbeCurrentAddr(v);
+-      sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+2);
+-      sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
+-    }
+-    if( p->iLimit>=0 ){
+-      sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
+-    }
++  hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
++  if( pOrderBy==0 && !hasDistinct ){
++    codeLimiter(v, p, iContinue, iBreak, 0);
+   }
+ 
+   /* Pull the requested columns.
+@@ -423,7 +442,7 @@
+   ** and this row has been seen before, then do not make this row
+   ** part of the result.
+   */
+-  if( distinct>=0 && pEList && pEList->nExpr>0 ){
++  if( hasDistinct ){
+ #if NULL_ALWAYS_DISTINCT
+     sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
+ #endif
+@@ -434,6 +453,9 @@
+     sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
+     sqliteVdbeAddOp(v, OP_String, 0, 0);
+     sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
++    if( pOrderBy==0 ){
++      codeLimiter(v, p, iContinue, iBreak, nColumn);
++    }
+   }
+ 
+   switch( eDest ){
+@@ -570,14 +592,7 @@
+   if( eDest==SRT_Sorter ) return;
+   sqliteVdbeAddOp(v, OP_Sort, 0, 0);
+   addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
+-  if( p->iOffset>=0 ){
+-    sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+4);
+-    sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+-    sqliteVdbeAddOp(v, OP_Goto, 0, addr);
+-  }
+-  if( p->iLimit>=0 ){
+-    sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, end2);
+-  }
++  codeLimiter(v, p, addr, end2, 1);
+   switch( eDest ){
+     case SRT_Callback: {
+       sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
+@@ -810,8 +825,9 @@
+     }else{
+       char zBuf[30];
+       sprintf(zBuf, "column%d", i+1);
+-      pTab->aCol[i].zName = sqliteStrDup(zBuf);
++      aCol[i].zName = sqliteStrDup(zBuf);
+     }
++    sqliteDequote(aCol[i].zName);
+   }
+   pTab->iPKey = -1;
+   return pTab;
+@@ -943,11 +959,11 @@
+         /* This expression is a "*" or a "TABLE.*" and needs to be
+         ** expanded. */
+         int tableSeen = 0;      /* Set to 1 when TABLE matches */
+-        Token *pName;           /* text of name of TABLE */
++        char *zTName;           /* text of name of TABLE */
+         if( pE->op==TK_DOT && pE->pLeft ){
+-          pName = &pE->pLeft->token;
++          zTName = sqliteTableNameFromToken(&pE->pLeft->token);
+         }else{
+-          pName = 0;
++          zTName = 0;
+         }
+         for(i=0; i<pTabList->nSrc; i++){
+           Table *pTab = pTabList->a[i].pTab;
+@@ -955,9 +971,8 @@
+           if( zTabName==0 || zTabName[0]==0 ){ 
+             zTabName = pTab->zName;
+           }
+-          if( pName && (zTabName==0 || zTabName[0]==0 || 
+-                 sqliteStrNICmp(pName->z, zTabName, pName->n)!=0 ||
+-                 zTabName[pName->n]!=0) ){
++          if( zTName && (zTabName==0 || zTabName[0]==0 || 
++                 sqliteStrICmp(zTName, zTabName)!=0) ){
+             continue;
+           }
+           tableSeen = 1;
+@@ -1002,13 +1017,14 @@
+           }
+         }
+         if( !tableSeen ){
+-          if( pName ){
+-            sqliteErrorMsg(pParse, "no such table: %T", pName);
++          if( zTName ){
++            sqliteErrorMsg(pParse, "no such table: %s", zTName);
+           }else{
+             sqliteErrorMsg(pParse, "no tables specified");
+           }
+           rc = 1;
+         }
++        sqliteFree(zTName);
+       }
+     }
+     sqliteExprListDelete(pEList);
+@@ -1916,6 +1932,12 @@
+   }else{
+     sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+     sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
++    if( seekOp==OP_Rewind ){
++      sqliteVdbeAddOp(v, OP_String, 0, 0);
++      sqliteVdbeAddOp(v, OP_MakeKey, 1, 0);
++      sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
++      seekOp = OP_MoveTo;
++    }
+     sqliteVdbeAddOp(v, seekOp, base+1, 0);
+     sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
+     sqliteVdbeAddOp(v, OP_Close, base+1, 0);
+diff -dPNur sqlite-1.0.3/libsqlite/src/sqlite.h.in sqlite-svn/libsqlite/src/sqlite.h.in
+--- sqlite-1.0.3/libsqlite/src/sqlite.h.in	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/sqlite.h.in	2012-10-09 13:36:42.541252205 +0000
+@@ -12,7 +12,7 @@
+ ** This header file defines the interface that the SQLite library
+ ** presents to client programs.
+ **
+-** @(#) $Id: sqlite.h.in,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** @(#) $Id: sqlite.h.in 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #ifndef _SQLITE_H_
+ #define _SQLITE_H_
+@@ -28,7 +28,11 @@
+ /*
+ ** The version of the SQLite library.
+ */
+-#define SQLITE_VERSION         "--VERS--"
++#ifdef SQLITE_VERSION
++# undef SQLITE_VERSION
++#else
++# define SQLITE_VERSION         "--VERS--"
++#endif
+ 
+ /*
+ ** The version string is also compiled into the library so that a program
+@@ -479,10 +483,24 @@
+   int datatype              /* The datatype for this function */
+ );
+ #define SQLITE_NUMERIC     (-1)
+-#define SQLITE_TEXT        (-2)
++/* #define SQLITE_TEXT     (-2)  // See below */
+ #define SQLITE_ARGS        (-3)
+ 
+ /*
++** SQLite version 3 defines SQLITE_TEXT differently.  To allow both
++** version 2 and version 3 to be included, undefine them both if a
++** conflict is seen.  Define SQLITE2_TEXT to be the version 2 value.
++*/
++#ifdef SQLITE_TEXT
++# undef SQLITE_TEXT
++#else
++# define SQLITE_TEXT     (-2)
++#endif
++#define SQLITE2_TEXT     (-2)
++
++
++
++/*
+ ** The user function implementations call one of the following four routines
+ ** in order to return their results.  The first parameter to each of these
+ ** routines is a copy of the first argument to xFunc() or xFinialize().
+diff -dPNur sqlite-1.0.3/libsqlite/src/sqlite.w32.h sqlite-svn/libsqlite/src/sqlite.w32.h
+--- sqlite-1.0.3/libsqlite/src/sqlite.w32.h	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/sqlite.w32.h	2012-10-09 13:36:42.551252050 +0000
+@@ -12,7 +12,7 @@
+ ** This header file defines the interface that the SQLite library
+ ** presents to client programs.
+ **
+-** @(#) $Id: sqlite.w32.h,v 1.3.6.3 2004/07/10 12:25:34 wez Exp $
++** @(#) $Id: sqlite.w32.h 203289 2005-12-20 15:26:26Z iliaa $
+ */
+ #ifndef _SQLITE_H_
+ #define _SQLITE_H_
+@@ -28,7 +28,7 @@
+ /*
+ ** The version of the SQLite library.
+ */
+-#define SQLITE_VERSION         "2.8.14"
++#define SQLITE_VERSION         "2.8.17"
+ 
+ /*
+ ** The version string is also compiled into the library so that a program
+@@ -204,32 +204,6 @@
+ */
+ int sqlite_changes(sqlite*);
+ 
+-/*
+-** This function returns the number of database rows that were changed
+-** by the last INSERT, UPDATE, or DELETE statment executed by sqlite_exec(),
+-** or by the last VM to run to completion. The change count is not updated
+-** by SQL statements other than INSERT, UPDATE or DELETE.
+-**
+-** Changes are counted, even if they are later undone by a ROLLBACK or
+-** ABORT. Changes associated with trigger programs that execute as a
+-** result of the INSERT, UPDATE, or DELETE statement are not counted.
+-**
+-** If a callback invokes sqlite_exec() recursively, then the changes
+-** in the inner, recursive call are counted together with the changes
+-** in the outer call.
+-**
+-** SQLite implements the command "DELETE FROM table" without a WHERE clause
+-** by dropping and recreating the table.  (This is much faster than going
+-** through and deleting individual elements form the table.)  Because of
+-** this optimization, the change count for "DELETE FROM table" will be
+-** zero regardless of the number of elements that were originally in the
+-** table. To get an accurate count of the number of rows deleted, use
+-** "DELETE FROM table WHERE 1" instead.
+-**
+-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+-*/
+-int sqlite_last_statement_changes(sqlite*);
+-
+ /* If the parameter to this routine is one of the return value constants
+ ** defined above, then this routine returns a constant text string which
+ ** descripts (in English) the meaning of the return value.
+@@ -466,12 +440,13 @@
+ ** Use the following routine to define the datatype returned by a
+ ** user-defined function.  The second argument can be one of the
+ ** constants SQLITE_NUMERIC, SQLITE_TEXT, or SQLITE_ARGS or it
+-** can be an integer greater than or equal to zero.  When the datatype
+-** parameter is non-negative, the type of the result will be the
+-** same as the datatype-th argument.  If datatype==SQLITE_NUMERIC
+-** then the result is always numeric.  If datatype==SQLITE_TEXT then
+-** the result is always text.  If datatype==SQLITE_ARGS then the result
+-** is numeric if any argument is numeric and is text otherwise.
++** can be an integer greater than or equal to zero.  The datatype
++** will be numeric or text (the only two types supported) if the
++** argument is SQLITE_NUMERIC or SQLITE_TEXT.  If the argument is
++** SQLITE_ARGS, then the datatype is numeric if any argument to the
++** function is numeric and is text otherwise.  If the second argument
++** is an integer, then the datatype of the result is the same as the
++** parameter to the function that corresponds to that integer.
+ */
+ int sqlite_function_type(
+   sqlite *db,               /* The database there the function is registered */
+@@ -779,88 +754,9 @@
+ ** query is immediately terminated and any database changes rolled back. If the
+ ** query was part of a larger transaction, then the transaction is not rolled
+ ** back and remains active. The sqlite_exec() call returns SQLITE_ABORT. 
+-**
+-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+ */
+ void sqlite_progress_handler(sqlite*, int, int(*)(void*), void*);
+ 
+-/*
+-** Register a callback function to be invoked whenever a new transaction
+-** is committed.  The pArg argument is passed through to the callback.
+-** callback.  If the callback function returns non-zero, then the commit
+-** is converted into a rollback.
+-**
+-** If another function was previously registered, its pArg value is returned.
+-** Otherwise NULL is returned.
+-**
+-** Registering a NULL function disables the callback.
+-**
+-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+-*/
+-void *sqlite_commit_hook(sqlite*, int(*)(void*), void*);
+-
+-/*
+-** Open an encrypted SQLite database.  If pKey==0 or nKey==0, this routine
+-** is the same as sqlite_open().
+-**
+-** The code to implement this API is not available in the public release
+-** of SQLite.
+-*/
+-sqlite *sqlite_open_encrypted(
+-  const char *zFilename,   /* Name of the encrypted database */
+-  const void *pKey,        /* Pointer to the key */
+-  int nKey,                /* Number of bytes in the key */
+-  int *pErrcode,           /* Write error code here */
+-  char **pzErrmsg          /* Write error message here */
+-);
+-
+-/*
+-** Change the key on an open database.  If the current database is not
+-** encrypted, this routine will encrypt it.  If pNew==0 or nNew==0, the
+-** database is decrypted.
+-**
+-** The code to implement this API is not available in the public release
+-** of SQLite.
+-*/
+-int sqlite_rekey(
+-  sqlite *db,                    /* Database to be rekeyed */
+-  const void *pKey, int nKey     /* The new key */
+-);
+-
+-/*
+-** Encode a binary buffer "in" of size n bytes so that it contains
+-** no instances of characters '\'' or '\000'.  The output is 
+-** null-terminated and can be used as a string value in an INSERT
+-** or UPDATE statement.  Use sqlite_decode_binary() to convert the
+-** string back into its original binary.
+-**
+-** The result is written into a preallocated output buffer "out".
+-** "out" must be able to hold at least 2 +(257*n)/254 bytes.
+-** In other words, the output will be expanded by as much as 3
+-** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
+-** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
+-**
+-** The return value is the number of characters in the encoded
+-** string, excluding the "\000" terminator.
+-**
+-** If out==NULL then no output is generated but the routine still returns
+-** the number of characters that would have been generated if out had
+-** not been NULL.
+-*/
+-int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
+-
+-/*
+-** Decode the string "in" into binary data and write it into "out".
+-** This routine reverses the encoding created by sqlite_encode_binary().
+-** The output will always be a few bytes less than the input.  The number
+-** of bytes of output is returned.  If the input is not a well-formed
+-** encoding, -1 is returned.
+-**
+-** The "in" and "out" parameters may point to the same buffer in order
+-** to decode a string in place.
+-*/
+-int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
+-
+ #ifdef __cplusplus
+ }  /* End of the 'extern "C"' block */
+ #endif
+diff -dPNur sqlite-1.0.3/libsqlite/src/sqliteInt.h sqlite-svn/libsqlite/src/sqliteInt.h
+--- sqlite-1.0.3/libsqlite/src/sqliteInt.h	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/sqliteInt.h	2012-10-09 13:36:42.551252050 +0000
+@@ -11,7 +11,7 @@
+ *************************************************************************
+ ** Internal interface definitions for SQLite.
+ **
+-** @(#) $Id: sqliteInt.h,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** @(#) $Id: sqliteInt.h 203289 2005-12-20 15:26:26Z iliaa $
+ */
+ #include "config.h"
+ #include "sqlite.h"
+@@ -102,6 +102,9 @@
+ #ifndef UINT16_TYPE
+ # define UINT16_TYPE unsigned short int
+ #endif
++#ifndef INT16_TYPE
++# define INT16_TYPE short int
++#endif
+ #ifndef UINT8_TYPE
+ # define UINT8_TYPE unsigned char
+ #endif
+@@ -117,6 +120,7 @@
+ #endif
+ typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
+ typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
++typedef INT16_TYPE i16;            /* 2-byte signed integer */
+ typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
+ typedef UINT8_TYPE i8;             /* 1-byte signed integer */
+ typedef INTPTR_TYPE ptr;           /* Big enough to hold a pointer */
+@@ -762,8 +766,8 @@
+ ** now be identified by a database name, a dot, then the table name: ID.ID.
+ */
+ struct SrcList {
+-  u16 nSrc;        /* Number of tables or subqueries in the FROM clause */
+-  u16 nAlloc;      /* Number of entries allocated in a[] below */
++  i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
++  i16 nAlloc;      /* Number of entries allocated in a[] below */
+   struct SrcList_item {
+     char *zDatabase;  /* Name of database holding this table */
+     char *zName;      /* Name of the table */
+@@ -1116,7 +1120,7 @@
+ #endif
+ char *sqliteMPrintf(const char*, ...);
+ char *sqliteVMPrintf(const char*, va_list);
+-void sqliteSetString(char **, const char *, ...);
++void sqliteSetString(char **, ...);
+ void sqliteSetNString(char **, ...);
+ void sqliteErrorMsg(Parse*, const char*, ...);
+ void sqliteDequote(char*);
+diff -dPNur sqlite-1.0.3/libsqlite/src/tokenize.c sqlite-svn/libsqlite/src/tokenize.c
+--- sqlite-1.0.3/libsqlite/src/tokenize.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/tokenize.c	2012-10-09 13:36:42.541252205 +0000
+@@ -15,7 +15,7 @@
+ ** individual tokens and sends those tokens one-by-one over to the
+ ** parser for analysis.
+ **
+-** $Id: tokenize.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: tokenize.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include "os.h"
+diff -dPNur sqlite-1.0.3/libsqlite/src/update.c sqlite-svn/libsqlite/src/update.c
+--- sqlite-1.0.3/libsqlite/src/update.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/update.c	2012-10-09 13:36:42.551252050 +0000
+@@ -12,7 +12,7 @@
+ ** This file contains C code routines that are called by the parser
+ ** to handle UPDATE statements.
+ **
+-** $Id: update.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: update.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+diff -dPNur sqlite-1.0.3/libsqlite/src/util.c sqlite-svn/libsqlite/src/util.c
+--- sqlite-1.0.3/libsqlite/src/util.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/util.c	2012-10-09 13:36:42.531952680 +0000
+@@ -14,7 +14,7 @@
+ ** This file contains functions for allocating memory, comparing
+ ** strings, and stuff like that.
+ **
+-** $Id: util.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: util.c 203289 2005-12-20 15:26:26Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include <stdarg.h>
+@@ -330,15 +330,15 @@
+ ** point to that string.  The 1st argument must either be NULL or 
+ ** point to memory obtained from sqliteMalloc().
+ */
+-void sqliteSetString(char **pz, const char *zFirst, ...){
++void sqliteSetString(char **pz, ...){
+   va_list ap;
+   int nByte;
+   const char *z;
+   char *zResult;
+ 
+   if( pz==0 ) return;
+-  nByte = strlen(zFirst) + 1;
+-  va_start(ap, zFirst);
++  nByte = 1;
++  va_start(ap, pz);
+   while( (z = va_arg(ap, const char*))!=0 ){
+     nByte += strlen(z);
+   }
+@@ -348,9 +348,8 @@
+   if( zResult==0 ){
+     return;
+   }
+-  strcpy(zResult, zFirst);
+-  zResult += strlen(zResult);
+-  va_start(ap, zFirst);
++  *zResult = 0;
++  va_start(ap, pz);
+   while( (z = va_arg(ap, const char*))!=0 ){
+     strcpy(zResult, z);
+     zResult += strlen(zResult);
+@@ -504,14 +503,14 @@
+   a = (unsigned char *)zLeft;
+   b = (unsigned char *)zRight;
+   while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+-  return *a - *b;
++  return UpperToLower[*a] - UpperToLower[*b];
+ }
+ int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
+   register unsigned char *a, *b;
+   a = (unsigned char *)zLeft;
+   b = (unsigned char *)zRight;
+   while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+-  return N<0 ? 0 : *a - *b;
++  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
+ }
+ 
+ /*
+diff -dPNur sqlite-1.0.3/libsqlite/src/vacuum.c sqlite-svn/libsqlite/src/vacuum.c
+--- sqlite-1.0.3/libsqlite/src/vacuum.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/vacuum.c	2012-10-09 13:36:42.541252205 +0000
+@@ -14,7 +14,7 @@
+ ** Most of the code in this file may be omitted by defining the
+ ** SQLITE_OMIT_VACUUM macro.
+ **
+-** $Id: vacuum.c,v 1.2.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: vacuum.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ #include "os.h"
+@@ -164,24 +164,6 @@
+ }
+ 
+ /*
+-** This callback is used to transfer PRAGMA settings from one database
+-** to the other.  The value in argv[0] should be passed to a pragma
+-** identified by ((vacuumStruct*)pArg)->zPragma.
+-*/
+-static int vacuumCallback3(void *pArg, int argc, char **argv, char **NotUsed){
+-  vacuumStruct *p = (vacuumStruct*)pArg;
+-  char zBuf[200];
+-  assert( argc==1 );
+-  if( argv==0 ) return 0;
+-  assert( argv[0]!=0 );
+-  assert( strlen(p->zPragma)<100 );
+-  assert( strlen(argv[0])<30 );
+-  sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
+-  p->rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
+-  return p->rc;
+-}
+-
+-/*
+ ** Generate a random name of 20 character in length.
+ */
+ static void randomName(unsigned char *zBuf){
+@@ -226,14 +208,6 @@
+   char *zErrMsg;          /* Error message */
+   vacuumStruct sVac;      /* Information passed to callbacks */
+ 
+-  /* These are all of the pragmas that need to be transferred over
+-  ** to the new database */
+-  static const char *zPragma[] = {
+-     "default_synchronous",
+-     "default_cache_size",
+-     /* "default_temp_store", */
+-  };
+-
+   if( db->flags & SQLITE_InTrans ){
+     sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction", 
+        (char*)0);
+@@ -283,13 +257,6 @@
+   sVac.dbOld = db;
+   sVac.dbNew = dbNew;
+   sVac.pzErrMsg = pzErrMsg;
+-  for(i=0; rc==SQLITE_OK && i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
+-    char zBuf[200];
+-    assert( strlen(zPragma[i])<100 );
+-    sprintf(zBuf, "PRAGMA %s;", zPragma[i]);
+-    sVac.zPragma = zPragma[i];
+-    rc = sqlite_exec(db, zBuf, vacuumCallback3, &sVac, &zErrMsg);
+-  }
+   if( rc==SQLITE_OK ){
+     rc = sqlite_exec(db, 
+       "SELECT type, name, sql FROM sqlite_master "
+@@ -300,6 +267,17 @@
+       vacuumCallback1, &sVac, &zErrMsg);
+   }
+   if( rc==SQLITE_OK ){
++    int meta1[SQLITE_N_BTREE_META];
++    int meta2[SQLITE_N_BTREE_META];
++    sqliteBtreeGetMeta(db->aDb[0].pBt, meta1);
++    sqliteBtreeGetMeta(dbNew->aDb[0].pBt, meta2);
++    meta2[1] = meta1[1]+1;
++    meta2[3] = meta1[3];
++    meta2[4] = meta1[4];
++    meta2[6] = meta1[6];
++    rc = sqliteBtreeUpdateMeta(dbNew->aDb[0].pBt, meta2);
++  }
++  if( rc==SQLITE_OK ){
+     rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
+     sqlite_exec(db, "COMMIT", 0, 0, 0);
+     sqliteResetInternalSchema(db, 0);
+diff -dPNur sqlite-1.0.3/libsqlite/src/vdbe.c sqlite-svn/libsqlite/src/vdbe.c
+--- sqlite-1.0.3/libsqlite/src/vdbe.c	2004-07-10 12:25:34.000000000 +0000
++++ sqlite-svn/libsqlite/src/vdbe.c	2012-10-09 13:36:42.551252050 +0000
+@@ -43,7 +43,7 @@
+ ** in this file for details.  If in doubt, do not deviate from existing
+ ** commenting and indentation practices when changing or adding code.
+ **
+-** $Id: vdbe.c,v 1.3.6.2 2004/07/10 12:25:34 wez Exp $
++** $Id: vdbe.c 219681 2006-09-09 10:59:05Z tony2001 $
+ */
+ #include "sqliteInt.h"
+ #include "os.h"
+@@ -114,7 +114,7 @@
+   sqlite *db;
+   int rc;
+ 
+-  if( p->magic!=VDBE_MAGIC_RUN ){
++  if( !p || p->magic!=VDBE_MAGIC_RUN ){
+     return SQLITE_MISUSE;
+   }
+   db = p->db;
+@@ -4545,6 +4545,10 @@
+     pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
+     pTos->flags |= MEM_Ephem;
+   }
++  if( pTos->flags & MEM_AggCtx ){
++    Release(pTos);
++    pTos->flags = MEM_Null;
++  }
+   break;
+ }
+ 
+@@ -4695,8 +4699,9 @@
+       break;
+     }
+   }else{
+-    assert( pSet->prev );
+-    pSet->prev = sqliteHashNext(pSet->prev);
++    if( pSet->prev ){
++      pSet->prev = sqliteHashNext(pSet->prev);
++    }
+     if( pSet->prev==0 ){
+       break;
+     }else{
+diff -dPNur sqlite-1.0.3/libsqlite/src/vdbe.h sqlite-svn/libsqlite/src/vdbe.h
+--- sqlite-1.0.3/libsqlite/src/vdbe.h	2004-07-10 12:25:35.000000000 +0000
++++ sqlite-svn/libsqlite/src/vdbe.h	2012-10-09 13:36:42.551252050 +0000
+@@ -15,7 +15,7 @@
+ ** or VDBE.  The VDBE implements an abstract machine that runs a
+ ** simple program to access and modify the underlying database.
+ **
+-** $Id: vdbe.h,v 1.3.6.2 2004/07/10 12:25:35 wez Exp $
++** $Id: vdbe.h 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #ifndef _SQLITE_VDBE_H_
+ #define _SQLITE_VDBE_H_
+diff -dPNur sqlite-1.0.3/libsqlite/src/where.c sqlite-svn/libsqlite/src/where.c
+--- sqlite-1.0.3/libsqlite/src/where.c	2004-07-10 12:25:35.000000000 +0000
++++ sqlite-svn/libsqlite/src/where.c	2012-10-09 13:36:42.541252205 +0000
+@@ -12,7 +12,7 @@
+ ** This module contains C code that generates VDBE code used to process
+ ** the WHERE clause of SQL statements.
+ **
+-** $Id: where.c,v 1.3.6.2 2004/07/10 12:25:35 wez Exp $
++** $Id: where.c 195361 2005-09-07 15:11:33Z iliaa $
+ */
+ #include "sqliteInt.h"
+ 
+@@ -46,7 +46,7 @@
+ typedef struct ExprMaskSet ExprMaskSet;
+ struct ExprMaskSet {
+   int n;          /* Number of assigned cursor values */
+-  int ix[32];     /* Cursor assigned to each bit */
++  int ix[31];     /* Cursor assigned to each bit */
+ };
+ 
+ /*
+@@ -123,7 +123,9 @@
+   unsigned int mask = 0;
+   if( p==0 ) return 0;
+   if( p->op==TK_COLUMN ){
+-    return getMask(pMaskSet, p->iTable);
++    mask = getMask(pMaskSet, p->iTable);
++    if( mask==0 ) mask = -1;
++    return mask;
+   }
+   if( p->pRight ){
+     mask = exprTableUsage(pMaskSet, p->pRight);
+@@ -270,6 +272,35 @@
+ }
+ 
+ /*
++** Disable a term in the WHERE clause.  Except, do not disable the term
++** if it controls a LEFT OUTER JOIN and it did not originate in the ON
++** or USING clause of that join.
++**
++** Consider the term t2.z='ok' in the following queries:
++**
++**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
++**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
++**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
++**
++** The t2.z='ok' is disabled in the in (2) because it did not originate
++** in the ON clause.  The term is disabled in (3) because it is not part
++** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
++**
++** Disabling a term causes that term to not be tested in the inner loop
++** of the join.  Disabling is an optimization.  We would get the correct
++** results if nothing were ever disabled, but joins might run a little
++** slower.  The trick is to disable as much as we can without disabling
++** too much.  If we disabled in (1), we'd get the wrong answer.
++** See ticket #813.
++*/
++static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
++  Expr *pExpr = *ppExpr;
++  if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
++    *ppExpr = 0;
++  }
++}
++
++/*
+ ** Generate the beginning of the loop used for WHERE clause processing.
+ ** The return value is a pointer to an (opaque) structure that contains
+ ** information needed to terminate the loop.  Later, the calling routine
+@@ -736,7 +767,7 @@
+       }else{
+         sqliteExprCode(pParse, aExpr[k].p->pLeft);
+       }
+-      aExpr[k].p = 0;
++      disableTerm(pLevel, &aExpr[k].p);
+       cont = pLevel->cont = sqliteVdbeMakeLabel(v);
+       sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
+       haveKey = 0;
+@@ -760,7 +791,7 @@
+           ){
+             if( pX->op==TK_EQ ){
+               sqliteExprCode(pParse, pX->pRight);
+-              aExpr[k].p = 0;
++              disableTerm(pLevel, &aExpr[k].p);
+               break;
+             }
+             if( pX->op==TK_IN && nColumn==1 ){
+@@ -777,7 +808,7 @@
+                 pLevel->inOp = OP_Next;
+                 pLevel->inP1 = pX->iTable;
+               }
+-              aExpr[k].p = 0;
++              disableTerm(pLevel, &aExpr[k].p);
+               break;
+             }
+           }
+@@ -787,7 +818,7 @@
+              && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
+           ){
+             sqliteExprCode(pParse, aExpr[k].p->pLeft);
+-            aExpr[k].p = 0;
++            disableTerm(pLevel, &aExpr[k].p);
+             break;
+           }
+         }
+@@ -854,7 +885,7 @@
+         sqliteVdbeAddOp(v, OP_ForceInt,
+           aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
+         sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
+-        aExpr[k].p = 0;
++        disableTerm(pLevel, &aExpr[k].p);
+       }else{
+         sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
+       }
+@@ -876,7 +907,7 @@
+         }else{
+           testOp = OP_Gt;
+         }
+-        aExpr[k].p = 0;
++        disableTerm(pLevel, &aExpr[k].p);
+       }
+       start = sqliteVdbeCurrentAddr(v);
+       pLevel->op = OP_Next;
+@@ -931,7 +962,7 @@
+              && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
+           ){
+             sqliteExprCode(pParse, aExpr[k].p->pRight);
+-            aExpr[k].p = 0;
++            disableTerm(pLevel, &aExpr[k].p);
+             break;
+           }
+           if( aExpr[k].idxRight==iCur
+@@ -940,7 +971,7 @@
+              && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
+           ){
+             sqliteExprCode(pParse, aExpr[k].p->pLeft);
+-            aExpr[k].p = 0;
++            disableTerm(pLevel, &aExpr[k].p);
+             break;
+           }
+         }
+@@ -977,7 +1008,7 @@
+           ){
+             sqliteExprCode(pParse, pExpr->pRight);
+             leFlag = pExpr->op==TK_LE;
+-            aExpr[k].p = 0;
++            disableTerm(pLevel, &aExpr[k].p);
+             break;
+           }
+           if( aExpr[k].idxRight==iCur
+@@ -987,7 +1018,7 @@
+           ){
+             sqliteExprCode(pParse, pExpr->pLeft);
+             leFlag = pExpr->op==TK_GE;
+-            aExpr[k].p = 0;
++            disableTerm(pLevel, &aExpr[k].p);
+             break;
+           }
+         }
+@@ -1036,7 +1067,7 @@
+           ){
+             sqliteExprCode(pParse, pExpr->pRight);
+             geFlag = pExpr->op==TK_GE;
+-            aExpr[k].p = 0;
++            disableTerm(pLevel, &aExpr[k].p);
+             break;
+           }
+           if( aExpr[k].idxRight==iCur
+@@ -1046,7 +1077,7 @@
+           ){
+             sqliteExprCode(pParse, pExpr->pLeft);
+             geFlag = pExpr->op==TK_LE;
+-            aExpr[k].p = 0;
++            disableTerm(pLevel, &aExpr[k].p);
+             break;
+           }
+         }
+diff -dPNur sqlite-1.0.3/package.xml sqlite-svn/package.xml
+--- sqlite-1.0.3/package.xml	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/package.xml	2012-10-09 13:36:42.760063980 +0000
+@@ -0,0 +1,158 @@
++<?xml version="1.0" encoding="UTF-8" ?>
++<package version="2.0" xmlns="http://pear.php.net/dtd/package-2.0"
++ xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
++ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
++ xsi:schemaLocation="
++  http://pear.php.net/dtd/tasks-1.0
++  http://pear.php.net/dtd/tasks-1.0.xsd
++  http://pear.php.net/dtd/package-2.0
++  http://pear.php.net/dtd/package-2.0.xsd">
++ <name>SQLite</name>
++ <channel>pecl.php.net</channel>
++ <summary>SQLite 2 database bindings</summary>
++ <description><![CDATA[
++SQLite is a C library that implements an embeddable SQL database engine.
++Programs that link with the SQLite library can have SQL database access
++without running a separate RDBMS process.
++This extension allows access to SQLite 2 databases from within PHP
++using sqlite_* and pdo_sqlite2 functions. 
++
++This extension does not work with SQLite 3 databases; use pdo_sqlite or ext/sqlite3
++for that.
++]]></description>
++ <lead>
++  <name>Wez Furlong</name>
++  <user>wez</user>
++  <email>wez@php.net</email>
++  <active>no</active>
++ </lead>
++ <lead>
++  <name>Marcus Borger</name>
++  <user>helly</user>
++  <email>helly@php.net</email>
++  <active>no</active>
++ </lead>
++ <developer>
++  <name>Ilia Alshanetsky</name>
++  <user>iliaa</user>
++  <email>ilia@php.net</email>
++  <active>no</active>
++ </developer>
++ <developer>
++  <name>Tal Peer</name>
++  <user>tal</user>
++  <email>tal@php.net</email>
++  <active>no</active>
++ </developer>
++ <date>2011-07-08</date>
++ <version>
++  <release>2.0.0</release>
++  <api>2.0.0</api>
++ </version>
++ <stability>
++  <release>stable</release>
++  <api>stable</api>
++ </stability>
++ <license uri="http://www.php.net/license">PHP License</license>
++ <notes><![CDATA[
++   * Moved from php-src back to PECL, and released as version 2.0.0
++   * Upgraded package.xml file from v1 to v2
++]]></notes>
++ <contents>
++  <dir name="/">
++   <file role="src" name="config.m4"/>
++   <file role="src" name="config.w32"/>
++   <file role="src" name="sqlite.c"/>
++   <file role="src" name="sqlite.dsp"/>
++   <file role="src" name="php_sqlite.h"/>
++   <file role="src" name="php_sqlite.def"/>
++   <file role="doc" name="CREDITS"/>
++   <file role="doc" name="README"/>
++   <file role="doc" name="TODO"/>
++   <file role="doc" name="sqlite.php"/>
++   <file role="test" name="tests/sqlite_001.phpt"/>
++   <file role="test" name="tests/sqlite_002.phpt"/>
++   <file role="test" name="tests/sqlite_003.phpt"/>
++   <file role="test" name="tests/sqlite_004.phpt"/>
++   <file role="test" name="tests/sqlite_005.phpt"/>
++   <file role="test" name="tests/sqlite_006.phpt"/>
++   <file role="test" name="tests/sqlite_007.phpt"/>
++   <file role="test" name="tests/sqlite_008.phpt"/>
++   <file role="test" name="tests/sqlite_009.phpt"/>
++   <file role="test" name="tests/sqlite_010.phpt"/>
++   <file role="test" name="tests/sqlite_011.phpt"/>
++   <file role="test" name="tests/sqlite_012.phpt"/>
++   <file role="test" name="tests/sqlite_013.phpt"/>
++   <file role="test" name="tests/sqlite_014.phpt"/>
++   <file role="test" name="tests/sqlite_015.phpt"/>
++   <file role="test" name="tests/sqlite_016.phpt"/>
++   <file role="test" name="tests/sqlite_017.phpt"/>
++   <file role="test" name="tests/blankdb.inc"/>
++
++   <dir name="libsqlite">
++    <file role="doc" name="README"/>
++    <file role="src" name="VERSION"/>
++
++    <dir name="src">
++     <file role="src" name="attach.c"/>
++     <file role="src" name="auth.c"/>
++     <file role="src" name="btree.c"/>
++     <file role="src" name="btree_rb.c"/>
++     <file role="src" name="build.c"/>
++     <file role="src" name="copy.c"/>
++     <file role="src" name="delete.c"/>
++     <file role="src" name="encode.c"/>
++     <file role="src" name="expr.c"/>
++     <file role="src" name="func.c"/>
++     <file role="src" name="hash.c"/>
++     <file role="src" name="insert.c"/>
++     <file role="src" name="main.c"/>
++     <file role="src" name="opcodes.c"/>
++     <file role="src" name="os.c"/>
++     <file role="src" name="pager.c"/>
++     <file role="src" name="parse.c"/>
++     <file role="src" name="parse.y"/>
++     <file role="src" name="pragma.c"/>
++     <file role="src" name="printf.c"/>
++     <file role="src" name="random.c"/>
++     <file role="src" name="select.c"/>
++     <file role="src" name="table.c"/>
++     <file role="src" name="tokenize.c"/>
++     <file role="src" name="trigger.c"/>
++     <file role="src" name="update.c"/>
++     <file role="src" name="util.c"/>
++     <file role="src" name="vacuum.c"/>
++     <file role="src" name="vdbe.c"/>
++     <file role="src" name="where.c"/>
++     <file role="src" name="btree.h"/>
++     <file role="src" name="hash.h"/>
++     <file role="src" name="opcodes.h"/>
++     <file role="src" name="os.h"/>
++     <file role="src" name="pager.h"/>
++     <file role="src" name="parse.h"/>
++     <file role="src" name="sqlite_config.w32.h"/>
++     <file role="src" name="sqlite.h.in"/>
++     <file role="src" name="sqliteInt.h"/>
++     <file role="src" name="sqlite.w32.h"/>
++     <file role="src" name="vdbe.h"/>
++    </dir>
++   </dir>
++  </dir>
++ </contents>
++ <dependencies>
++  <required>
++   <php>
++    <min>5.1.0</min>
++   </php>
++   <pearinstaller>
++    <min>1.4.1</min>
++   </pearinstaller>
++  </required>
++ </dependencies>
++ <providesextension>SQLite</providesextension>
++ <changelog />
++ <extsrcrelease />
++</package>
++<!--
++vim:et:ts=1:sw=1
++-->
+diff -dPNur sqlite-1.0.3/pdo_sqlite2.c sqlite-svn/pdo_sqlite2.c
+--- sqlite-1.0.3/pdo_sqlite2.c	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/pdo_sqlite2.c	2012-10-09 13:36:42.760063980 +0000
+@@ -0,0 +1,633 @@
++/*
++  +----------------------------------------------------------------------+
++  | PHP Version 5                                                        |
++  +----------------------------------------------------------------------+
++  | Copyright (c) 1997-2010 The PHP Group                                |
++  +----------------------------------------------------------------------+
++  | This source file is subject to version 3.01 of the PHP license,      |
++  | that is bundled with this package in the file LICENSE, and is        |
++  | available through the world-wide-web at the following url:           |
++  | http://www.php.net/license/3_01.txt                                  |
++  | If you did not receive a copy of the PHP license and are unable to   |
++  | obtain it through the world-wide-web, please send a note to          |
++  | license@php.net so we can mail you a copy immediately.               |
++  +----------------------------------------------------------------------+
++  | Author: Wez Furlong <wez@php.net>                                    |
++  +----------------------------------------------------------------------+
++*/
++
++/* $Id: pdo_sqlite2.c 300612 2010-06-20 14:12:06Z felipe $ */
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++#include "php.h"
++
++#ifdef PHP_SQLITE2_HAVE_PDO
++#include "sqlite.h"
++#include "pdo/php_pdo.h"
++#include "pdo/php_pdo_driver.h"
++#include "zend_exceptions.h"
++
++#define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
++#define php_sqlite_decode_binary(in, out)    sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out)
++
++
++typedef struct {
++	const char *file;
++	int line;
++	unsigned int errcode;
++	char *errmsg;
++} pdo_sqlite2_error_info;
++
++typedef struct {
++	sqlite *db;
++	pdo_sqlite2_error_info einfo;
++} pdo_sqlite2_db_handle;
++
++typedef struct {
++	pdo_sqlite2_db_handle 	*H;
++	sqlite_vm *vm;
++	const char **rowdata, **colnames;
++	int ncols;
++	unsigned pre_fetched:1;
++	unsigned done:1;
++	pdo_sqlite2_error_info einfo;
++} pdo_sqlite2_stmt;
++
++extern int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC);
++#define pdo_sqlite2_error(msg, s) _pdo_sqlite2_error(s, NULL, msg, __FILE__, __LINE__ TSRMLS_CC)
++#define pdo_sqlite2_error_stmt(msg, s) _pdo_sqlite2_error(stmt->dbh, stmt, msg, __FILE__, __LINE__ TSRMLS_CC)
++
++extern struct pdo_stmt_methods sqlite2_stmt_methods;
++
++static int pdo_sqlite2_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
++{
++	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
++
++	if (S->vm) {
++		char *errmsg = NULL;
++		sqlite_finalize(S->vm, &errmsg);
++		if (errmsg) {
++			sqlite_freemem(errmsg);
++		}
++		S->vm = NULL;
++	}
++	if (S->einfo.errmsg) {
++		pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
++	}
++	efree(S);
++	return 1;
++}
++
++static int pdo_sqlite2_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
++{
++	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
++	char *errmsg = NULL;
++	const char *tail;
++
++	if (stmt->executed && !S->done) {
++		sqlite_finalize(S->vm, &errmsg);
++		pdo_sqlite2_error_stmt(errmsg, stmt);
++		errmsg = NULL;
++		S->vm = NULL;
++	}
++
++	S->einfo.errcode = sqlite_compile(S->H->db, stmt->active_query_string, &tail, &S->vm, &errmsg);
++	if (S->einfo.errcode != SQLITE_OK) {
++		pdo_sqlite2_error_stmt(errmsg, stmt);
++		return 0;
++	}
++
++	S->done = 0;
++	S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
++	switch (S->einfo.errcode) {
++		case SQLITE_ROW:
++			S->pre_fetched = 1;
++			stmt->column_count = S->ncols;
++			return 1;
++
++		case SQLITE_DONE:
++			stmt->column_count = S->ncols;
++			stmt->row_count = sqlite_changes(S->H->db);
++			S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
++			if (S->einfo.errcode != SQLITE_OK) {
++				pdo_sqlite2_error_stmt(errmsg, stmt);
++			}
++			S->done = 1;
++			return 1;
++
++		case SQLITE_ERROR:
++		case SQLITE_MISUSE:
++		case SQLITE_BUSY:
++		default:
++			pdo_sqlite2_error_stmt(errmsg, stmt);
++			return 0;
++	}
++}
++
++static int pdo_sqlite2_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
++		enum pdo_param_event event_type TSRMLS_DC)
++{
++	return 1;
++}
++
++static int pdo_sqlite2_stmt_fetch(pdo_stmt_t *stmt,
++	enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
++{
++	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
++	char *errmsg = NULL;
++
++	if (!S->vm) {
++		return 0;	
++	}
++	if (S->pre_fetched) {
++		S->pre_fetched = 0;
++		return 1;
++	}
++	if (S->done) {
++		return 0;
++	}
++
++	S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
++	switch (S->einfo.errcode) {
++		case SQLITE_ROW:
++			return 1;
++
++		case SQLITE_DONE:
++			S->done = 1;
++			S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
++			if (S->einfo.errcode != SQLITE_OK) {
++				pdo_sqlite2_error_stmt(errmsg, stmt);
++				errmsg = NULL;
++			}
++			return 0;
++
++		default:
++			pdo_sqlite2_error_stmt(errmsg, stmt);
++			return 0;
++	}
++}
++
++static int pdo_sqlite2_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
++{
++	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
++
++	if(colno >= S->ncols) {
++		/* error invalid column */
++		pdo_sqlite2_error_stmt(NULL, stmt);
++		return 0;
++	}
++
++	stmt->columns[colno].name = estrdup(S->colnames[colno]);
++	stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
++	stmt->columns[colno].maxlen = 0xffffffff;
++	stmt->columns[colno].precision = 0;
++	stmt->columns[colno].param_type = PDO_PARAM_STR;
++
++	return 1;
++}
++
++static int pdo_sqlite2_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
++{
++	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
++	if (!S->vm) {
++		return 0;
++	}
++	if(colno >= S->ncols) {
++		/* error invalid column */
++		pdo_sqlite2_error_stmt(NULL, stmt);
++		return 0;
++	}
++	if (S->rowdata[colno]) {
++		if (S->rowdata[colno][0] == '\x01') {
++			/* encoded */
++			*caller_frees = 1;
++			*ptr = emalloc(strlen(S->rowdata[colno]));
++			*len = php_sqlite_decode_binary(S->rowdata[colno]+1, *ptr);
++			(*(char**)ptr)[*len] = '\0';
++		} else {
++			*ptr = (char*)S->rowdata[colno];
++			*len = strlen(*ptr);
++		}
++	} else {
++		*ptr = NULL;
++		*len = 0;
++	}
++	return 1;
++}
++
++struct pdo_stmt_methods sqlite2_stmt_methods = {
++	pdo_sqlite2_stmt_dtor,
++	pdo_sqlite2_stmt_execute,
++	pdo_sqlite2_stmt_fetch,
++	pdo_sqlite2_stmt_describe,
++	pdo_sqlite2_stmt_get_col,
++	pdo_sqlite2_stmt_param_hook,
++	NULL, /* set_attr */
++	NULL, /* get_attr */
++	NULL
++};
++
++
++int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
++	pdo_sqlite2_error_info *einfo = &H->einfo;
++	pdo_sqlite2_stmt *S;
++
++	if (stmt) {
++		S = stmt->driver_data;
++		einfo = &S->einfo;
++	}
++
++	einfo->file = file;
++	einfo->line = line;
++
++	if (einfo->errmsg) {
++		pefree(einfo->errmsg, dbh->is_persistent);
++		einfo->errmsg = NULL;
++	}
++
++	if (einfo->errcode != SQLITE_OK) {
++		if (errmsg) {
++			einfo->errmsg = pestrdup(errmsg, dbh->is_persistent);
++			sqlite_freemem(errmsg);
++		} else {
++			einfo->errmsg = pestrdup(sqlite_error_string(einfo->errcode), dbh->is_persistent);
++		}
++	} else { /* no error */
++		strcpy(*pdo_err, PDO_ERR_NONE);
++		return 0;
++	}
++	switch (einfo->errcode) {
++		case SQLITE_NOTFOUND:
++			strcpy(*pdo_err, "42S02");
++			break;	
++
++		case SQLITE_INTERRUPT:
++			strcpy(*pdo_err, "01002");
++			break;
++
++		case SQLITE_NOLFS:
++			strcpy(*pdo_err, "HYC00");
++			break;
++
++		case SQLITE_TOOBIG:
++			strcpy(*pdo_err, "22001");
++			break;
++
++		case SQLITE_CONSTRAINT:
++			strcpy(*pdo_err, "23000");
++			break;
++
++		case SQLITE_ERROR:
++		default:
++			strcpy(*pdo_err, "HY000");
++			break;
++	}
++
++	if (!dbh->methods) {
++		zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
++				*pdo_err, einfo->errcode, einfo->errmsg);
++	}
++
++	return einfo->errcode;
++}
++/* }}} */
++
++static int pdo_sqlite2_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	pdo_sqlite2_error_info *einfo = &H->einfo;
++	pdo_sqlite2_stmt *S;
++
++	if (stmt) {
++		S = stmt->driver_data;
++		einfo = &S->einfo;
++	}
++
++	if (einfo->errcode) {
++		add_next_index_long(info, einfo->errcode);
++		if (einfo->errmsg) {
++			add_next_index_string(info, einfo->errmsg, 1);
++		}
++	}
++
++	return 1;
++}
++
++static int sqlite2_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	
++	if (H) {
++		if (H->db) {
++			sqlite_close(H->db);
++			H->db = NULL;
++		}
++		if (H->einfo.errmsg) {
++			pefree(H->einfo.errmsg, dbh->is_persistent);
++			H->einfo.errmsg = NULL;
++		}
++		pefree(H, dbh->is_persistent);
++		dbh->driver_data = NULL;
++	}
++	return 0;
++}
++/* }}} */
++
++static int sqlite2_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	pdo_sqlite2_stmt *S = ecalloc(1, sizeof(pdo_sqlite2_stmt));
++
++	S->H = H;
++	stmt->driver_data = S;
++	stmt->methods = &sqlite2_stmt_methods;
++	stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
++
++	if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
++		H->einfo.errcode = SQLITE_ERROR;
++		pdo_sqlite2_error(NULL, dbh);
++		return 0;
++	}
++
++	return 1;
++}
++
++static long sqlite2_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	char *errmsg = NULL;
++
++	if ((H->einfo.errcode = sqlite_exec(H->db, sql, NULL, NULL, &errmsg)) != SQLITE_OK) {
++		pdo_sqlite2_error(errmsg, dbh);
++		return -1;
++	} else {
++		return sqlite_changes(H->db);
++	}
++}
++
++static char *pdo_sqlite2_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	char *id;
++	
++	id = php_pdo_int64_to_str(sqlite_last_insert_rowid(H->db) TSRMLS_CC);
++	*len = strlen(id);
++	return id;
++}
++
++static int sqlite2_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype  TSRMLS_DC)
++{
++	char *ret;
++
++	if (unquotedlen && (unquoted[0] == '\x01' || memchr(unquoted, '\0', unquotedlen) != NULL)) {
++		/* binary string */
++		int len;
++		ret = safe_emalloc(1 + unquotedlen / 254, 257, 5);
++		ret[0] = '\'';
++		ret[1] = '\x01';
++		len = php_sqlite_encode_binary(unquoted, unquotedlen, ret+2);
++		ret[len + 2] = '\'';
++		ret[len + 3] = '\0';
++		*quoted = ret;
++		*quotedlen = len + 3;
++		/* fprintf(stderr, "Quoting:%d:%.*s:\n", *quotedlen, *quotedlen, *quoted); */
++		return 1;
++	} else if (unquotedlen) {
++		ret = sqlite_mprintf("'%q'", unquoted);
++		if (ret) {
++			*quoted = estrdup(ret);
++			*quotedlen = strlen(ret);
++			sqlite_freemem(ret);
++			return 1;
++		}
++		return 0;
++	} else {
++		*quoted = estrdup("''");
++		*quotedlen = 2;
++		return 1;
++	}
++}
++
++static int sqlite2_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	char *errmsg = NULL;
++
++	if (sqlite_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
++		pdo_sqlite2_error(errmsg, dbh);
++		return 0;
++	}
++	return 1;
++}
++
++static int sqlite2_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	char *errmsg = NULL;
++
++	if (sqlite_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
++		pdo_sqlite2_error(errmsg, dbh);
++		return 0;
++	}
++	return 1;
++}
++
++static int sqlite2_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++	char *errmsg = NULL;
++
++	if (sqlite_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
++		pdo_sqlite2_error(errmsg, dbh);
++		return 0;
++	}
++	return 1;
++}
++
++static int pdo_sqlite2_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
++{
++	switch (attr) {
++		case PDO_ATTR_CLIENT_VERSION:
++		case PDO_ATTR_SERVER_VERSION:
++			ZVAL_STRING(return_value, (char *)sqlite_libversion(), 1);
++			break;
++		
++		default:
++			return 0;	
++	}
++
++	return 1;
++}
++
++static int pdo_sqlite2_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
++{
++	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
++
++	switch (attr) {
++		case PDO_ATTR_TIMEOUT:
++			convert_to_long(val);
++			sqlite_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
++			return 1;
++	}
++	return 0;
++}
++
++static PHP_FUNCTION(sqlite2_create_function)
++{
++	/* TODO: implement this stuff */
++}
++
++static const zend_function_entry dbh_methods[] = {
++	PHP_FE(sqlite2_create_function, NULL)
++	{NULL, NULL, NULL}
++};
++
++static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
++{
++	switch (kind) {
++		case PDO_DBH_DRIVER_METHOD_KIND_DBH:
++			return dbh_methods;
++
++		default:
++			return NULL;
++	}
++}
++
++static struct pdo_dbh_methods sqlite2_methods = {
++	sqlite2_handle_closer,
++	sqlite2_handle_preparer,
++	sqlite2_handle_doer,
++	sqlite2_handle_quoter,
++	sqlite2_handle_begin,
++	sqlite2_handle_commit,
++	sqlite2_handle_rollback,
++	pdo_sqlite2_set_attr,
++	pdo_sqlite2_last_insert_id,
++	pdo_sqlite2_fetch_error_func,
++	pdo_sqlite2_get_attribute,
++	NULL,	/* check_liveness: not needed */
++	get_driver_methods
++};
++
++static char *make_filename_safe(const char *filename TSRMLS_DC)
++{
++	if (*filename && strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
++		char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
++
++		if (!fullpath) {
++			return NULL;
++		}
++
++		if (php_check_open_basedir(fullpath TSRMLS_CC)) {
++			efree(fullpath);
++			return NULL;
++		}
++		return fullpath;
++	}
++	return estrdup(filename);
++}
++
++static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
++		const char *arg5, const char *arg6)
++{
++	char *filename;
++	switch (access_type) {
++		case SQLITE_COPY: {
++			TSRMLS_FETCH();
++			filename = make_filename_safe(arg4 TSRMLS_CC);
++			if (!filename) {
++				return SQLITE_DENY;
++			}
++			efree(filename);
++			return SQLITE_OK;
++		}
++
++		case SQLITE_ATTACH: {
++			TSRMLS_FETCH();
++			filename = make_filename_safe(arg3 TSRMLS_CC);
++			if (!filename) {
++				return SQLITE_DENY;
++			}
++			efree(filename);
++			return SQLITE_OK;
++		}
++
++		default:
++			/* access allowed */
++			return SQLITE_OK;
++	}
++}
++
++static int pdo_sqlite2_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
++{
++	pdo_sqlite2_db_handle *H;
++	int ret = 0;
++	long timeout = 60;
++	char *filename;
++	char *errmsg = NULL;
++
++	H = pecalloc(1, sizeof(pdo_sqlite2_db_handle), dbh->is_persistent);
++
++	H->einfo.errcode = 0;
++	H->einfo.errmsg = NULL;
++	dbh->driver_data = H;
++
++	filename = make_filename_safe(dbh->data_source TSRMLS_CC);
++
++	if (!filename) {
++		zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
++				"open_basedir prohibits opening %s",
++				dbh->data_source);
++		goto cleanup;
++	}
++
++	H->db = sqlite_open(filename, 0666, &errmsg);
++	efree(filename);
++
++	if (!H->db) {
++		H->einfo.errcode = SQLITE_ERROR;
++		pdo_sqlite2_error(errmsg, dbh);
++		goto cleanup;
++	}
++
++	sqlite_set_authorizer(H->db, authorizer, NULL);
++
++	if (driver_options) {
++		timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
++	}
++	sqlite_busy_timeout(H->db, timeout * 1000);
++
++	dbh->alloc_own_columns = 1;
++	dbh->max_escaped_char_length = 2;
++
++	ret = 1;
++
++cleanup:
++	dbh->methods = &sqlite2_methods;
++
++	return ret;
++}
++/* }}} */
++
++pdo_driver_t pdo_sqlite2_driver = {
++	PDO_DRIVER_HEADER(sqlite2),
++	pdo_sqlite2_handle_factory
++};
++
++
++
++#endif
++
++
++/*
++ * Local variables:
++ * tab-width: 4
++ * c-basic-offset: 4
++ * End:
++ * vim600: noet sw=4 ts=4 fdm=marker
++ * vim<600: noet sw=4 ts=4
++ */
+diff -dPNur sqlite-1.0.3/php_sqlite.def sqlite-svn/php_sqlite.def
+--- sqlite-1.0.3/php_sqlite.def	2003-06-12 23:22:33.000000000 +0000
++++ sqlite-svn/php_sqlite.def	2012-10-09 13:36:42.760063980 +0000
+@@ -35,3 +35,9 @@
+ sqlite_compile
+ sqlite_step
+ sqlite_finalize
++; some experimental stuff
++sqlite_last_statement_changes
++sqlite_reset
++sqlite_bind
++sqlite_progress_handler
++sqlite_commit_hook
+diff -dPNur sqlite-1.0.3/php_sqlite.h sqlite-svn/php_sqlite.h
+--- sqlite-1.0.3/php_sqlite.h	2004-05-13 14:54:55.000000000 +0000
++++ sqlite-svn/php_sqlite.h	2012-10-09 13:36:42.760063980 +0000
+@@ -1,13 +1,13 @@
+ /*
+    +----------------------------------------------------------------------+
+-   | PHP Version 4                                                        |
++   | PHP Version 5                                                        |
+    +----------------------------------------------------------------------+
+-   | Copyright (c) 1997-2003 The PHP Group                                |
++   | Copyright (c) 1997-2010 The PHP Group                                |
+    +----------------------------------------------------------------------+
+-   | This source file is subject to version 3.0 of the PHP license,       |
++   | This source file is subject to version 3.01 of the PHP license,      |
+    | that is bundled with this package in the file LICENSE, and is        |
+    | available through the world-wide-web at the following url:           |
+-   | http://www.php.net/license/3_0.txt.                                  |
++   | http://www.php.net/license/3_01.txt                                  |
+    | If you did not receive a copy of the PHP license and are unable to   |
+    | obtain it through the world-wide-web, please send a note to          |
+    | license@php.net so we can mail you a copy immediately.               |
+@@ -17,7 +17,7 @@
+    |          Marcus Boerger <helly@php.net>                              |
+    +----------------------------------------------------------------------+
+ 
+-   $Id: php_sqlite.h,v 1.23.2.3 2004/05/13 14:54:55 stas Exp $ 
++   $Id: php_sqlite.h 293036 2010-01-03 09:23:27Z sebastian $ 
+ */
+ 
+ #ifndef PHP_SQLITE_H
+@@ -26,19 +26,12 @@
+ extern zend_module_entry sqlite_module_entry;
+ #define phpext_sqlite_ptr &sqlite_module_entry
+ 
+-#ifdef PHP_WIN32
+-#define PHP_SQLITE_API __declspec(dllexport)
+-#else
+-#define PHP_SQLITE_API
+-#endif
+-
+ #ifdef ZTS
+ #include "TSRM.h"
+ #endif
+ 
+ PHP_MINIT_FUNCTION(sqlite);
+ PHP_MSHUTDOWN_FUNCTION(sqlite);
+-PHP_RINIT_FUNCTION(sqlite);
+ PHP_RSHUTDOWN_FUNCTION(sqlite);
+ PHP_MINFO_FUNCTION(sqlite);
+ 
+@@ -52,6 +45,7 @@
+ PHP_FUNCTION(sqlite_single_query);
+ 
+ PHP_FUNCTION(sqlite_fetch_array);
++PHP_FUNCTION(sqlite_fetch_object);
+ PHP_FUNCTION(sqlite_fetch_single);
+ PHP_FUNCTION(sqlite_fetch_all);
+ PHP_FUNCTION(sqlite_current);
+@@ -63,7 +57,11 @@
+ PHP_FUNCTION(sqlite_seek);
+ PHP_FUNCTION(sqlite_rewind);
+ PHP_FUNCTION(sqlite_next);
+-PHP_FUNCTION(sqlite_has_more);
++PHP_FUNCTION(sqlite_prev);
++PHP_FUNCTION(sqlite_key);
++
++PHP_FUNCTION(sqlite_valid);
++PHP_FUNCTION(sqlite_has_prev);
+ 
+ PHP_FUNCTION(sqlite_libversion);
+ PHP_FUNCTION(sqlite_libencoding);
+@@ -83,6 +81,10 @@
+ PHP_FUNCTION(sqlite_udf_decode_binary);
+ PHP_FUNCTION(sqlite_udf_encode_binary);
+ 
++PHP_FUNCTION(sqlite_factory);
++
++PHP_FUNCTION(sqlite_fetch_column_types);
++
+ ZEND_BEGIN_MODULE_GLOBALS(sqlite)
+ 	 long assoc_case;
+ ZEND_END_MODULE_GLOBALS(sqlite)
+diff -dPNur sqlite-1.0.3/sess_sqlite.c sqlite-svn/sess_sqlite.c
+--- sqlite-1.0.3/sess_sqlite.c	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/sess_sqlite.c	2012-10-09 13:36:42.760063980 +0000
+@@ -0,0 +1,200 @@
++/* 
++   +----------------------------------------------------------------------+
++   | PHP Version 5                                                        |
++   +----------------------------------------------------------------------+
++   | Copyright (c) 1997-2010 The PHP Group                                |
++   +----------------------------------------------------------------------+
++   | This source file is subject to version 3.01 of the PHP license,      |
++   | that is bundled with this package in the file LICENSE, and is        |
++   | available through the world-wide-web at the following url:           |
++   | http://www.php.net/license/3_01.txt                                  |
++   | If you did not receive a copy of the PHP license and are unable to   |
++   | obtain it through the world-wide-web, please send a note to          |
++   | license@php.net so we can mail you a copy immediately.               |
++   +----------------------------------------------------------------------+
++   | Authors: John Coggeshall <john@php.net>                              |
++   |          Wez Furlong <wez@thebrainroom.com>                          |
++   +----------------------------------------------------------------------+
++ */
++
++/* $Id: sess_sqlite.c 298625 2010-04-26 23:53:30Z kalle $ */
++
++#include "php.h"
++
++#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
++
++#include "ext/session/php_session.h"
++#include "ext/standard/php_lcg.h"
++#include <sqlite.h>
++#define SQLITE_RETVAL(__r) ((__r) == SQLITE_OK ? SUCCESS : FAILURE)
++#define PS_SQLITE_DATA sqlite *db = (sqlite*)PS_GET_MOD_DATA()
++extern int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
++extern int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
++
++PS_FUNCS(sqlite);
++
++ps_module ps_mod_sqlite = {
++	PS_MOD(sqlite)
++};
++
++PS_OPEN_FUNC(sqlite) 
++{
++	char *errmsg = NULL;
++	sqlite *db;
++
++	db = sqlite_open(save_path, 0666, &errmsg);
++	if (db == NULL) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, 
++				"SQLite: failed to open/create session database `%s' - %s", save_path, errmsg);
++		sqlite_freemem(errmsg);
++		return FAILURE;
++	}
++
++	/* allow up to 1 minute when busy */
++	sqlite_busy_timeout(db, 60000);
++
++	sqlite_exec(db, "PRAGMA default_synchronous = OFF", NULL, NULL, NULL);
++	sqlite_exec(db, "PRAGMA count_changes = OFF", NULL, NULL, NULL);
++
++	/* This will fail if the table already exists, but that's not a big problem. I'm
++	   unclear as to how to check for a table's existence in SQLite -- that would be better here. */
++	sqlite_exec(db, 
++	    "CREATE TABLE session_data ("
++	    "    sess_id PRIMARY KEY," 
++	    "    value TEXT, "
++	    "    updated INTEGER "
++	    ")", NULL, NULL, NULL);
++
++	PS_SET_MOD_DATA(db);
++
++	return SUCCESS;
++}
++
++PS_CLOSE_FUNC(sqlite) 
++{
++	PS_SQLITE_DATA;
++
++	sqlite_close(db);
++
++	return SUCCESS;
++}
++
++PS_READ_FUNC(sqlite) 
++{
++	PS_SQLITE_DATA;
++	char *query;
++	const char *tail;
++	sqlite_vm *vm;
++	int colcount, result;
++	const char **rowdata, **colnames;
++	char *error;
++
++	*val = NULL;
++	*vallen = 0;
++	
++	query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key);
++	if (query == NULL) {
++		/* no memory */
++		return FAILURE;
++	}
++
++	if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session read query: %s", error);
++		sqlite_freemem(error);
++		sqlite_freemem(query);
++		return FAILURE;
++	}
++
++	switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) {
++		case SQLITE_ROW:
++			if (rowdata[0] != NULL) {
++				*vallen = strlen(rowdata[0]);
++				if (*vallen) {
++					*val = emalloc(*vallen);
++					*vallen = sqlite_decode_binary(rowdata[0], *val);
++					(*val)[*vallen] = '\0';
++				} else {
++					*val = STR_EMPTY_ALLOC();
++				}
++			}
++			break;
++		default:
++			sqlite_freemem(error);
++			error = NULL;
++	}
++	
++	if (SQLITE_OK != sqlite_finalize(vm, &error)) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session read: error %s", error);
++		sqlite_freemem(error);
++		error = NULL;
++	}
++
++	sqlite_freemem(query);
++	
++	return *val == NULL ? FAILURE : SUCCESS;
++}
++
++PS_WRITE_FUNC(sqlite) 
++{
++	PS_SQLITE_DATA;
++	char *error;
++	time_t t;
++	char *binary;
++	int binlen;
++	int rv;
++	
++	t = time(NULL);
++
++	binary = safe_emalloc(1 + vallen / 254, 257, 3);
++	binlen = sqlite_encode_binary((const unsigned char*)val, vallen, binary);
++	
++	rv = sqlite_exec_printf(db, "REPLACE INTO session_data VALUES('%q', '%q', %d)", NULL, NULL, &error, key, binary, t);
++	if (rv != SQLITE_OK) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session write query failed: %s", error);
++		sqlite_freemem(error);
++	}
++	efree(binary);
++
++	return SQLITE_RETVAL(rv);
++}
++
++PS_DESTROY_FUNC(sqlite) 
++{
++	int rv;
++	PS_SQLITE_DATA;
++
++	rv = sqlite_exec_printf(db, "DELETE FROM session_data WHERE sess_id='%q'", NULL, NULL, NULL, key);
++	
++	return SQLITE_RETVAL(rv);
++}
++
++PS_GC_FUNC(sqlite) 
++{
++	PS_SQLITE_DATA;
++	int rv;
++	time_t t = time(NULL);
++
++	rv = sqlite_exec_printf(db, 
++			"DELETE FROM session_data WHERE (%d - updated) > %d", 
++			NULL, NULL, NULL, t, maxlifetime);
++
++	/* because SQLite does not actually clear the deleted data from the database 
++	 * we need to occassionaly do so manually to prevent the sessions database 
++	 * from growing endlessly.
++	 */
++	if ((int) ((float) PS(gc_divisor) * PS(gc_divisor) * php_combined_lcg(TSRMLS_C)) < PS(gc_probability)) {
++		rv = sqlite_exec_printf(db, "VACUUM", NULL, NULL, NULL);
++	}
++	return SQLITE_RETVAL(rv);
++}
++
++#endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */
++
++/*
++ * Local variables:
++ * tab-width: 4
++ * c-basic-offset: 4
++ * End:
++ * vim600: sw=4 ts=4 fdm=marker
++ * vim<600: sw=4 ts=4
++ */
+diff -dPNur sqlite-1.0.3/sqlite.c sqlite-svn/sqlite.c
+--- sqlite-1.0.3/sqlite.c	2004-07-18 10:23:18.000000000 +0000
++++ sqlite-svn/sqlite.c	2012-10-09 13:36:42.760063980 +0000
+@@ -1,13 +1,13 @@
+ /*
+    +----------------------------------------------------------------------+
+-   | PHP Version 4                                                        |
++   | PHP Version 5                                                        |
+    +----------------------------------------------------------------------+
+-   | Copyright (c) 1997-2003 The PHP Group                                |
++   | Copyright (c) 1997-2010 The PHP Group                                |
+    +----------------------------------------------------------------------+
+-   | This source file is subject to version 3.0 of the PHP license,       |
++   | This source file is subject to version 3.01 of the PHP license,      |
+    | that is bundled with this package in the file LICENSE, and is        |
+    | available through the world-wide-web at the following url:           |
+-   | http://www.php.net/license/3_0.txt.                                  |
++   | http://www.php.net/license/3_01.txt                                  |
+    | If you did not receive a copy of the PHP license and are unable to   |
+    | obtain it through the world-wide-web, please send a note to          |
+    | license@php.net so we can mail you a copy immediately.               |
+@@ -17,43 +17,65 @@
+    |          Marcus Boerger <helly@php.net>                              |
+    +----------------------------------------------------------------------+
+ 
+-   $Id: sqlite.c,v 1.62.2.25 2004/07/10 12:25:33 wez Exp $ 
++   $Id: sqlite.c 299692 2010-05-24 14:11:39Z dmitry $
+ */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+ 
+-#define PHP_SQLITE_MODULE_VERSION	"1.0.3"
++#define PHP_SQLITE_MODULE_VERSION	"2.0-dev"
+ 
+ #include "php.h"
+ #include "php_ini.h"
+ #include "ext/standard/info.h"
++#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
++#include "ext/session/php_session.h"
++#endif
+ #include "php_sqlite.h"
+ 
+ #if HAVE_TIME_H
+ # include <time.h>
+ #endif
+-#ifdef HAVE_UNISTD_H
++#if HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ 
+ #include <sqlite.h>
+ 
+-#ifndef safe_emalloc
+-# define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
++#include "zend_exceptions.h"
++#include "zend_interfaces.h"
++
++#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
++extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
++extern PHPAPI zend_class_entry *spl_ce_Countable;
+ #endif
+ 
+-#ifndef ZEND_ENGINE_2
+-# define OnUpdateLong OnUpdateInt
++#if PHP_SQLITE2_HAVE_PDO
++# include "pdo/php_pdo.h"
++# include "pdo/php_pdo_driver.h"
++extern pdo_driver_t pdo_sqlite2_driver;
++#endif
++
++#ifndef safe_emalloc
++# define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
+ #endif
+ 
+ ZEND_DECLARE_MODULE_GLOBALS(sqlite)
++static PHP_GINIT_FUNCTION(sqlite);
++
++#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
++extern ps_module ps_mod_sqlite;
++#define ps_sqlite_ptr &ps_mod_sqlite
++#endif
+ 
+ extern int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
+ extern int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
+ 
+-static unsigned char arg3_force_ref[] = {3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
++#define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
++#define php_sqlite_decode_binary(in, out) in && *in ? sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out) : 0
++
++static int sqlite_count_elements(zval *object, long *count TSRMLS_DC);
+ 
+ static int le_sqlite_db, le_sqlite_result, le_sqlite_pdb;
+ 
+@@ -80,11 +102,34 @@
+ PHP_INI_END()
+ /* }}} */
+ 
+-
+ #define DB_FROM_ZVAL(db, zv)	ZEND_FETCH_RESOURCE2(db, struct php_sqlite_db *, zv, -1, "sqlite database", le_sqlite_db, le_sqlite_pdb)
+ 
++#define DB_FROM_OBJECT(db, object) \
++	{ \
++		sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
++		db = obj->u.db; \
++		if (!db) { \
++			php_error_docref(NULL TSRMLS_CC, E_WARNING, "The database wasn't opened"); \
++			RETURN_NULL(); \
++		} \
++	}
++
++#define RES_FROM_OBJECT_RESTORE_ERH(res, object, error_handling) \
++	{ \
++		sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
++		res = obj->u.res; \
++		if (!res) { \
++			php_error_docref(NULL TSRMLS_CC, E_WARNING, "No result set available"); \
++			if (error_handling) \
++				zend_restore_error_handling(error_handling TSRMLS_CC); \
++			RETURN_NULL(); \
++		} \
++	}
++
++#define RES_FROM_OBJECT(res, object) RES_FROM_OBJECT_RESTORE_ERH(res, object, NULL)
++
+ #define PHP_SQLITE_EMPTY_QUERY \
+-	if (!sql_len) { \
++	if (!sql_len || !*sql) { \
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute empty query."); \
+ 		RETURN_FALSE; \
+ 	}
+@@ -98,15 +143,15 @@
+ 	int curr_row;
+ 	char **col_names;
+ 	int alloc_rows;
+-	char **table;
+ 	int mode;
++	char **table;
+ };
+ 
+ struct php_sqlite_db {
+ 	sqlite *db;
+ 	int last_err_code;
+-	int is_persistent;
+-	int rsrc_id;
++	zend_bool is_persistent;
++	long rsrc_id;
+ 
+ 	HashTable callbacks;
+ };
+@@ -118,62 +163,475 @@
+ 	zval *fini;
+ };
+ 
++static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC);
++static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC);
+ 
+ enum { PHPSQLITE_ASSOC = 1, PHPSQLITE_NUM = 2, PHPSQLITE_BOTH = PHPSQLITE_ASSOC|PHPSQLITE_NUM };
+ 
+-function_entry sqlite_functions[] = {
+-	PHP_FE(sqlite_open, arg3_force_ref)
+-	PHP_FE(sqlite_popen, arg3_force_ref)
+-	PHP_FE(sqlite_close, NULL)
+-	PHP_FE(sqlite_query, NULL)
+-	PHP_FE(sqlite_exec, NULL)
+-	PHP_FE(sqlite_array_query, NULL)
+-	PHP_FE(sqlite_single_query, NULL)
+-	PHP_FE(sqlite_fetch_array, NULL)
+-	PHP_FE(sqlite_fetch_single, NULL)
+-	PHP_FALIAS(sqlite_fetch_string, sqlite_fetch_single, NULL)
+-	PHP_FE(sqlite_fetch_all, NULL)
+-	PHP_FE(sqlite_current, NULL)
+-	PHP_FE(sqlite_column, NULL)
+-	PHP_FE(sqlite_libversion, NULL)
+-	PHP_FE(sqlite_libencoding, NULL)
+-	PHP_FE(sqlite_changes, NULL)
+-	PHP_FE(sqlite_last_insert_rowid, NULL)
+-	PHP_FE(sqlite_num_rows, NULL)
+-	PHP_FE(sqlite_num_fields, NULL)
+-	PHP_FE(sqlite_field_name, NULL)
+-	PHP_FE(sqlite_seek, NULL)
+-	PHP_FE(sqlite_rewind, NULL)
+-	PHP_FE(sqlite_next, NULL)
+-	PHP_FE(sqlite_has_more, NULL)
+-	PHP_FE(sqlite_escape_string, NULL)
+-	PHP_FE(sqlite_busy_timeout, NULL)
+-	PHP_FE(sqlite_last_error, NULL)
+-	PHP_FE(sqlite_error_string, NULL)
+-	PHP_FE(sqlite_unbuffered_query, NULL)
+-	PHP_FE(sqlite_create_aggregate, NULL)
+-	PHP_FE(sqlite_create_function, NULL)
+-	PHP_FE(sqlite_udf_encode_binary, NULL)
+-	PHP_FE(sqlite_udf_decode_binary, NULL)
++/* {{{ arginfo */
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_popen, 0, 0, 1)
++	ZEND_ARG_INFO(0, filename)
++	ZEND_ARG_INFO(0, mode)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_open, 0, 0, 1)
++	ZEND_ARG_INFO(0, filename)
++	ZEND_ARG_INFO(0, mode)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_factory, 0, 0, 1)
++	ZEND_ARG_INFO(0, filename)
++	ZEND_ARG_INFO(0, mode)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_busy_timeout, 0, 0, 2)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, ms)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_busy_timeout, 0, 0, 1)
++	ZEND_ARG_INFO(0, ms)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_close, 0, 0, 1)
++	ZEND_ARG_INFO(0, db)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_unbuffered_query, 0, 0, 2)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_unbuffered_query, 0, 0, 1)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_column_types, 0, 0, 2)
++	ZEND_ARG_INFO(0, table_name)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, result_type)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_column_types, 0, 0, 1)
++	ZEND_ARG_INFO(0, table_name)
++	ZEND_ARG_INFO(0, result_type)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_query, 0, 0, 2)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_query, 0, 0, 1)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_exec, 0, 0, 2)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_exec, 0, 0, 1)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(1, error_message)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_all, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_all, 0, 0, 0)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_array, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_array, 0, 0, 0)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_object, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, class_name)
++	ZEND_ARG_INFO(0, ctor_params)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_object, 0, 0, 0)
++	ZEND_ARG_INFO(0, class_name)
++	ZEND_ARG_INFO(0, ctor_params)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_array_query, 0, 0, 2)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_array_query, 0, 0, 1)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_single_query, 0, 0, 2)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, first_row_only)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_single_query, 0, 0, 1)
++	ZEND_ARG_INFO(0, query)
++	ZEND_ARG_INFO(0, first_row_only)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_single, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_single, 0, 0, 0)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_current, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_current, 0, 0, 0)
++	ZEND_ARG_INFO(0, result_type)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_column, 0, 0, 2)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, index_or_name)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_column, 0, 0, 1)
++	ZEND_ARG_INFO(0, index_or_name)
++	ZEND_ARG_INFO(0, decode_binary)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libversion, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libencoding, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_changes, 0, 0, 1)
++	ZEND_ARG_INFO(0, db)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_changes, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_insert_rowid, 0, 0, 1)
++	ZEND_ARG_INFO(0, db)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_insert_rowid, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_rows, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_rows, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_valid, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_valid, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_has_prev, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_has_prev, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_fields, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_fields, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_field_name, 0, 0, 2)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, field_index)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_field_name, 0, 0, 1)
++	ZEND_ARG_INFO(0, field_index)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_seek, 0, 0, 2)
++	ZEND_ARG_INFO(0, result)
++	ZEND_ARG_INFO(0, row)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_seek, 0, 0, 1)
++	ZEND_ARG_INFO(0, row)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_rewind, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_rewind, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_next, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_next, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_key, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_key, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_prev, 0, 0, 1)
++	ZEND_ARG_INFO(0, result)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_prev, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_escape_string, 0, 0, 1)
++	ZEND_ARG_INFO(0, item)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_error, 0, 0, 1)
++	ZEND_ARG_INFO(0, db)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_error, 0)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_error_string, 0, 0, 1)
++	ZEND_ARG_INFO(0, error_code)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_aggregate, 0, 0, 4)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, funcname)
++	ZEND_ARG_INFO(0, step_func)
++	ZEND_ARG_INFO(0, finalize_func)
++	ZEND_ARG_INFO(0, num_args)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_aggregate, 0, 0, 3)
++	ZEND_ARG_INFO(0, funcname)
++	ZEND_ARG_INFO(0, step_func)
++	ZEND_ARG_INFO(0, finalize_func)
++	ZEND_ARG_INFO(0, num_args)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_function, 0, 0, 3)
++	ZEND_ARG_INFO(0, db)
++	ZEND_ARG_INFO(0, funcname)
++	ZEND_ARG_INFO(0, callback)
++	ZEND_ARG_INFO(0, num_args)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_function, 0, 0, 2)
++	ZEND_ARG_INFO(0, funcname)
++	ZEND_ARG_INFO(0, callback)
++	ZEND_ARG_INFO(0, num_args)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_encode_binary, 0, 0, 1)
++	ZEND_ARG_INFO(0, data)
++ZEND_END_ARG_INFO()
++
++ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_decode_binary, 0, 0, 1)
++	ZEND_ARG_INFO(0, data)
++ZEND_END_ARG_INFO()
++/* }}} */
++
++const zend_function_entry sqlite_functions[] = {
++	PHP_FE(sqlite_open, 				arginfo_sqlite_open)
++	PHP_FE(sqlite_popen, 				arginfo_sqlite_popen)
++	PHP_FE(sqlite_close, 				arginfo_sqlite_close)
++	PHP_FE(sqlite_query, 				arginfo_sqlite_query)
++	PHP_FE(sqlite_exec, 				arginfo_sqlite_exec)
++	PHP_FE(sqlite_array_query, 			arginfo_sqlite_array_query)
++	PHP_FE(sqlite_single_query, 		arginfo_sqlite_single_query)
++	PHP_FE(sqlite_fetch_array, 			arginfo_sqlite_fetch_array)
++	PHP_FE(sqlite_fetch_object, 		arginfo_sqlite_fetch_object)
++	PHP_FE(sqlite_fetch_single, 		arginfo_sqlite_fetch_single)
++	PHP_FALIAS(sqlite_fetch_string, sqlite_fetch_single, arginfo_sqlite_fetch_single)
++	PHP_FE(sqlite_fetch_all, 			arginfo_sqlite_fetch_all)
++	PHP_FE(sqlite_current, 				arginfo_sqlite_current)
++	PHP_FE(sqlite_column, 				arginfo_sqlite_column)
++	PHP_FE(sqlite_libversion, 			arginfo_sqlite_libversion)
++	PHP_FE(sqlite_libencoding, 			arginfo_sqlite_libencoding)
++	PHP_FE(sqlite_changes, 				arginfo_sqlite_changes)
++	PHP_FE(sqlite_last_insert_rowid, 	arginfo_sqlite_last_insert_rowid)
++	PHP_FE(sqlite_num_rows, 			arginfo_sqlite_num_rows)
++	PHP_FE(sqlite_num_fields, 			arginfo_sqlite_num_fields)
++	PHP_FE(sqlite_field_name, 			arginfo_sqlite_field_name)
++	PHP_FE(sqlite_seek, 				arginfo_sqlite_seek)
++	PHP_FE(sqlite_rewind, 				arginfo_sqlite_rewind)
++	PHP_FE(sqlite_next, 				arginfo_sqlite_next)
++	PHP_FE(sqlite_prev, 				arginfo_sqlite_prev)
++	PHP_FE(sqlite_valid, 				arginfo_sqlite_valid)
++	PHP_FALIAS(sqlite_has_more, sqlite_valid, arginfo_sqlite_valid)
++	PHP_FE(sqlite_has_prev, 			arginfo_sqlite_has_prev)
++	PHP_FE(sqlite_escape_string, 		arginfo_sqlite_escape_string)
++	PHP_FE(sqlite_busy_timeout, 		arginfo_sqlite_busy_timeout)
++	PHP_FE(sqlite_last_error, 			arginfo_sqlite_last_error)
++	PHP_FE(sqlite_error_string, 		arginfo_sqlite_error_string)
++	PHP_FE(sqlite_unbuffered_query, 	arginfo_sqlite_unbuffered_query)
++	PHP_FE(sqlite_create_aggregate, 	arginfo_sqlite_create_aggregate)
++	PHP_FE(sqlite_create_function, 		arginfo_sqlite_create_function)
++	PHP_FE(sqlite_factory, 				arginfo_sqlite_factory)
++	PHP_FE(sqlite_udf_encode_binary, 	arginfo_sqlite_udf_encode_binary)
++	PHP_FE(sqlite_udf_decode_binary, 	arginfo_sqlite_udf_decode_binary)
++	PHP_FE(sqlite_fetch_column_types,	arginfo_sqlite_fetch_column_types)
++	{NULL, NULL, NULL}
++};
++
++const zend_function_entry sqlite_funcs_db[] = {
++	PHP_ME_MAPPING(__construct, sqlite_open, arginfo_sqlite_open, 0)
++/*	PHP_ME_MAPPING(close, sqlite_close, NULL, 0)*/
++	PHP_ME_MAPPING(query, sqlite_query, arginfo_sqlite_method_query, 0)
++	PHP_ME_MAPPING(queryExec, sqlite_exec, arginfo_sqlite_method_exec, 0)
++	PHP_ME_MAPPING(arrayQuery, sqlite_array_query, arginfo_sqlite_method_array_query, 0)
++	PHP_ME_MAPPING(singleQuery, sqlite_single_query, arginfo_sqlite_method_single_query, 0)
++	PHP_ME_MAPPING(unbufferedQuery, sqlite_unbuffered_query, arginfo_sqlite_method_unbuffered_query, 0)
++	PHP_ME_MAPPING(lastInsertRowid, sqlite_last_insert_rowid, arginfo_sqlite_method_last_insert_rowid, 0)
++	PHP_ME_MAPPING(changes, sqlite_changes, arginfo_sqlite_method_changes, 0)
++	PHP_ME_MAPPING(createAggregate, sqlite_create_aggregate, arginfo_sqlite_method_create_aggregate, 0)
++	PHP_ME_MAPPING(createFunction, sqlite_create_function, arginfo_sqlite_method_create_function, 0)
++	PHP_ME_MAPPING(busyTimeout, sqlite_busy_timeout, arginfo_sqlite_method_busy_timeout, 0)
++	PHP_ME_MAPPING(lastError, sqlite_last_error, arginfo_sqlite_method_last_error, 0)
++	PHP_ME_MAPPING(fetchColumnTypes, sqlite_fetch_column_types, arginfo_sqlite_method_fetch_column_types, 0)
++/*	PHP_ME_MAPPING(error_string, sqlite_error_string, NULL, 0) static */
++/*	PHP_ME_MAPPING(escape_string, sqlite_escape_string, NULL, 0) static */
++	{NULL, NULL, NULL}
++};
++
++const zend_function_entry sqlite_funcs_query[] = {
++	PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
++	PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
++	PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
++	PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
++	PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
++	PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
++	PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
++	/* iterator */
++	PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
++	PHP_ME_MAPPING(key, sqlite_key, arginfo_sqlite_method_key, 0)
++	PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
++	PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
++	PHP_ME_MAPPING(rewind, sqlite_rewind, arginfo_sqlite_method_rewind, 0)
++	/* countable */
++	PHP_ME_MAPPING(count, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
++	/* additional */
++	PHP_ME_MAPPING(prev, sqlite_prev, arginfo_sqlite_method_prev, 0)
++	PHP_ME_MAPPING(hasPrev, sqlite_has_prev, arginfo_sqlite_method_has_prev, 0)
++	PHP_ME_MAPPING(numRows, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
++	PHP_ME_MAPPING(seek, sqlite_seek, arginfo_sqlite_method_seek, 0)
++	{NULL, NULL, NULL}
++};
++
++const zend_function_entry sqlite_funcs_ub_query[] = {
++	PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
++	PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
++	PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
++	PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
++	PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
++	PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
++	PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
++	/* iterator */
++	PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
++	PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
++	PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
+ 	{NULL, NULL, NULL}
+ };
+ 
++const zend_function_entry sqlite_funcs_exception[] = {
++	{NULL, NULL, NULL}
++};
++
++/* Dependancies */
++static const zend_module_dep sqlite_deps[] = {
++#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
++	ZEND_MOD_REQUIRED("spl")
++#endif
++#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
++	ZEND_MOD_REQUIRED("session")
++#endif
++#ifdef PHP_SQLITE2_HAVE_PDO
++	ZEND_MOD_REQUIRED("pdo")
++#endif
++	{NULL, NULL, NULL}
++};
+ 
+ zend_module_entry sqlite_module_entry = {
+-#if ZEND_MODULE_API_NO >= 20010901
++#if ZEND_MODULE_API_NO >= 20050922
++	STANDARD_MODULE_HEADER_EX, NULL,
++	sqlite_deps,
++#elif ZEND_MODULE_API_NO >= 20010901
+ 	STANDARD_MODULE_HEADER,
+ #endif
+-	"sqlite",
++	"SQLite",
+ 	sqlite_functions,
+ 	PHP_MINIT(sqlite),
+-	NULL,
++	PHP_MSHUTDOWN(sqlite),
+ 	NULL,
+ 	PHP_RSHUTDOWN(sqlite),
+ 	PHP_MINFO(sqlite),
+ #if ZEND_MODULE_API_NO >= 20010901
+ 	PHP_SQLITE_MODULE_VERSION,
+ #endif
++#if ZEND_MODULE_API_NO >= 20060613
++	PHP_MODULE_GLOBALS(sqlite),
++	PHP_GINIT(sqlite),
++	NULL,
++	NULL,
++	STANDARD_MODULE_PROPERTIES_EX
++#else
+ 	STANDARD_MODULE_PROPERTIES
++#endif
+ };
+ 
+ 
+@@ -218,11 +676,11 @@
+ {
+ 	if (rsrc->ptr) {
+ 		struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
+-	
++
+ 		sqlite_close(db->db);
+ 
+ 		zend_hash_destroy(&db->callbacks);
+-		
++
+ 		pefree(db, db->is_persistent);
+ 
+ 		rsrc->ptr = NULL;
+@@ -264,6 +722,17 @@
+ 	efree(res);
+ }
+ 
++static int _clean_unfinished_results(zend_rsrc_list_entry *le, void *db TSRMLS_DC)
++{
++	if (Z_TYPE_P(le) == le_sqlite_result) {
++		struct php_sqlite_result *res = (struct php_sqlite_result *)le->ptr;
++		if (res->db->rsrc_id == ((struct php_sqlite_db*)db)->rsrc_id) {
++			return ZEND_HASH_APPLY_REMOVE;
++		}
++	}
++	return ZEND_HASH_APPLY_KEEP;
++}
++
+ static ZEND_RSRC_DTOR_FUNC(php_sqlite_result_dtor)
+ {
+ 	struct php_sqlite_result *res = (struct php_sqlite_result *)rsrc->ptr;
+@@ -280,12 +749,12 @@
+ 
+ 	/* prevent bad mojo if someone tries to use a previously registered function in the next request */
+ 	zend_hash_apply(&db->callbacks, (apply_func_t)php_sqlite_callback_invalidator TSRMLS_CC);
+-	
++
+ 	db->rsrc_id = FAILURE;
+ 
+ 	/* don't leave pending commits hanging around */
+ 	sqlite_exec(db->db, "ROLLBACK", NULL, NULL, NULL);
+-	
++
+ 	return 0;
+ }
+ 
+@@ -310,21 +779,21 @@
+ 		sqlite_set_result_error(func, "not enough parameters", -1);
+ 		return;
+ 	}
+-	
+-	ZVAL_STRING(&funcname, (char*)argv[0], 0);
+ 
+-	if (!zend_is_callable(&funcname, 0, &callable)) {
+-		spprintf(&errbuf, 0, "function `%s' is not callable", callable);
++	ZVAL_STRING(&funcname, (char*)argv[0], 1);
++
++	if (!zend_make_callable(&funcname, &callable TSRMLS_CC)) {
++		spprintf(&errbuf, 0, "function `%s' is not a function name", callable);
+ 		sqlite_set_result_error(func, errbuf, -1);
+ 		efree(errbuf);
+ 		efree(callable);
++		zval_dtor(&funcname);
+ 		return;
+ 	}
+-	efree(callable);
+-	
++
+ 	if (argc > 1) {
+ 		zargs = (zval ***)safe_emalloc((argc - 1), sizeof(zval **), 0);
+-		
++
+ 		for (i = 0; i < argc-1; i++) {
+ 			zargs[i] = emalloc(sizeof(zval *));
+ 			MAKE_STD_ZVAL(*zargs[i]);
+@@ -340,6 +809,8 @@
+ 			zargs,
+ 			0, NULL TSRMLS_CC);
+ 
++	zval_dtor(&funcname);
++
+ 	if (res == SUCCESS) {
+ 		if (retval == NULL) {
+ 			sqlite_set_result_string(func, NULL, 0);
+@@ -361,9 +832,14 @@
+ 			}
+ 		}
+ 	} else {
+-		sqlite_set_result_error(func, "call_user_function_ex failed", -1);
++		char *errbuf;
++		spprintf(&errbuf, 0, "call_user_function_ex failed for function %s()", callable);
++		sqlite_set_result_error(func, errbuf, -1);
++		efree(errbuf);
+ 	}
+ 
++	efree(callable);
++
+ 	if (retval) {
+ 		zval_ptr_dtor(&retval);
+ 	}
+@@ -394,7 +870,7 @@
+ 
+ 	if (argc > 0) {
+ 		zargs = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
+-		
++
+ 		for (i = 0; i < argc; i++) {
+ 			zargs[i] = emalloc(sizeof(zval *));
+ 			MAKE_STD_ZVAL(*zargs[i]);
+@@ -473,16 +949,16 @@
+ 	if (argc < 1) {
+ 		return;
+ 	}
+-	
++
+ 	zargc = argc + 1;
+ 	zargs = (zval ***)safe_emalloc(zargc, sizeof(zval **), 0);
+-		
++
+ 	/* first arg is always the context zval */
+ 	context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
+ 
+ 	if (*context_p == NULL) {
+ 		MAKE_STD_ZVAL(*context_p);
+-		(*context_p)->is_ref = 1;
++		Z_SET_ISREF_PP(context_p);
+ 		Z_TYPE_PP(context_p) = IS_NULL;
+ 	}
+ 
+@@ -538,9 +1014,9 @@
+ 		sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
+ 		return;
+ 	}
+-	
++
+ 	context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
+-	
++
+ 	res = call_user_function_ex(EG(function_table),
+ 			NULL,
+ 			funcs->fini,
+@@ -590,9 +1066,6 @@
+ 		case SQLITE_COPY:
+ 			if (strncmp(arg4, ":memory:", sizeof(":memory:") - 1)) {
+ 				TSRMLS_FETCH();
+-				if (PG(safe_mode) && (!php_checkuid(arg4, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
+-					return SQLITE_DENY;
+-				}
+ 
+ 				if (php_check_open_basedir(arg4 TSRMLS_CC)) {
+ 					return SQLITE_DENY;
+@@ -603,9 +1076,6 @@
+ 		case SQLITE_ATTACH:
+ 			if (strncmp(arg3, ":memory:", sizeof(":memory:") - 1)) {
+ 				TSRMLS_FETCH();
+-				if (PG(safe_mode) && (!php_checkuid(arg3, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
+-					return SQLITE_DENY;
+-				}
+ 
+ 				if (php_check_open_basedir(arg3 TSRMLS_CC)) {
+ 					return SQLITE_DENY;
+@@ -621,18 +1091,303 @@
+ }
+ /* }}} */
+ 
+-static int init_sqlite_globals(zend_sqlite_globals *g)
++/* {{{ OO init/structure stuff */
++#define REGISTER_SQLITE_CLASS(name, c_name, parent) \
++	{ \
++		zend_class_entry ce; \
++		INIT_CLASS_ENTRY(ce, "SQLite" # name, sqlite_funcs_ ## c_name); \
++		ce.create_object = sqlite_object_new_ ## c_name; \
++		sqlite_ce_ ## c_name = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
++		memcpy(&sqlite_object_handlers_ ## c_name, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
++		sqlite_object_handlers_ ## c_name.clone_obj = NULL; \
++		sqlite_ce_ ## c_name->ce_flags |= ZEND_ACC_FINAL_CLASS; \
++	}
++
++zend_class_entry *sqlite_ce_db, *sqlite_ce_exception;
++zend_class_entry *sqlite_ce_query, *sqlite_ce_ub_query;
++
++static zend_object_handlers sqlite_object_handlers_db;
++static zend_object_handlers sqlite_object_handlers_query;
++static zend_object_handlers sqlite_object_handlers_ub_query;
++static zend_object_handlers sqlite_object_handlers_exception;
++
++typedef enum {
++	is_db,
++	is_result
++} sqlite_obj_type;
++
++typedef struct _sqlite_object {
++	zend_object       std;
++	sqlite_obj_type   type;
++	union {
++		struct php_sqlite_db     *db;
++		struct php_sqlite_result *res;
++		void *ptr;
++	} u;
++} sqlite_object;
++
++static int sqlite_free_persistent(zend_rsrc_list_entry *le, void *ptr TSRMLS_DC)
+ {
+-	g->assoc_case = 0;
+-	return SUCCESS;
++	return le->ptr == ptr ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_KEEP;
+ }
+ 
+-PHP_MINIT_FUNCTION(sqlite)
++static void sqlite_object_free_storage(void *object TSRMLS_DC)
+ {
+-	ZEND_INIT_MODULE_GLOBALS(sqlite, init_sqlite_globals, NULL);
++	sqlite_object *intern = (sqlite_object *)object;
++
++	zend_object_std_dtor(&intern->std TSRMLS_CC);
++
++	if (intern->u.ptr) {
++		if (intern->type == is_db) {
++			if (intern->u.db->rsrc_id) {
++				zend_list_delete(intern->u.db->rsrc_id);
++				zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) sqlite_free_persistent, &intern->u.ptr TSRMLS_CC);
++			}
++		} else {
++			real_result_dtor(intern->u.res TSRMLS_CC);
++		}
++	}
++
++	efree(object);
++}
++
++static void sqlite_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC)
++{
++	sqlite_object *intern;
++
++	intern = emalloc(sizeof(sqlite_object));
++	memset(intern, 0, sizeof(sqlite_object));
++
++	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
++	object_properties_init(&intern->std, class_type);
+ 	
++	retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) sqlite_object_free_storage, NULL TSRMLS_CC);
++	retval->handlers = handlers;
++}
++
++static zend_object_value sqlite_object_new_db(zend_class_entry *class_type TSRMLS_DC)
++{
++	zend_object_value retval;
++
++	sqlite_object_new(class_type, &sqlite_object_handlers_db, &retval TSRMLS_CC);
++	return retval;
++}
++
++static zend_object_value sqlite_object_new_query(zend_class_entry *class_type TSRMLS_DC)
++{
++	zend_object_value retval;
++
++	sqlite_object_new(class_type, &sqlite_object_handlers_query, &retval TSRMLS_CC);
++	return retval;
++}
++
++static zend_object_value sqlite_object_new_ub_query(zend_class_entry *class_type TSRMLS_DC)
++{
++	zend_object_value retval;
++
++	sqlite_object_new(class_type, &sqlite_object_handlers_ub_query, &retval TSRMLS_CC);
++	return retval;
++}
++
++static zend_object_value sqlite_object_new_exception(zend_class_entry *class_type TSRMLS_DC)
++{
++	zend_object_value retval;
++
++	sqlite_object_new(class_type, &sqlite_object_handlers_exception, &retval TSRMLS_CC);
++	return retval;
++}
++
++#define SQLITE_REGISTER_OBJECT(_type, _object, _ptr) \
++	{ \
++		sqlite_object *obj; \
++		obj = (sqlite_object*)zend_object_store_get_object(_object TSRMLS_CC); \
++		obj->type = is_ ## _type; \
++		obj->u._type = _ptr; \
++	}
++
++static zend_class_entry *sqlite_get_ce_query(const zval *object TSRMLS_DC)
++{
++	return sqlite_ce_query;
++}
++
++static zend_class_entry *sqlite_get_ce_ub_query(const zval *object TSRMLS_DC)
++{
++	return sqlite_ce_ub_query;
++}
++
++static zval * sqlite_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
++{
++	if (!object) {
++		ALLOC_ZVAL(object);
++	}
++	Z_TYPE_P(object) = IS_OBJECT;
++	object_init_ex(object, pce);
++	Z_SET_REFCOUNT_P(object, 1);
++	Z_SET_ISREF_P(object);
++	return object;
++}
++
++typedef struct _sqlite_object_iterator {
++	zend_object_iterator     it;
++	struct php_sqlite_result *res;
++	zval *value;
++} sqlite_object_iterator;
++
++void sqlite_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
++{
++	zval *object = (zval*)((sqlite_object_iterator*)iter)->it.data;
++
++	if (((sqlite_object_iterator*)iter)->value) {
++		zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
++		((sqlite_object_iterator*)iter)->value = NULL;
++	}
++	zval_ptr_dtor(&object);
++	efree(iter);
++}
++
++void sqlite_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
++{
++	struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
++
++	if (((sqlite_object_iterator*)iter)->value) {
++		zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
++		((sqlite_object_iterator*)iter)->value = NULL;
++	}
++	if (res) {
++		res->curr_row = 0;
++	}
++}
++
++int sqlite_iterator_valid(zend_object_iterator *iter TSRMLS_DC)
++{
++	struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
++
++	if (res && res->curr_row < res->nrows && res->nrows) { /* curr_row may be -1 */
++		return SUCCESS;
++	} else {
++		return FAILURE;
++	}
++}
++
++void sqlite_iterator_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
++{
++	struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
++
++	*data = &((sqlite_object_iterator*)iter)->value;
++	if (res && !**data) {
++		MAKE_STD_ZVAL(**data);
++		php_sqlite_fetch_array(res, res->mode, 1, 0, **data TSRMLS_CC);
++	}
++
++}
++
++int sqlite_iterator_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
++{
++	struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
++
++	*str_key = NULL;
++	*str_key_len = 0;
++	*int_key = res ? res->curr_row : 0;
++	return HASH_KEY_IS_LONG;
++}
++
++void sqlite_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
++{
++	struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
++
++	if (((sqlite_object_iterator*)iter)->value) {
++		zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
++		((sqlite_object_iterator*)iter)->value = NULL;
++	}
++	if (res) {
++		if (!res->buffered && res->vm) {
++			php_sqlite_fetch(res TSRMLS_CC);
++		}
++		if (res->curr_row >= res->nrows) {
++			/* php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available"); */
++			return;
++		}
++
++		res->curr_row++;
++	}
++}
++
++zend_object_iterator_funcs sqlite_ub_query_iterator_funcs = {
++	sqlite_iterator_dtor,
++	sqlite_iterator_valid,
++	sqlite_iterator_get_current_data,
++	sqlite_iterator_get_current_key,
++	sqlite_iterator_move_forward,
++	NULL
++};
++
++zend_object_iterator_funcs sqlite_query_iterator_funcs = {
++	sqlite_iterator_dtor,
++	sqlite_iterator_valid,
++	sqlite_iterator_get_current_data,
++	sqlite_iterator_get_current_key,
++	sqlite_iterator_move_forward,
++	sqlite_iterator_rewind
++};
++
++zend_object_iterator *sqlite_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
++{
++	sqlite_object_iterator *iterator = emalloc(sizeof(sqlite_object_iterator));
++
++	sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
++
++	if (by_ref) {
++		zend_error(E_RECOVERABLE_ERROR, "An iterator cannot be used with foreach by reference");
++	}
++	Z_ADDREF_P(object);
++	iterator->it.data = (void*)object;
++	iterator->it.funcs = ce->iterator_funcs.funcs;
++	iterator->res = obj->u.res;
++	iterator->value = NULL;
++	return (zend_object_iterator*)iterator;
++}
++/* }}} */
++
++static PHP_GINIT_FUNCTION(sqlite)
++{
++	sqlite_globals->assoc_case = 0;
++}
++
++PHP_MINIT_FUNCTION(sqlite)
++{
++	REGISTER_SQLITE_CLASS(Database,   db,        NULL);
++	REGISTER_SQLITE_CLASS(Result,     query,     NULL);
++	REGISTER_SQLITE_CLASS(Unbuffered, ub_query,  NULL);
++#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
++	REGISTER_SQLITE_CLASS(Exception,  exception, spl_ce_RuntimeException);
++#else
++	REGISTER_SQLITE_CLASS(Exception,  exception, zend_exception_get_default(TSRMLS_C));
++#endif
++
++	sqlite_ce_db->ce_flags &= ~ZEND_ACC_FINAL_CLASS;
++	sqlite_ce_db->constructor->common.fn_flags |= ZEND_ACC_FINAL;
++
++	sqlite_object_handlers_query.get_class_entry = sqlite_get_ce_query;
++	sqlite_object_handlers_ub_query.get_class_entry = sqlite_get_ce_ub_query;
++	sqlite_object_handlers_ub_query.count_elements = sqlite_count_elements;
++
++	sqlite_ce_ub_query->get_iterator = sqlite_get_iterator;
++	sqlite_ce_ub_query->iterator_funcs.funcs = &sqlite_ub_query_iterator_funcs;
++
++#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
++	zend_class_implements(sqlite_ce_query TSRMLS_CC, 2, zend_ce_iterator, spl_ce_Countable);
++#else
++	zend_class_implements(sqlite_ce_query TSRMLS_CC, 1, zend_ce_iterator);
++#endif
++	sqlite_ce_query->get_iterator = sqlite_get_iterator;
++	sqlite_ce_query->iterator_funcs.funcs = &sqlite_query_iterator_funcs;
++
+ 	REGISTER_INI_ENTRIES();
+ 
++#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
++	php_session_register_module(ps_sqlite_ptr);
++#endif
++
+ 	le_sqlite_db = zend_register_list_destructors_ex(php_sqlite_db_dtor, NULL, "sqlite database", module_number);
+ 	le_sqlite_pdb = zend_register_list_destructors_ex(NULL, php_sqlite_db_dtor, "sqlite database (persistent)", module_number);
+ 	le_sqlite_result = zend_register_list_destructors_ex(php_sqlite_result_dtor, NULL, "sqlite result", module_number);
+@@ -640,7 +1395,7 @@
+ 	REGISTER_LONG_CONSTANT("SQLITE_BOTH",	PHPSQLITE_BOTH, CONST_CS|CONST_PERSISTENT);
+ 	REGISTER_LONG_CONSTANT("SQLITE_NUM",	PHPSQLITE_NUM, CONST_CS|CONST_PERSISTENT);
+ 	REGISTER_LONG_CONSTANT("SQLITE_ASSOC",	PHPSQLITE_ASSOC, CONST_CS|CONST_PERSISTENT);
+-	
++
+ 	REGISTER_LONG_CONSTANT("SQLITE_OK",				SQLITE_OK, CONST_CS|CONST_PERSISTENT);
+ 	REGISTER_LONG_CONSTANT("SQLITE_ERROR",			SQLITE_ERROR, CONST_CS|CONST_PERSISTENT);
+ 	REGISTER_LONG_CONSTANT("SQLITE_INTERNAL",		SQLITE_INTERNAL, CONST_CS|CONST_PERSISTENT);
+@@ -665,18 +1420,30 @@
+ 	REGISTER_LONG_CONSTANT("SQLITE_MISUSE",			SQLITE_MISUSE, CONST_CS|CONST_PERSISTENT);
+ 	REGISTER_LONG_CONSTANT("SQLITE_NOLFS",			SQLITE_NOLFS, CONST_CS|CONST_PERSISTENT);
+ 	REGISTER_LONG_CONSTANT("SQLITE_AUTH",			SQLITE_AUTH, CONST_CS|CONST_PERSISTENT);
++	REGISTER_LONG_CONSTANT("SQLITE_NOTADB",			SQLITE_NOTADB, CONST_CS|CONST_PERSISTENT);
+ #ifdef SQLITE_FORMAT
+ 	REGISTER_LONG_CONSTANT("SQLITE_FORMAT",			SQLITE_FORMAT, CONST_CS|CONST_PERSISTENT);
+ #endif
+-#ifdef SQLITE_RANGE
+-	REGISTER_LONG_CONSTANT("SQLITE_RANGE",			SQLITE_RANGE, CONST_CS|CONST_PERSISTENT);
+-#endif
+-#ifdef SQLITE_NOTADB
+-	REGISTER_LONG_CONSTANT("SQLITE_NOTADB",			SQLITE_NOTADB, CONST_CS|CONST_PERSISTENT);
+-#endif
+ 	REGISTER_LONG_CONSTANT("SQLITE_ROW",			SQLITE_ROW, CONST_CS|CONST_PERSISTENT);
+ 	REGISTER_LONG_CONSTANT("SQLITE_DONE",			SQLITE_DONE, CONST_CS|CONST_PERSISTENT);
+ 
++#ifdef PHP_SQLITE2_HAVE_PDO
++    if (FAILURE == php_pdo_register_driver(&pdo_sqlite2_driver)) {
++	return FAILURE;
++    }
++#endif
++
++	return SUCCESS;
++}
++
++PHP_MSHUTDOWN_FUNCTION(sqlite)
++{
++	UNREGISTER_INI_ENTRIES();
++
++#ifdef PHP_SQLITE2_HAVE_PDO
++    php_pdo_unregister_driver(&pdo_sqlite2_driver);
++#endif
++
+ 	return SUCCESS;
+ }
+ 
+@@ -684,7 +1451,7 @@
+ {
+ 	php_info_print_table_start();
+ 	php_info_print_table_header(2, "SQLite support", "enabled");
+-	php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c,v 1.62.2.25 2004/07/10 12:25:33 wez Exp $");
++	php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c 299692 2010-05-24 14:11:39Z dmitry $");
+ 	php_info_print_table_row(2, "SQLite Library", sqlite_libversion());
+ 	php_info_print_table_row(2, "SQLite Encoding", sqlite_libencoding());
+ 	php_info_print_table_end();
+@@ -692,7 +1459,7 @@
+ 	DISPLAY_INI_ENTRIES();
+ }
+ 
+-static struct php_sqlite_db *php_sqlite_open(char *filename, int mode, char *persistent_id, zval *return_value, zval *errmsg TSRMLS_DC)
++static struct php_sqlite_db *php_sqlite_open(char *filename, int mode, char *persistent_id, zval *return_value, zval *errmsg, zval *object TSRMLS_DC)
+ {
+ 	char *errtext = NULL;
+ 	sqlite *sdb = NULL;
+@@ -710,7 +1477,12 @@
+ 
+ 		sqlite_freemem(errtext);
+ 
+-		RETVAL_FALSE;
++		/* if object is not an object then we're called from the factory() function */
++		if (object && Z_TYPE_P(object) != IS_OBJECT) {
++			RETVAL_NULL();
++		} else {
++			RETVAL_FALSE;
++		}
+ 		return NULL;
+ 	}
+ 
+@@ -720,7 +1492,7 @@
+ 	db->db = sdb;
+ 
+ 	zend_hash_init(&db->callbacks, 0, NULL, php_sqlite_callback_dtor, db->is_persistent);
+-	
++
+ 	/* register the PHP functions */
+ 	sqlite_create_function(sdb, "php", -1, php_sqlite_generic_function_callback, 0);
+ 
+@@ -731,12 +1503,22 @@
+ 	/* authorizer hook so we can enforce safe mode
+ 	 * Note: the declaration of php_sqlite_authorizer is correct for 2.8.2 of libsqlite,
+ 	 * and IS backwards binary compatible with earlier versions */
+-	sqlite_set_authorizer(sdb, php_sqlite_authorizer, NULL);
+-	
+-	db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, persistent_id ? le_sqlite_pdb : le_sqlite_db);
++	if (PG(open_basedir) && *PG(open_basedir)) {
++		sqlite_set_authorizer(sdb, php_sqlite_authorizer, NULL);
++	}
++
++	db->rsrc_id = ZEND_REGISTER_RESOURCE(object ? NULL : return_value, db, persistent_id ? le_sqlite_pdb : le_sqlite_db);
++	if (object) {
++		/* if object is not an object then we're called from the factory() function */
++		if (Z_TYPE_P(object) != IS_OBJECT) {
++			sqlite_instanciate(sqlite_ce_db, object TSRMLS_CC);
++		}
++		/* and now register the object */
++		SQLITE_REGISTER_OBJECT(db, object, db)
++	}
+ 
+ 	if (persistent_id) {
+-		list_entry le;
++		zend_rsrc_list_entry le;
+ 
+ 		Z_TYPE(le) = le_sqlite_pdb;
+ 		le.ptr = db;
+@@ -747,51 +1529,51 @@
+ 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent resource");
+ 		}
+ 	}
+-	
++
+ 	return db;
+ }
+ 
+-/* {{{ proto resource sqlite_popen(string filename [, int mode, string &errmessage])
+-   Opens a persistent handle to an SQLite database.  Will create the database if it does not exist */
++/* {{{ proto resource sqlite_popen(string filename [, int mode [, string &error_message]])
++   Opens a persistent handle to a SQLite database. Will create the database if it does not exist. */
+ PHP_FUNCTION(sqlite_popen)
+ {
+-	int mode = 0666;
++	long mode = 0666;
+ 	char *filename, *fullpath, *hashkey;
+-	long filename_len, hashkeylen;
++	int filename_len, hashkeylen;
+ 	zval *errmsg = NULL;
+ 	struct php_sqlite_db *db = NULL;
+-	list_entry *le;
+-	
++	zend_rsrc_list_entry *le;
++
+ 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
+ 				&filename, &filename_len, &mode, &errmsg)) {
+ 		return;
+ 	}
+ 	if (errmsg) {
+ 		zval_dtor(errmsg);
++		ZVAL_NULL(errmsg);
+ 	}
+ 
+ 	if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
+ 		/* resolve the fully-qualified path name to use as the hash key */
+-		fullpath = expand_filepath(filename, NULL TSRMLS_CC);
+-	
+-		if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
++		if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
+ 			RETURN_FALSE;
+ 		}
+ 
+ 		if (php_check_open_basedir(fullpath TSRMLS_CC)) {
++			efree(fullpath);
+ 			RETURN_FALSE;
+ 		}
+ 	} else {
+ 		fullpath = estrndup(filename, filename_len);
+ 	}
+ 
+-	hashkeylen = spprintf(&hashkey, 0, "sqlite_pdb_%s:%d", fullpath, mode);
+-	
++	hashkeylen = spprintf(&hashkey, 0, "sqlite_pdb_%s:%ld", fullpath, mode);
++
+ 	/* do we have an existing persistent connection ? */
+ 	if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, hashkeylen+1, (void*)&le)) {
+ 		if (Z_TYPE_P(le) == le_sqlite_pdb) {
+ 			db = (struct php_sqlite_db*)le->ptr;
+-			
++
+ 			if (db->rsrc_id == FAILURE) {
+ 				/* give it a valid resource id for this request */
+ 				db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
+@@ -799,7 +1581,7 @@
+ 				int type;
+ 				/* sanity check to ensure that the resource is still a valid regular resource
+ 				 * number */
+-				if (_zend_list_find(db->rsrc_id, &type TSRMLS_CC) == db) {
++				if (zend_list_find(db->rsrc_id, &type) == db) {
+ 					/* already accessed this request; map it */
+ 					zend_list_addref(db->rsrc_id);
+ 					ZVAL_RESOURCE(return_value, db->rsrc_id);
+@@ -809,109 +1591,174 @@
+ 			}
+ 
+ 			/* all set */
+-			efree(fullpath);
+-			efree(hashkey);
+-			return;
++			goto done;
+ 		}
+ 
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Some other type of persistent resource is using this hash key!?");
+-		RETURN_FALSE;
++		RETVAL_FALSE;
++		goto done;
+ 	}
+ 
+ 	/* now we need to open the database */
+-	php_sqlite_open(fullpath, mode, hashkey, return_value, errmsg TSRMLS_CC);
+-
++	php_sqlite_open(fullpath, (int)mode, hashkey, return_value, errmsg, NULL TSRMLS_CC);
++done:
+ 	efree(fullpath);
+ 	efree(hashkey);
+ }
+ /* }}} */
+ 
+-/* {{{ proto resource sqlite_open(string filename [, int mode, string &errmessage])
+-   Opens an SQLite database.  Will create the database if it does not exist */
++/* {{{ proto resource sqlite_open(string filename [, int mode [, string &error_message]])
++   Opens a SQLite database. Will create the database if it does not exist. */
+ PHP_FUNCTION(sqlite_open)
+ {
+-	int mode = 0666;
++	long mode = 0666;
+ 	char *filename, *fullpath = NULL;
+-	long filename_len;
++	int filename_len;
+ 	zval *errmsg = NULL;
++	zval *object = getThis();
++	zend_error_handling error_handling;
+ 
++	zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
+ 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
+ 				&filename, &filename_len, &mode, &errmsg)) {
++		zend_restore_error_handling(&error_handling TSRMLS_CC);
+ 		return;
+ 	}
+ 	if (errmsg) {
+ 		zval_dtor(errmsg);
++		ZVAL_NULL(errmsg);
+ 	}
+ 
+ 	if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
+ 		/* resolve the fully-qualified path name to use as the hash key */
+-		fullpath = expand_filepath(filename, NULL TSRMLS_CC);
+-	
+-		if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
++		if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
++			zend_restore_error_handling(&error_handling TSRMLS_CC);
++			if (object) {
++				RETURN_NULL();
++			} else {
++				RETURN_FALSE;
++			}
++		}
++
++		if (php_check_open_basedir(fullpath TSRMLS_CC)) {
+ 			efree(fullpath);
+-			RETURN_FALSE;
++			zend_restore_error_handling(&error_handling TSRMLS_CC);
++			if (object) {
++				RETURN_NULL();
++			} else {
++				RETURN_FALSE;
++			}
++		}
++	}
++
++	php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, object TSRMLS_CC);
++
++	if (fullpath) {
++		efree(fullpath);
++	}
++	zend_restore_error_handling(&error_handling TSRMLS_CC);
++}
++/* }}} */
++
++/* {{{ proto object sqlite_factory(string filename [, int mode [, string &error_message]])
++   Opens a SQLite database and creates an object for it. Will create the database if it does not exist. */
++PHP_FUNCTION(sqlite_factory)
++{
++	long mode = 0666;
++	char *filename, *fullpath = NULL;
++	int filename_len;
++	zval *errmsg = NULL;
++	zend_error_handling error_handling;
++
++	zend_replace_error_handling(EH_THROW, sqlite_ce_exception, &error_handling TSRMLS_CC);
++	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
++				&filename, &filename_len, &mode, &errmsg)) {
++		zend_restore_error_handling(&error_handling TSRMLS_CC);
++		RETURN_NULL();
++	}
++	if (errmsg) {
++		zval_dtor(errmsg);
++		ZVAL_NULL(errmsg);
++	}
++
++	if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
++		/* resolve the fully-qualified path name to use as the hash key */
++		if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
++			zend_restore_error_handling(&error_handling TSRMLS_CC);
++			RETURN_NULL();
+ 		}
+ 
+ 		if (php_check_open_basedir(fullpath TSRMLS_CC)) {
+ 			efree(fullpath);
+-			RETURN_FALSE;
++			zend_restore_error_handling(&error_handling TSRMLS_CC);
++			RETURN_NULL();
+ 		}
+ 	}
+-	
+-	php_sqlite_open(fullpath ? fullpath : filename, mode, NULL, return_value, errmsg TSRMLS_CC);
+ 
++	php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, return_value TSRMLS_CC);
+ 	if (fullpath) {
+ 		efree(fullpath);
+ 	}
++	zend_restore_error_handling(&error_handling TSRMLS_CC);
+ }
+ /* }}} */
+ 
+ /* {{{ proto void sqlite_busy_timeout(resource db, int ms)
+-   Set busy timeout duration. If ms <= 0, all busy handlers are disabled */
++   Set busy timeout duration. If ms <= 0, all busy handlers are disabled. */
+ PHP_FUNCTION(sqlite_busy_timeout)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
+ 	long ms;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zdb, &ms)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ms)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zdb, &ms)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+ 
+-	DB_FROM_ZVAL(db, &zdb);
+-
+ 	sqlite_busy_timeout(db->db, ms);
+ }
+ /* }}} */
+ 
+ /* {{{ proto void sqlite_close(resource db)
+-   Closes an open sqlite database */
++   Closes an open sqlite database. */
+ PHP_FUNCTION(sqlite_close)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
+-		return;
+-	}
+-	DB_FROM_ZVAL(db, &zdb);
+-
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
+-		return;
++	if (object) {
++		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Ignored, you must destruct the object instead");
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+ 
+-	DB_FROM_ZVAL(db, &zdb);
++	zend_hash_apply_with_argument(&EG(regular_list),
++		(apply_func_arg_t) _clean_unfinished_results,
++		db TSRMLS_CC);
+ 
+ 	zend_list_delete(Z_RESVAL_P(zdb));
+ }
+ /* }}} */
+ 
+ /* {{{ php_sqlite_fetch */
+-int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC)
++static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC)
+ {
+ 	const char **rowdata, **colnames;
+ 	int ret, i, base;
+-	char *errtext = NULL, *colname;
++	char *errtext = NULL;
+ 
+ next_row:
+ 	ret = sqlite_step(rres->vm, &rres->ncolumns, &rowdata, &colnames);
+@@ -919,14 +1766,13 @@
+ 		/* first row - lets copy the column names */
+ 		rres->col_names = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
+ 		for (i = 0; i < rres->ncolumns; i++) {
+-			colname = (char*)colnames[i];
++			rres->col_names[i] = estrdup((char*)colnames[i]);
+ 
+ 			if (SQLITE_G(assoc_case) == 1) {
+-				php_sqlite_strtoupper(colname);
++				php_sqlite_strtoupper(rres->col_names[i]);
+ 			} else if (SQLITE_G(assoc_case) == 2) {
+-				php_sqlite_strtolower(colname);
++				php_sqlite_strtolower(rres->col_names[i]);
+ 			}
+-			rres->col_names[i] = estrdup(colname);
+ 		}
+ 		if (!rres->buffered) {
+ 			/* non buffered mode - also fetch memory for on single row */
+@@ -940,7 +1786,7 @@
+ 				/* add the row to our collection */
+ 				if (rres->nrows + 1 >= rres->alloc_rows) {
+ 					rres->alloc_rows = rres->alloc_rows ? rres->alloc_rows * 2 : 16;
+-					rres->table = erealloc(rres->table, rres->alloc_rows * rres->ncolumns * sizeof(char *));
++					rres->table = safe_erealloc(rres->table, rres->alloc_rows, rres->ncolumns*sizeof(char *), 0);
+ 				}
+ 				base = rres->nrows * rres->ncolumns;
+ 				for (i = 0; i < rres->ncolumns; i++) {
+@@ -994,9 +1840,9 @@
+ /* }}} */
+ 
+ /* {{{ sqlite_query */
+-void sqlite_query(struct php_sqlite_db *db, char *sql, long sql_len, int mode, int buffered, zval *return_value, struct php_sqlite_result *rres TSRMLS_DC)
++void sqlite_query(zval *object, struct php_sqlite_db *db, char *sql, long sql_len, int mode, int buffered, zval *return_value, struct php_sqlite_result **prres, zval *errmsg TSRMLS_DC)
+ {
+-	struct php_sqlite_result res;
++	struct php_sqlite_result res, *rres;
+ 	int ret;
+ 	char *errtext = NULL;
+ 	const char *tail;
+@@ -1010,61 +1856,92 @@
+ 
+ 	if (ret != SQLITE_OK) {
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
++		if (errmsg) {
++			ZVAL_STRING(errmsg, errtext, 1);
++		}
+ 		sqlite_freemem(errtext);
+ 		goto terminate;
+-	} else if (!res.vm) { /* emptry query */
++	} else if (!res.vm) { /* empty query */
+ terminate:
+ 		if (return_value) {
+ 			RETURN_FALSE;
+ 		} else {
+-			efree(rres);
+ 			return;
+ 		}
+ 	}
+ 
+-	if (!rres) {
+-		rres = (struct php_sqlite_result*)emalloc(sizeof(*rres));
++	if (!prres) {
++		rres = NULL;
++		prres = &rres;
+ 	}
+-	memcpy(rres, &res, sizeof(*rres));
+-	rres->db = db;
++	if (!*prres) {
++		*prres = (struct php_sqlite_result*)emalloc(sizeof(**prres));
++	}
++	memcpy(*prres, &res, sizeof(**prres));
++	(*prres)->db = db;
+ 	zend_list_addref(db->rsrc_id);
+ 
++
+ 	/* now the result set is ready for stepping: get first row */
+-	if (php_sqlite_fetch(rres TSRMLS_CC) != SQLITE_OK) {
+-		real_result_dtor(rres TSRMLS_CC);
++	if (php_sqlite_fetch((*prres) TSRMLS_CC) != SQLITE_OK) {
++		real_result_dtor((*prres) TSRMLS_CC);
++		*prres = NULL;
+ 		if (return_value) {
+ 			RETURN_FALSE;
+ 		} else {
+-			return;	
++			return;
+ 		}
+ 	}
+-	
+-	rres->curr_row = 0;
+ 
+-	if (return_value) {
+-		ZEND_REGISTER_RESOURCE(return_value, rres, le_sqlite_result);
++	(*prres)->curr_row = 0;
++
++	if (object) {
++		sqlite_object *obj;
++		if (buffered) {
++			sqlite_instanciate(sqlite_ce_query, return_value TSRMLS_CC);
++		} else {
++			sqlite_instanciate(sqlite_ce_ub_query, return_value TSRMLS_CC);
++		}
++		obj = (sqlite_object *) zend_object_store_get_object(return_value TSRMLS_CC);
++		obj->type = is_result;
++		obj->u.res = (*prres);
++	} else if (return_value) {
++		ZEND_REGISTER_RESOURCE(object ? NULL : return_value, (*prres), le_sqlite_result);
+ 	}
+ }
+ /* }}} */
+ 
+-/* {{{ proto resource sqlite_unbuffered_query(string query, resource db [ , int result_type ])
+-   Execute a query that does not prefetch and buffer all data */
++/* {{{ proto resource sqlite_unbuffered_query(string query, resource db [ , int result_type [, string &error_message]])
++   Executes a query that does not prefetch and buffer all data. */
+ PHP_FUNCTION(sqlite_unbuffered_query)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
+ 	char *sql;
+-	long sql_len;
+-	int mode = PHPSQLITE_BOTH;
++	int sql_len;
++	long mode = PHPSQLITE_BOTH;
+ 	char *errtext = NULL;
++	zval *errmsg = NULL;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
+-				ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &sql, &sql_len, &zdb, &mode) && 
+-			FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &sql, &sql_len, &mode)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
++				ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
++			FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+ 
+-	DB_FROM_ZVAL(db, &zdb);
++	if (errmsg) {
++		zval_dtor(errmsg);
++		ZVAL_NULL(errmsg);
++	}
+ 
+ 	PHP_SQLITE_EMPTY_QUERY;
+ 
+@@ -1074,32 +1951,124 @@
+ 
+ 		if (db->last_err_code != SQLITE_OK) {
+ 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
++			if (errmsg) {
++				ZVAL_STRING(errmsg, errtext, 1);
++			}
+ 			sqlite_freemem(errtext);
+ 		}
+ 		return;
+ 	}
+-	
+-	sqlite_query(db, sql, sql_len, mode, 0, return_value, NULL TSRMLS_CC);
++
++	sqlite_query(object, db, sql, sql_len, (int)mode, 0, return_value, NULL, errmsg TSRMLS_CC);
+ }
+ /* }}} */
+ 
+-/* {{{ proto resource sqlite_query(string query, resource db [ , int result_type ])
+-   Executes a query against a given database and returns a result handle */
++/* {{{ proto resource sqlite_fetch_column_types(string table_name, resource db [, int result_type])
++   Return an array of column types from a particular table. */
++PHP_FUNCTION(sqlite_fetch_column_types)
++{
++	zval *zdb;
++	struct php_sqlite_db *db;
++	char *tbl, *sql;
++	int tbl_len;
++	char *errtext = NULL;
++	zval *object = getThis();
++	struct php_sqlite_result res;
++	const char **rowdata, **colnames, *tail;
++	int i, ncols;
++	long result_type = PHPSQLITE_ASSOC;
++
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &tbl, &tbl_len, &result_type)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
++				ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &tbl, &tbl_len, &zdb, &result_type) &&
++			FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &tbl, &tbl_len, &result_type)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
++	}
++
++	if (!(sql = sqlite_mprintf("SELECT * FROM '%q' LIMIT 1", tbl))) {
++		RETURN_FALSE;
++	}
++
++	sqlite_exec(db->db, "PRAGMA show_datatypes = ON", NULL, NULL, NULL);
++
++	db->last_err_code = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
++
++	sqlite_freemem(sql);
++
++	if (db->last_err_code != SQLITE_OK) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
++		sqlite_freemem(errtext);
++		RETVAL_FALSE;
++		goto done;
++	}
++
++	sqlite_step(res.vm, &ncols, &rowdata, &colnames);
++
++	array_init(return_value);
++
++	for (i = 0; i < ncols; i++) {
++		if (result_type == PHPSQLITE_ASSOC) {
++			char *colname = estrdup((char *)colnames[i]);
++
++			if (SQLITE_G(assoc_case) == 1) {
++				php_sqlite_strtoupper(colname);
++			} else if (SQLITE_G(assoc_case) == 2) {
++				php_sqlite_strtolower(colname);
++			}
++
++			add_assoc_string(return_value, colname, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
++			efree(colname);
++		}
++		if (result_type == PHPSQLITE_NUM) {
++			add_index_string(return_value, i, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
++		}
++	}
++	if (res.vm) {
++		sqlite_finalize(res.vm, NULL);
++	}
++done:
++	sqlite_exec(db->db, "PRAGMA show_datatypes = OFF", NULL, NULL, NULL);
++}
++/* }}} */
++
++/* {{{ proto resource sqlite_query(string query, resource db [, int result_type [, string &error_message]])
++   Executes a query against a given database and returns a result handle. */
+ PHP_FUNCTION(sqlite_query)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
+ 	char *sql;
+-	long sql_len;
+-	int mode = PHPSQLITE_BOTH;
++	int sql_len;
++	long mode = PHPSQLITE_BOTH;
+ 	char *errtext = NULL;
++	zval *errmsg = NULL;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
+-			ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &sql, &sql_len, &zdb, &mode) && 
+-		FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &sql, &sql_len, &mode)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
++				ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
++			FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
++	}
++
++	if (errmsg) {
++		zval_dtor(errmsg);
++		ZVAL_NULL(errmsg);
+ 	}
+-	DB_FROM_ZVAL(db, &zdb);
+ 
+ 	PHP_SQLITE_EMPTY_QUERY;
+ 
+@@ -1109,31 +2078,48 @@
+ 
+ 		if (db->last_err_code != SQLITE_OK) {
+ 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
++			if (errmsg) {
++				ZVAL_STRING(errmsg, errtext, 1);
++			}
+ 			sqlite_freemem(errtext);
+ 		}
+ 		return;
+ 	}
+-	
+-	sqlite_query(db, sql, sql_len, mode, 1, return_value, NULL TSRMLS_CC);
++
++	sqlite_query(object, db, sql, sql_len, (int)mode, 1, return_value, NULL, errmsg TSRMLS_CC);
+ }
+ /* }}} */
+ 
+-/* {{{ proto boolean sqlite_exec(string query, resource db)
++/* {{{ proto boolean sqlite_exec(string query, resource db[, string &error_message])
+    Executes a result-less query against a given database */
+ PHP_FUNCTION(sqlite_exec)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
+ 	char *sql;
+-	long sql_len;
++	int sql_len;
+ 	char *errtext = NULL;
++	zval *errmsg = NULL;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
+-			ZEND_NUM_ARGS() TSRMLS_CC, "sr", &sql, &sql_len, &zdb) && 
+-		FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zdb, &sql, &sql_len)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &sql, &sql_len, &errmsg)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if(FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
++			ZEND_NUM_ARGS() TSRMLS_CC, "sr", &sql, &sql_len, &zdb) &&
++		   FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z/", &zdb, &sql, &sql_len, &errmsg)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
++	}
++
++	if (errmsg) {
++		zval_dtor(errmsg);
++		ZVAL_NULL(errmsg);
+ 	}
+-	DB_FROM_ZVAL(db, &zdb);
+ 
+ 	PHP_SQLITE_EMPTY_QUERY;
+ 
+@@ -1141,6 +2127,9 @@
+ 
+ 	if (db->last_err_code != SQLITE_OK) {
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
++		if (errmsg) {
++			ZVAL_STRING(errmsg, errtext, 1);
++		}
+ 		sqlite_freemem(errtext);
+ 		RETURN_FALSE;
+ 	}
+@@ -1152,9 +2141,9 @@
+ /* {{{ php_sqlite_fetch_array */
+ static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC)
+ {
+-	int j, buffered = res->buffered;
++	int j, n = res->ncolumns, buffered = res->buffered;
+ 	const char **rowdata, **colnames;
+-	
++
+ 	/* check range of the row */
+ 	if (res->curr_row >= res->nrows) {
+ 		/* no more */
+@@ -1170,7 +2159,7 @@
+ 	/* now populate the result */
+ 	array_init(return_value);
+ 
+-	for (j = 0; j < res->ncolumns; j++) {
++	for (j = 0; j < n; j++) {
+ 		zval *decoded;
+ 		MAKE_STD_ZVAL(decoded);
+ 
+@@ -1178,7 +2167,7 @@
+ 			ZVAL_NULL(decoded);
+ 		} else if (decode_binary && rowdata[j][0] == '\x01') {
+ 			Z_STRVAL_P(decoded) = emalloc(strlen(rowdata[j]));
+-			Z_STRLEN_P(decoded) = sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
++			Z_STRLEN_P(decoded) = php_sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
+ 			Z_STRVAL_P(decoded)[Z_STRLEN_P(decoded)] = '\0';
+ 			Z_TYPE_P(decoded) = IS_STRING;
+ 			if (!buffered) {
+@@ -1195,7 +2184,7 @@
+ 		if (mode & PHPSQLITE_NUM) {
+ 			if (mode & PHPSQLITE_ASSOC) {
+ 				add_index_zval(return_value, j, decoded);
+-				ZVAL_ADDREF(decoded);
++				Z_ADDREF_P(decoded);
+ 				add_assoc_zval(return_value, (char*)colnames[j], decoded);
+ 			} else {
+ 				add_next_index_zval(return_value, decoded);
+@@ -1252,10 +2241,10 @@
+ 
+ 	if (rowdata[j] == NULL) {
+ 		RETURN_NULL();
+-	} else if (decode_binary && rowdata[j][0] == '\x01') {
++	} else if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
+ 		int l = strlen(rowdata[j]);
+ 		char *decoded = emalloc(l);
+-		l = sqlite_decode_binary(rowdata[j]+1, decoded);
++		l = php_sqlite_decode_binary(rowdata[j]+1, decoded);
+ 		decoded[l] = '\0';
+ 		RETVAL_STRINGL(decoded, l, 0);
+ 		if (!res->buffered) {
+@@ -1271,26 +2260,37 @@
+ }
+ /* }}} */
+ 
+-/* {{{ proto array sqlite_fetch_all(resource result [, int result_type, bool decode_binary])
+-   Fetches all rows from a result set as an array */
++/* {{{ proto array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])
++   Fetches all rows from a result set as an array of arrays. */
+ PHP_FUNCTION(sqlite_fetch_all)
+ {
+ 	zval *zres, *ent;
+-	int mode = PHPSQLITE_BOTH;
++	long mode = PHPSQLITE_BOTH;
+ 	zend_bool decode_binary = 1;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
+-		return;
+-	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+-	if (ZEND_NUM_ARGS() < 2) {
+-		mode = res->mode;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++		if (!ZEND_NUM_ARGS()) {
++			mode = res->mode;
++		}
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
++		if (ZEND_NUM_ARGS() < 2) {
++			mode = res->mode;
++		}
+ 	}
+ 
+ 	if (res->curr_row >= res->nrows && res->nrows) {
+ 		if (!res->buffered) {
+-			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "One or more rowsets were already returned");
++			php_error_docref(NULL TSRMLS_CC, E_WARNING, "One or more rowsets were already returned; returning NULL this time");
+ 		} else {
+ 			res->curr_row = 0;
+ 		}
+@@ -1306,46 +2306,184 @@
+ }
+ /* }}} */
+ 
+-/* {{{ proto array sqlite_fetch_array(resource result [, int result_type, bool decode_binary])
+-   Fetches the next row from a result set as an array */
++/* {{{ proto array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])
++   Fetches the next row from a result set as an array. */
+ PHP_FUNCTION(sqlite_fetch_array)
+ {
+ 	zval *zres;
+-	int mode = PHPSQLITE_BOTH;
++	long mode = PHPSQLITE_BOTH;
+ 	zend_bool decode_binary = 1;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++		if (!ZEND_NUM_ARGS()) {
++			mode = res->mode;
++		}
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
++		if (ZEND_NUM_ARGS() < 2) {
++			mode = res->mode;
++		}
++	}
++
++	php_sqlite_fetch_array(res, mode, decode_binary, 1, return_value TSRMLS_CC);
++}
++/* }}} */
++
++/* {{{ proto object sqlite_fetch_object(resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]])
++   Fetches the next row from a result set as an object. */
++   /* note that you can do array(&$val) for param ctor_params */
++PHP_FUNCTION(sqlite_fetch_object)
++{
++	zval *zres;
++	zend_bool decode_binary = 1;
++	struct php_sqlite_result *res;
++	zval *object = getThis();
++	char *class_name = NULL;
++	int class_name_len;
++	zend_class_entry *ce;
++	zval dataset;
++	zend_fcall_info fci;
++	zend_fcall_info_cache fcc;
++	zval *retval_ptr;
++	zval *ctor_params = NULL;
++	zend_error_handling error_handling;
++
++	zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szb", &class_name, &class_name_len, &ctor_params, &decode_binary)) {
++			zend_restore_error_handling(&error_handling TSRMLS_CC);
++			return;
++		}
++		RES_FROM_OBJECT_RESTORE_ERH(res, object, &error_handling);
++		if (!class_name) {
++			ce = zend_standard_class_def;
++		} else {
++			ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
++		}
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|szb", &zres, &class_name, &class_name_len, &ctor_params, &decode_binary)) {
++			zend_restore_error_handling(&error_handling TSRMLS_CC);
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
++		if (!class_name) {
++			ce = zend_standard_class_def;
++		} else {
++			ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
++		}
++	}
++
++	if (!ce) {
++		zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not find class '%s'", class_name);
++		zend_restore_error_handling(&error_handling TSRMLS_CC);
+ 		return;
+ 	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+-	if (ZEND_NUM_ARGS() < 2) {
+-		mode = res->mode;
++
++	if (res->curr_row < res->nrows) {
++		php_sqlite_fetch_array(res, PHPSQLITE_ASSOC, decode_binary, 1, &dataset TSRMLS_CC);
++	} else {
++		zend_restore_error_handling(&error_handling TSRMLS_CC);
++		RETURN_FALSE;
+ 	}
+ 
+-	php_sqlite_fetch_array(res, mode, decode_binary, 1, return_value TSRMLS_CC);
++	object_and_properties_init(return_value, ce, NULL);
++	zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
++
++	zend_restore_error_handling(&error_handling TSRMLS_CC);
++
++	if (ce->constructor) {
++		fci.size = sizeof(fci);
++		fci.function_table = &ce->function_table;
++		fci.function_name = NULL;
++		fci.symbol_table = NULL;
++		fci.object_ptr = return_value;
++		fci.retval_ptr_ptr = &retval_ptr;
++		if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
++			if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
++				HashTable *ht = Z_ARRVAL_P(ctor_params);
++				Bucket *p;
++
++				fci.param_count = 0;
++				fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
++				p = ht->pListHead;
++				while (p != NULL) {
++					fci.params[fci.param_count++] = (zval**)p->pData;
++					p = p->pListNext;
++				}
++			} else {
++				/* Two problems why we throw exceptions here: PHP is typeless
++				 * and hence passing one argument that's not an array could be
++				 * by mistake and the other way round is possible, too. The
++				 * single value is an array. Also we'd have to make that one
++				 * argument passed by reference.
++				 */
++				zend_throw_exception(sqlite_ce_exception, "Parameter ctor_params must be an array", 0 TSRMLS_CC);
++				return;
++			}
++		} else {
++			fci.param_count = 0;
++			fci.params = NULL;
++		}
++		fci.no_separation = 1;
++
++		fcc.initialized = 1;
++		fcc.function_handler = ce->constructor;
++		fcc.calling_scope = EG(scope);
++		fcc.called_scope = Z_OBJCE_P(return_value);
++		fcc.object_ptr = return_value;
++
++		if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
++			zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not execute %s::%s()", class_name, ce->constructor->common.function_name);
++		} else {
++			if (retval_ptr) {
++				zval_ptr_dtor(&retval_ptr);
++			}
++		}
++		if (fci.params) {
++			efree(fci.params);
++		}
++	} else if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
++		zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Class %s does not have a constructor, use NULL for parameter ctor_params or omit it", class_name);
++	}
+ }
+ /* }}} */
+ 
+-/* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type, bool decode_binary ])
+-   Executes a query against a given database and returns an array */
++/* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])
++   Executes a query against a given database and returns an array of arrays. */
+ PHP_FUNCTION(sqlite_array_query)
+ {
+ 	zval *zdb, *ent;
+ 	struct php_sqlite_db *db;
+ 	struct php_sqlite_result *rres;
+ 	char *sql;
+-	long sql_len;
+-	int mode = PHPSQLITE_BOTH;
++	int sql_len;
++	long mode = PHPSQLITE_BOTH;
+ 	char *errtext = NULL;
+ 	zend_bool decode_binary = 1;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
+-			ZEND_NUM_ARGS() TSRMLS_CC, "sr|lb", &sql, &sql_len, &zdb, &mode, &decode_binary) && 
+-		FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lb", &zdb, &sql, &sql_len, &mode, &decode_binary)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &sql, &sql_len, &mode, &decode_binary)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
++				ZEND_NUM_ARGS() TSRMLS_CC, "sr|lb", &sql, &sql_len, &zdb, &mode, &decode_binary) &&
++			FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lb", &zdb, &sql, &sql_len, &mode, &decode_binary)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+-	DB_FROM_ZVAL(db, &zdb);
+ 
+ 	PHP_SQLITE_EMPTY_QUERY;
+ 
+@@ -1360,10 +2498,12 @@
+ 		return;
+ 	}
+ 
+-	rres = (struct php_sqlite_result *)emalloc(sizeof(*rres));
+-	sqlite_query(db, sql, sql_len, mode, 0, NULL, rres TSRMLS_CC);
++	rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
++	sqlite_query(NULL, db, sql, sql_len, (int)mode, 0, NULL, &rres, NULL TSRMLS_CC);
+ 	if (db->last_err_code != SQLITE_OK) {
+-		/* no need to free rres, as it will be freed by sqlite_query() for us */
++		if (rres) {
++			efree(rres);
++		}
+ 		RETURN_FALSE;
+ 	}
+ 
+@@ -1384,13 +2524,13 @@
+ 	const char **rowdata;
+ 	char *decoded;
+ 	int decoded_len;
+-	
++
+ 	/* check range of the row */
+ 	if (res->curr_row >= res->nrows) {
+ 		/* no more */
+ 		RETURN_FALSE;
+ 	}
+-	
++
+ 	if (res->buffered) {
+ 		rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
+ 	} else {
+@@ -1399,7 +2539,7 @@
+ 
+ 	if (decode_binary && rowdata[0] != NULL && rowdata[0][0] == '\x01') {
+ 		decoded = emalloc(strlen(rowdata[0]));
+-		decoded_len = sqlite_decode_binary(rowdata[0]+1, decoded);
++		decoded_len = php_sqlite_decode_binary(rowdata[0]+1, decoded);
+ 		if (!res->buffered) {
+ 			efree((char*)rowdata[0]);
+ 			rowdata[0] = NULL;
+@@ -1432,25 +2572,34 @@
+ }
+ /* }}} */
+ 
+-/* {{{ proto array sqlite_single_query(resource db, string query [ , bool single_row, bool decode_binary ])
+-   Executes a query against a given database and returns an array */
++
++/* {{{ proto array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])
++   Executes a query and returns either an array for one single column or the value of the first row. */
+ PHP_FUNCTION(sqlite_single_query)
+ {
+ 	zval *zdb, *ent;
+ 	struct php_sqlite_db *db;
+ 	struct php_sqlite_result *rres;
+ 	char *sql;
+-	long sql_len;
++	int sql_len;
+ 	char *errtext = NULL;
+ 	zend_bool decode_binary = 1;
+ 	zend_bool srow = 1;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
+-			ZEND_NUM_ARGS() TSRMLS_CC, "sr|bb", &sql, &sql_len, &zdb, &srow, &decode_binary) && 
+-		FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|bb", &zdb, &sql, &sql_len, &srow, &decode_binary)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bb", &sql, &sql_len, &srow, &decode_binary)) {
++			return;
++		}
++		RES_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
++				ZEND_NUM_ARGS() TSRMLS_CC, "sr|bb", &sql, &sql_len, &zdb, &srow, &decode_binary) &&
++			FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|bb", &zdb, &sql, &sql_len, &srow, &decode_binary)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+-	DB_FROM_ZVAL(db, &zdb);
+ 
+ 	PHP_SQLITE_EMPTY_QUERY;
+ 
+@@ -1465,10 +2614,12 @@
+ 		return;
+ 	}
+ 
+-	rres = (struct php_sqlite_result *)emalloc(sizeof(*rres));
+-	sqlite_query(db, sql, sql_len, PHPSQLITE_NUM, 0, NULL, rres TSRMLS_CC);
++	rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
++	sqlite_query(NULL, db, sql, sql_len, PHPSQLITE_NUM, 0, NULL, &rres, NULL TSRMLS_CC);
+ 	if (db->last_err_code != SQLITE_OK) {
+-		/* no need to free rres, as it will be freed by sqlite_query() for us */
++		if (rres) {
++			efree(rres);
++		}
+ 		RETURN_FALSE;
+ 	}
+ 
+@@ -1501,38 +2652,57 @@
+ /* }}} */
+ 
+ 
+-/* {{{ proto string sqlite_fetch_array(resource result [, bool decode_binary])
+-   Fetches first column of a result set as a string */
++/* {{{ proto string sqlite_fetch_single(resource result [, bool decode_binary])
++   Fetches the first column of a result set as a string. */
+ PHP_FUNCTION(sqlite_fetch_single)
+ {
+ 	zval *zres;
+ 	zend_bool decode_binary = 1;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &zres, &decode_binary)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &decode_binary)) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &zres, &decode_binary)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 
+ 	php_sqlite_fetch_single(res, decode_binary, return_value TSRMLS_CC);
+ }
+ /* }}} */
+ 
+-/* {{{ proto array sqlite_fetch_array(resource result [, int result_type, bool decode_binary])
+-   Fetches the current row from a result set as an array */
++/* {{{ proto array sqlite_current(resource result [, int result_type [, bool decode_binary]])
++   Fetches the current row from a result set as an array. */
+ PHP_FUNCTION(sqlite_current)
+ {
+ 	zval *zres;
+-	int mode = PHPSQLITE_BOTH;
++	long mode = PHPSQLITE_BOTH;
+ 	zend_bool decode_binary = 1;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
+-		return;
+-	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+-	if (ZEND_NUM_ARGS() < 2) {
+-		mode = res->mode;
++	if (object) {
++		if (ZEND_NUM_ARGS() && FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++		if (!ZEND_NUM_ARGS()) {
++			mode = res->mode;
++		}
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
++		if (ZEND_NUM_ARGS() < 2) {
++			mode = res->mode;
++		}
+ 	}
+ 
+ 	php_sqlite_fetch_array(res, mode, decode_binary, 0, return_value TSRMLS_CC);
+@@ -1540,92 +2710,139 @@
+ /* }}} */
+ 
+ /* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
+-   Fetches a column from the current row of a result set */
++   Fetches a column from the current row of a result set. */
+ PHP_FUNCTION(sqlite_column)
+ {
+ 	zval *zres;
+ 	zval *which;
+ 	zend_bool decode_binary = 1;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zres, &which, &decode_binary)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &which, &decode_binary)) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zres, &which, &decode_binary)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 
+ 	php_sqlite_fetch_column(res, which, decode_binary, return_value TSRMLS_CC);
+ }
+ /* }}} */
+ 
+ /* {{{ proto string sqlite_libversion()
+-   Returns the version of the linked SQLite library */
++   Returns the version of the linked SQLite library. */
+ PHP_FUNCTION(sqlite_libversion)
+ {
+-	if (ZEND_NUM_ARGS() != 0) {
+-		WRONG_PARAM_COUNT;
++	if (zend_parse_parameters_none() == FAILURE) {
++		return;
+ 	}
+ 	RETURN_STRING((char*)sqlite_libversion(), 1);
+ }
+ /* }}} */
+ 
+ /* {{{ proto string sqlite_libencoding()
+-   Returns the encoding (iso8859 or UTF-8) of the linked SQLite library */
++   Returns the encoding (iso8859 or UTF-8) of the linked SQLite library. */
+ PHP_FUNCTION(sqlite_libencoding)
+ {
+-	if (ZEND_NUM_ARGS() != 0) {
+-		WRONG_PARAM_COUNT;
++	if (zend_parse_parameters_none() == FAILURE) {
++		return;
+ 	}
+ 	RETURN_STRING((char*)sqlite_libencoding(), 1);
+ }
+ /* }}} */
+ 
+ /* {{{ proto int sqlite_changes(resource db)
+-   Returns the number of rows that were changed by the most recent SQL statement */
++   Returns the number of rows that were changed by the most recent SQL statement. */
+ PHP_FUNCTION(sqlite_changes)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+ 
+-	DB_FROM_ZVAL(db, &zdb);
+-
+ 	RETURN_LONG(sqlite_changes(db->db));
+ }
+ /* }}} */
+ 
+ /* {{{ proto int sqlite_last_insert_rowid(resource db)
+-   Returns the rowid of the most recently inserted row */
++   Returns the rowid of the most recently inserted row. */
+ PHP_FUNCTION(sqlite_last_insert_rowid)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+ 
+-	DB_FROM_ZVAL(db, &zdb);
+-
+ 	RETURN_LONG(sqlite_last_insert_rowid(db->db));
+ }
+ /* }}} */
+ 
++static int sqlite_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
++{
++	sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
++
++	if (obj->u.res == NULL) {
++		zend_throw_exception(sqlite_ce_exception, "Row count is not available for this query", 0 TSRMLS_CC);
++		return FAILURE;
++	}
++
++	if (obj->u.res->buffered) {
++		* count = obj->u.res->nrows;
++		return SUCCESS;
++	} else {
++		zend_throw_exception(sqlite_ce_exception, "Row count is not available for unbuffered queries", 0 TSRMLS_CC);
++		return FAILURE;
++	}
++} /* }}} */
++
+ /* {{{ proto int sqlite_num_rows(resource result)
+-   Returns the number of rows in a result set */
++   Returns the number of rows in a buffered result set. */
+ PHP_FUNCTION(sqlite_num_rows)
+ {
+ 	zval *zres;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+ 
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+-
+ 	if (res->buffered) {
+ 		RETURN_LONG(res->nrows);
+ 	} else {
+@@ -1635,55 +2852,106 @@
+ }
+ /* }}} */
+ 
+-/* {{{ proto bool sqlite_has_more(resource result)
+-   Returns whether or not more rows are available */
+-PHP_FUNCTION(sqlite_has_more)
++/* {{{ proto bool sqlite_valid(resource result)
++   Returns whether more rows are available. */
++PHP_FUNCTION(sqlite_valid)
+ {
+ 	zval *zres;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 
+-	RETURN_BOOL(res->nrows && res->curr_row < res->nrows); /* curr_row may be -1 */
++	RETURN_BOOL(res->curr_row < res->nrows && res->nrows); /* curr_row may be -1 */
++}
++/* }}} */
++
++/* {{{ proto bool sqlite_has_prev(resource result)
++ * Returns whether a previous row is available. */
++PHP_FUNCTION(sqlite_has_prev)
++{
++	zval *zres;
++	struct php_sqlite_result *res;
++	zval *object = getThis();
++
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
++	}
++
++	if(!res->buffered) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_has_prev on unbuffered querys");
++		RETURN_FALSE;
++	}
++
++	RETURN_BOOL(res->curr_row);
+ }
+ /* }}} */
+ 
+ /* {{{ proto int sqlite_num_fields(resource result)
+-   Returns the number of fields in a result set */
++   Returns the number of fields in a result set. */
+ PHP_FUNCTION(sqlite_num_fields)
+ {
+ 	zval *zres;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+ 
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+-
+ 	RETURN_LONG(res->ncolumns);
+ }
+ /* }}} */
+ 
+-/* {{{ proto string sqlite_field_name(resource result, int field)
+-   Returns the name of a particular field */
++/* {{{ proto string sqlite_field_name(resource result, int field_index)
++   Returns the name of a particular field of a result set. */
+ PHP_FUNCTION(sqlite_field_name)
+ {
+ 	zval *zres;
+ 	struct php_sqlite_result *res;
+-	int field;
++	long field;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &field)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &field)) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &field)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+ 
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+-
+ 	if (field < 0 || field >= res->ncolumns) {
+-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "field %d out of range", field);
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "field %ld out of range", field);
+ 		RETURN_FALSE;
+ 	}
+ 
+@@ -1692,26 +2960,33 @@
+ /* }}} */
+ 
+ /* {{{ proto bool sqlite_seek(resource result, int row)
+-   Seek to a particular row number */
++   Seek to a particular row number of a buffered result set. */
+ PHP_FUNCTION(sqlite_seek)
+ {
+ 	zval *zres;
+ 	struct php_sqlite_result *res;
+-	int row;
++	long row;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &row)) {
+-		return;
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &row)) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &row)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+ 
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+-
+ 	if (!res->buffered) {
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot seek an unbuffered result set");
+ 		RETURN_FALSE;
+ 	}
+-	
++
+ 	if (row < 0 || row >= res->nrows) {
+-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "row %d out of range", row);
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "row %ld out of range", row);
+ 		RETURN_FALSE;
+ 	}
+ 
+@@ -1721,22 +2996,30 @@
+ /* }}} */
+ 
+ /* {{{ proto bool sqlite_rewind(resource result)
+-   Seek to first row number */
++   Seek to the first row number of a buffered result set. */
+ PHP_FUNCTION(sqlite_rewind)
+ {
+ 	zval *zres;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 
+ 	if (!res->buffered) {
+-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot seek an unbuffered result set");
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rewind an unbuffered result set");
+ 		RETURN_FALSE;
+ 	}
+-	
++
+ 	if (!res->nrows) {
+ 		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "no rows received");
+ 		RETURN_FALSE;
+@@ -1748,16 +3031,24 @@
+ /* }}} */
+ 
+ /* {{{ proto bool sqlite_next(resource result)
+-   Seek to next row number */
++   Seek to the next row number of a result set. */
+ PHP_FUNCTION(sqlite_next)
+ {
+ 	zval *zres;
+ 	struct php_sqlite_result *res;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 	}
+-	ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
+ 
+ 	if (!res->buffered && res->vm) {
+ 		php_sqlite_fetch(res TSRMLS_CC);
+@@ -1774,12 +3065,72 @@
+ }
+ /* }}} */
+ 
++/* {{{ proto int sqlite_key(resource result)
++   Return the current row index of a buffered result. */
++PHP_FUNCTION(sqlite_key)
++{
++	zval *zres;
++	struct php_sqlite_result *res;
++	zval *object = getThis();
++
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
++	}
++
++	RETURN_LONG(res->curr_row);
++}
++/* }}} */
++
++/* {{{ proto bool sqlite_prev(resource result)
++ * Seek to the previous row number of a result set. */
++PHP_FUNCTION(sqlite_prev)
++{
++	zval *zres;
++	struct php_sqlite_result *res;
++	zval *object = getThis();
++
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		RES_FROM_OBJECT(res, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
++			return;
++		}
++		ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
++	}
++
++	if (!res->buffered) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_prev on unbuffered querys");
++		RETURN_FALSE;
++	}
++
++	if (res->curr_row <= 0) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "no previous row available");
++		RETURN_FALSE;
++	}
++
++	res->curr_row--;
++
++	RETURN_TRUE;
++}
++/* }}} */
++
+ /* {{{ proto string sqlite_escape_string(string item)
+-   Escapes a string for use as a query parameter */
++   Escapes a string for use as a query parameter. */
+ PHP_FUNCTION(sqlite_escape_string)
+ {
+ 	char *string = NULL;
+-	long stringlen;
++	int stringlen;
+ 	char *ret;
+ 
+ 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &stringlen)) {
+@@ -1789,41 +3140,50 @@
+ 	if (stringlen && (string[0] == '\x01' || memchr(string, '\0', stringlen) != NULL)) {
+ 		/* binary string */
+ 		int enclen;
+-		
+-		ret = emalloc( 1 + 5 + stringlen * ((float) 256 / (float) 253) );
++
++		ret = safe_emalloc(1 + stringlen / 254, 257, 3);
+ 		ret[0] = '\x01';
+-		enclen = sqlite_encode_binary((const unsigned char*)string, stringlen, ret+1);
++		enclen = php_sqlite_encode_binary(string, stringlen, ret+1);
+ 		RETVAL_STRINGL(ret, enclen+1, 0);
+-		
+-	} else  {
++
++	} else if (stringlen) {
+ 		ret = sqlite_mprintf("%q", string);
+ 		if (ret) {
+ 			RETVAL_STRING(ret, 1);
+ 			sqlite_freemem(ret);
+ 		}
++	} else {
++		RETURN_EMPTY_STRING();
+ 	}
+ }
+ /* }}} */
+ 
+ /* {{{ proto int sqlite_last_error(resource db)
+-   Returns the error code of the last error for a database */
++   Returns the error code of the last error for a database. */
+ PHP_FUNCTION(sqlite_last_error)
+ {
+ 	zval *zdb;
+ 	struct php_sqlite_db *db;
++	zval *object = getThis();
+ 
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
+-		return;
++	if (object) {
++		if (zend_parse_parameters_none() == FAILURE) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+ 
+-	DB_FROM_ZVAL(db, &zdb);
+-
+ 	RETURN_LONG(db->last_err_code);
+ }
+ /* }}} */
+ 
+ /* {{{ proto string sqlite_error_string(int error_code)
+-   Returns the textual description of an error code */
++   Returns the textual description of an error code. */
+ PHP_FUNCTION(sqlite_error_string)
+ {
+ 	long code;
+@@ -1832,7 +3192,7 @@
+ 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code)) {
+ 		return;
+ 	}
+-	
++
+ 	msg = sqlite_error_string(code);
+ 
+ 	if (msg) {
+@@ -1890,86 +3250,106 @@
+ 	MAKE_STD_ZVAL(alloc_funcs->step);
+ 	*(alloc_funcs->step)  = *step;
+ 	zval_copy_ctor(alloc_funcs->step);
++	INIT_PZVAL(alloc_funcs->step);
+ 
+ 	if (is_agg) {
+ 		MAKE_STD_ZVAL(alloc_funcs->fini);
+ 		*(alloc_funcs->fini) = *fini;
+ 		zval_copy_ctor(alloc_funcs->fini);
++		INIT_PZVAL(alloc_funcs->fini);
+ 	} else {
+ 		alloc_funcs->fini = NULL;
+ 	}
+ 	alloc_funcs->is_valid = 1;
+ 	*funcs = alloc_funcs;
+-	
++
+ 	return ret;
+ }
+ 
+ 
+ /* {{{ proto bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])
+-    Registers an aggregated function for queries*/
++    Registers an aggregate function for queries. */
+ PHP_FUNCTION(sqlite_create_aggregate)
+ {
+ 	char *funcname = NULL;
+-	long funcname_len;
++	int funcname_len;
+ 	zval *zstep, *zfinal, *zdb;
+ 	struct php_sqlite_db *db;
+ 	struct php_sqlite_agg_functions *funcs;
+ 	char *callable = NULL;
+ 	long num_args = -1;
+-	
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rszz|l", &zdb, &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
+-		return;
++	zval *object = getThis();
++
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rszz|l", &zdb, &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+-	DB_FROM_ZVAL(db, &zdb);
+ 
+-	if (!zend_is_callable(zstep, 0, &callable)) {
++	if (!zend_is_callable(zstep, 0, &callable TSRMLS_CC)) {
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "step function `%s' is not callable", callable);
+ 		efree(callable);
+ 		return;
+ 	}
+ 	efree(callable);
+-	
+-	if (!zend_is_callable(zfinal, 0, &callable)) {
++
++	if (!zend_is_callable(zfinal, 0, &callable TSRMLS_CC)) {
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "finalize function `%s' is not callable", callable);
+ 		efree(callable);
+ 		return;
+ 	}
+ 	efree(callable);
+ 
++
+ 	if (prep_callback_struct(db, 1, funcname, zstep, zfinal, &funcs) == DO_REG) {
+ 		sqlite_create_aggregate(db->db, funcname, num_args,
+ 				php_sqlite_agg_step_function_callback,
+ 				php_sqlite_agg_fini_function_callback, funcs);
+ 	}
+-	
++
+ 
+ }
+ /* }}} */
+ 
+ /* {{{ proto bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])
+-    Registers a "regular" function for queries */
++    Registers a "regular" function for queries. */
+ PHP_FUNCTION(sqlite_create_function)
+ {
+ 	char *funcname = NULL;
+-	long funcname_len;
++	int funcname_len;
+ 	zval *zcall, *zdb;
+ 	struct php_sqlite_db *db;
+ 	struct php_sqlite_agg_functions *funcs;
+ 	char *callable = NULL;
+ 	long num_args = -1;
+-	
+-	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|l", &zdb, &funcname, &funcname_len, &zcall, &num_args)) {
+-		return;
++
++	zval *object = getThis();
++
++	if (object) {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &funcname, &funcname_len, &zcall, &num_args)) {
++			return;
++		}
++		DB_FROM_OBJECT(db, object);
++	} else {
++		if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|l", &zdb, &funcname, &funcname_len, &zcall, &num_args)) {
++			return;
++		}
++		DB_FROM_ZVAL(db, &zdb);
+ 	}
+-	DB_FROM_ZVAL(db, &zdb);
+ 
+-	if (!zend_is_callable(zcall, 0, &callable)) {
++	if (!zend_is_callable(zcall, 0, &callable TSRMLS_CC)) {
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "function `%s' is not callable", callable);
+ 		efree(callable);
+ 		return;
+ 	}
+ 	efree(callable);
+-	
++
+ 	if (prep_callback_struct(db, 0, funcname, zcall, NULL, &funcs) == DO_REG) {
+ 		sqlite_create_function(db->db, funcname, num_args, php_sqlite_function_callback, funcs);
+ 	}
+@@ -1977,11 +3357,11 @@
+ /* }}} */
+ 
+ /* {{{ proto string sqlite_udf_encode_binary(string data)
+-   Apply binary encoding (if required) to a string to return from an UDF */
++   Apply binary encoding (if required) to a string to return from an UDF. */
+ PHP_FUNCTION(sqlite_udf_encode_binary)
+ {
+ 	char *data = NULL;
+-	long datalen;
++	int datalen;
+ 
+ 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
+ 		return;
+@@ -1994,10 +3374,10 @@
+ 		/* binary string */
+ 		int enclen;
+ 		char *ret;
+-		
+-		ret = emalloc( 1 + 5 + datalen * ((float) 256 / (float) 253) );
++
++		ret = safe_emalloc(1 + datalen / 254, 257, 3);
+ 		ret[0] = '\x01';
+-		enclen = sqlite_encode_binary((const unsigned char*)data, datalen, ret+1);
++		enclen = php_sqlite_encode_binary(data, datalen, ret+1);
+ 		RETVAL_STRINGL(ret, enclen+1, 0);
+ 	} else {
+ 		RETVAL_STRINGL(data, datalen, 1);
+@@ -2006,11 +3386,11 @@
+ /* }}} */
+ 
+ /* {{{ proto string sqlite_udf_decode_binary(string data)
+-   Decode binary encoding on a string parameter passed to an UDF */
++   Decode binary encoding on a string parameter passed to an UDF. */
+ PHP_FUNCTION(sqlite_udf_decode_binary)
+ {
+ 	char *data = NULL;
+-	long datalen;
++	int datalen;
+ 
+ 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
+ 		return;
+@@ -2023,9 +3403,9 @@
+ 		/* encoded string */
+ 		int enclen;
+ 		char *ret;
+-		
++
+ 		ret = emalloc(datalen);
+-		enclen = sqlite_decode_binary((const unsigned char*)data+1, ret);
++		enclen = php_sqlite_decode_binary(data+1, ret);
+ 		ret[enclen] = '\0';
+ 		RETVAL_STRINGL(ret, enclen, 0);
+ 	} else {
+diff -dPNur sqlite-1.0.3/sqlite.dsp sqlite-svn/sqlite.dsp
+--- sqlite-1.0.3/sqlite.dsp	2004-01-17 00:33:14.000000000 +0000
++++ sqlite-svn/sqlite.dsp	2012-10-09 13:36:42.760063980 +0000
+@@ -44,7 +44,7 @@
+ # PROP Ignore_Export_Lib 0
+ # PROP Target_Dir ""
+ # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SQLITE_EXPORTS" /YX /FD /c
+-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\php4" /I "..\..\..\php4\main" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_SQLITE" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_SQLITE=1 /D "PHP_SQLITE_EXPORTS" /FR /YX /FD /c
++# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\win32" /I "..\..\..\php_build" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_SQLITE" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_SQLITE=1 /D "PHP_SQLITE_EXPORTS" /FR /YX /FD /c
+ # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+ # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+ # ADD BASE RSC /l 0x407 /d "NDEBUG"
+@@ -54,7 +54,7 @@
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+-# ADD LINK32 php4ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS\php_sqlite.dll" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline" /libpath:"..\..\..\php_build\release"
++# ADD LINK32 php5ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS\php_sqlite.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\release"
+ 
+ !ELSEIF  "$(CFG)" == "sqlite - Win32 Debug_TS"
+ 
+@@ -70,7 +70,7 @@
+ # PROP Ignore_Export_Lib 0
+ # PROP Target_Dir ""
+ # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SQLITE_EXPORTS" /YX /FD /GZ /c
+-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\php4" /I "..\..\..\php4\main" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_SQLITE" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_SQLITE=1 /D "PHP_SQLITE_EXPORTS" /YX /FD /GZ /c
++# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\win32" /I "..\..\..\php_build" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_SQLITE" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_SQLITE=1 /D "PHP_SQLITE_EXPORTS" /YX /FD /GZ /c
+ # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+ # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+ # ADD BASE RSC /l 0x407 /d "_DEBUG"
+@@ -80,7 +80,7 @@
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 php4ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS\php_sqlite.dll" /pdbtype:sept /libpath:"..\..\..\php4\Debug_TS" /libpath:"..\..\..\php_build\release"
++# ADD LINK32 php5ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS\php_sqlite.dll" /pdbtype:sept /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\release"
+ 
+ !ENDIF 
+ 
+@@ -314,10 +314,6 @@
+ # End Source File
+ # Begin Source File
+ 
+-SOURCE=.\libsqlite\src\vdbeInt.h
+-# End Source File
+-# Begin Source File
+-
+ SOURCE=.\libsqlite\src\where.c
+ # End Source File
+ # End Group
+diff -dPNur sqlite-1.0.3/sqlite.php sqlite-svn/sqlite.php
+--- sqlite-1.0.3/sqlite.php	2003-04-17 20:08:00.000000000 +0000
++++ sqlite-svn/sqlite.php	2012-10-09 13:36:42.760063980 +0000
+@@ -1,6 +1,9 @@
+ <?php
+ if (!extension_loaded("sqlite")) {
+ 	dl("sqlite.so");
++	if (!extension_loaded("sqlite")) {
++		exit("Please enable SQLite support\n");
++	}
+ }
+ 
+ debug_zval_dump(sqlite_libversion());
+diff -dPNur sqlite-1.0.3/tests/blankdb.inc sqlite-svn/tests/blankdb.inc
+--- sqlite-1.0.3/tests/blankdb.inc	2003-04-18 20:53:18.000000000 +0000
++++ sqlite-svn/tests/blankdb.inc	2012-10-09 13:36:42.740092676 +0000
+@@ -1,11 +1,3 @@
+ <?php #vim:ft=php
+-$dbname = tempnam(dirname(__FILE__), "phpsql");
+-function cleanup() {
+-	if ($GLOBALS['db']) {
+-		sqlite_close($GLOBALS['db']);
+-	}
+-	unlink($GLOBALS['dbname']);
+-}
+-register_shutdown_function("cleanup");
+-$db = sqlite_open($dbname);
++$db = sqlite_open(":memory:");
+ ?>
+diff -dPNur sqlite-1.0.3/tests/blankdb_oo.inc sqlite-svn/tests/blankdb_oo.inc
+--- sqlite-1.0.3/tests/blankdb_oo.inc	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/blankdb_oo.inc	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,3 @@
++<?php #vim:ft=php
++$db = new SQLiteDatabase(":memory:");
++?>
+diff -dPNur sqlite-1.0.3/tests/bug26911.phpt sqlite-svn/tests/bug26911.phpt
+--- sqlite-1.0.3/tests/bug26911.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/bug26911.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,12 @@
++--TEST--
++Bug #26911 (crash when fetching data from empty queries)
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php
++	$db = sqlite_open(":memory:");
++	$a = sqlite_query($db, "  ");
++	echo "I am ok\n";
++?>
++--EXPECT--
++I am ok
+diff -dPNur sqlite-1.0.3/tests/bug28112.phpt sqlite-svn/tests/bug28112.phpt
+--- sqlite-1.0.3/tests/bug28112.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/bug28112.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,16 @@
++--TEST--
++Bug #28112 (sqlite_query() crashing apache on malformed query)
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php
++
++if (!($db = sqlite_open(":memory:", 666, $error))) die ("Couldn't open the database");
++sqlite_query($db, "create table frob (foo INTEGER PRIMARY KEY, bar text);");
++$res = @sqlite_array_query($db, "");
++
++?>
++===DONE===
++<?php exit(0); ?>
++--EXPECTF--
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/bug35248.phpt sqlite-svn/tests/bug35248.phpt
+--- sqlite-1.0.3/tests/bug35248.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/bug35248.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,15 @@
++--TEST--
++Bug #35248 (sqlite_query does not return parse error message)
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php
++	$db = sqlite_open(":memory:");
++	$res = @sqlite_query($db, "asdfesdfa", SQLITE_NUM, $err);
++	var_dump($err);
++	$res = @sqlite_unbuffered_query($db, "asdfesdfa", SQLITE_NUM, $err);
++	var_dump($err);
++?>
++--EXPECT--
++string(30) "near "asdfesdfa": syntax error"
++string(30) "near "asdfesdfa": syntax error"
+diff -dPNur sqlite-1.0.3/tests/bug38759.phpt sqlite-svn/tests/bug38759.phpt
+--- sqlite-1.0.3/tests/bug38759.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/bug38759.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,18 @@
++--TEST--
++Bug #38759 (sqlite2 empty query causes segfault)
++--SKIPIF--
++<?php 
++if (!extension_loaded("pdo")) print "skip"; 
++if (!extension_loaded("sqlite")) print "skip"; 
++?>
++--FILE--
++<?php
++
++$dbh = new PDO('sqlite2::memory:');
++var_dump($dbh->query(" "));
++
++echo "Done\n";
++?>
++--EXPECTF--	
++bool(false)
++Done
+diff -dPNur sqlite-1.0.3/tests/bug48679.phpt sqlite-svn/tests/bug48679.phpt
+--- sqlite-1.0.3/tests/bug48679.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/bug48679.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,20 @@
++--TEST--
++Bug #48679 (sqlite2 count on unbuffered query causes segfault)
++--SKIPIF--
++<?php 
++if (!extension_loaded("sqlite")) print "skip"; 
++?>
++--FILE--
++<?php
++
++try {
++	$x = new sqliteunbuffered;
++	count($x);
++} catch (SQLiteException $e) {
++	var_dump($e->getMessage());
++}
++echo "Done\n";
++?>
++--EXPECT--	
++string(41) "Row count is not available for this query"
++Done
+diff -dPNur sqlite-1.0.3/tests/pdo/common.phpt sqlite-svn/tests/pdo/common.phpt
+--- sqlite-1.0.3/tests/pdo/common.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/pdo/common.phpt	2012-10-09 13:36:42.700706048 +0000
+@@ -0,0 +1,12 @@
++--TEST--
++SQLite2
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded('pdo') || !extension_loaded('sqlite')) print 'skip'; ?>
++--REDIRECTTEST--
++return array(
++	'ENV' => array(
++			'PDOTEST_DSN' => 'sqlite2::memory:'
++		),
++	'TESTS' => 'ext/pdo/tests'
++	);
+diff -dPNur sqlite-1.0.3/tests/sqlite_001.phpt sqlite-svn/tests/sqlite_001.phpt
+--- sqlite-1.0.3/tests/sqlite_001.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_001.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -9,7 +9,6 @@
+ require_once('blankdb.inc');
+ echo "$db\n";
+ sqlite_close($db);
+-$db = NULL;
+ echo "Done\n";
+ ?>
+ --EXPECTF--
+diff -dPNur sqlite-1.0.3/tests/sqlite_002.phpt sqlite-svn/tests/sqlite_002.phpt
+--- sqlite-1.0.3/tests/sqlite_002.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_002.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -13,6 +13,7 @@
+ sqlite_query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)", $db);
+ $r = sqlite_query("SELECT * from foo", $db);
+ var_dump(sqlite_fetch_array($r));
++sqlite_close($db);
+ ?>
+ --EXPECT--
+ array(6) {
+diff -dPNur sqlite-1.0.3/tests/sqlite_003.phpt sqlite-svn/tests/sqlite_003.phpt
+--- sqlite-1.0.3/tests/sqlite_003.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_003.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -17,6 +17,7 @@
+ var_dump(sqlite_fetch_array($r, SQLITE_NUM));
+ $r = sqlite_query("SELECT * from foo", $db);
+ var_dump(sqlite_fetch_array($r, SQLITE_ASSOC));
++sqlite_close($db);
+ ?>
+ --EXPECT--
+ array(6) {
+diff -dPNur sqlite-1.0.3/tests/sqlite_004.phpt sqlite-svn/tests/sqlite_004.phpt
+--- sqlite-1.0.3/tests/sqlite_004.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_004.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -35,6 +35,9 @@
+ 	}
+ 	$i++;
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_005.phpt sqlite-svn/tests/sqlite_005.phpt
+--- sqlite-1.0.3/tests/sqlite_005.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_005.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -37,6 +37,9 @@
+ while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
+ 	var_dump($row);
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_006.phpt sqlite-svn/tests/sqlite_006.phpt
+--- sqlite-1.0.3/tests/sqlite_006.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_006.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -34,6 +34,9 @@
+ while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
+ 	var_dump($row);
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_007.phpt sqlite-svn/tests/sqlite_007.phpt
+--- sqlite-1.0.3/tests/sqlite_007.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_007.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -17,6 +17,7 @@
+ var_dump(sqlite_fetch_array($r, SQLITE_NUM));
+ $r = sqlite_unbuffered_query("SELECT * from foo", $db);
+ var_dump(sqlite_fetch_array($r, SQLITE_ASSOC));
++sqlite_close($db);
+ ?>
+ --EXPECT--
+ array(6) {
+diff -dPNur sqlite-1.0.3/tests/sqlite_008.phpt sqlite-svn/tests/sqlite_008.phpt
+--- sqlite-1.0.3/tests/sqlite_008.phpt	2003-05-02 22:09:54.000000000 +0000
++++ sqlite-svn/tests/sqlite_008.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -25,6 +25,9 @@
+ while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
+ 	var_dump($row);
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_009.phpt sqlite-svn/tests/sqlite_009.phpt
+--- sqlite-1.0.3/tests/sqlite_009.phpt	2003-05-01 13:29:11.000000000 +0000
++++ sqlite-svn/tests/sqlite_009.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -25,6 +25,9 @@
+ while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
+ 	var_dump($row);
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_010.phpt sqlite-svn/tests/sqlite_010.phpt
+--- sqlite-1.0.3/tests/sqlite_010.phpt	2003-05-02 22:09:54.000000000 +0000
++++ sqlite-svn/tests/sqlite_010.phpt	2012-10-09 13:36:42.721252390 +0000
+@@ -22,20 +22,23 @@
+ }
+ 
+ $r = sqlite_unbuffered_query("SELECT a from strings", $db);
+-while (sqlite_has_more($r)) {
++while (sqlite_valid($r)) {
+ 	var_dump(sqlite_current($r, SQLITE_NUM));
+ 	sqlite_next($r);
+ }
+ $r = sqlite_query("SELECT a from strings", $db);
+-while (sqlite_has_more($r)) {
++while (sqlite_valid($r)) {
+ 	var_dump(sqlite_current($r, SQLITE_NUM));
+ 	sqlite_next($r);
+ }
+ sqlite_rewind($r);
+-while (sqlite_has_more($r)) {
++while (sqlite_valid($r)) {
+ 	var_dump(sqlite_current($r, SQLITE_NUM));
+ 	sqlite_next($r);
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_011.phpt sqlite-svn/tests/sqlite_011.phpt
+--- sqlite-1.0.3/tests/sqlite_011.phpt	2003-12-14 18:47:14.000000000 +0000
++++ sqlite-svn/tests/sqlite_011.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -15,6 +15,7 @@
+ sqlite_query("INSERT INTO bar VALUES ('4', '5', '6')", $db);
+ $r = sqlite_query("SELECT * from foo, bar", $db, SQLITE_ASSOC);
+ var_dump(sqlite_fetch_array($r));
++sqlite_close($db);
+ ?>
+ --EXPECT--
+ array(6) {
+diff -dPNur sqlite-1.0.3/tests/sqlite_012.phpt sqlite-svn/tests/sqlite_012.phpt
+--- sqlite-1.0.3/tests/sqlite_012.phpt	2003-05-02 22:09:54.000000000 +0000
++++ sqlite-svn/tests/sqlite_012.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -21,6 +21,9 @@
+ for($i=0; $i<sqlite_num_fields($r); $i++) {
+ 	var_dump(sqlite_field_name($r, $i));
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_013.phpt sqlite-svn/tests/sqlite_013.phpt
+--- sqlite-1.0.3/tests/sqlite_013.phpt	2003-06-09 23:16:32.000000000 +0000
++++ sqlite-svn/tests/sqlite_013.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -22,7 +22,7 @@
+ 
+ echo "====BUFFERED====\n";
+ $r = sqlite_query("SELECT a, b from strings", $db);
+-while (sqlite_has_more($r)) {
++while (sqlite_valid($r)) {
+ 	var_dump(sqlite_current($r, SQLITE_NUM));
+ 	var_dump(sqlite_column($r, 0));
+ 	var_dump(sqlite_column($r, 1));
+@@ -32,13 +32,16 @@
+ }
+ echo "====UNBUFFERED====\n";
+ $r = sqlite_unbuffered_query("SELECT a, b from strings", $db);
+-while (sqlite_has_more($r)) {
++while (sqlite_valid($r)) {
+ 	var_dump(sqlite_column($r, 0));
+ 	var_dump(sqlite_column($r, 'b'));
+ 	var_dump(sqlite_column($r, 1));
+ 	var_dump(sqlite_column($r, 'a'));
+ 	sqlite_next($r);
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_014.phpt sqlite-svn/tests/sqlite_014.phpt
+--- sqlite-1.0.3/tests/sqlite_014.phpt	2003-06-09 23:21:06.000000000 +0000
++++ sqlite-svn/tests/sqlite_014.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -37,6 +37,8 @@
+ var_dump(sqlite_fetch_array($r));
+ var_dump(sqlite_fetch_all($r));
+ 
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECTF--
+@@ -59,7 +61,7 @@
+   }
+ }
+ 
+-Notice: sqlite_fetch_all(): One or more rowsets were already returned in %ssqlite_014.php on line %d
++Warning: sqlite_fetch_all(): One or more rowsets were already returned; returning NULL this time in %ssqlite_014.php on line %d
+ array(0) {
+ }
+ unbuffered with fetch_array
+diff -dPNur sqlite-1.0.3/tests/sqlite_015.phpt sqlite-svn/tests/sqlite_015.phpt
+--- sqlite-1.0.3/tests/sqlite_015.phpt	2003-06-09 23:22:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_015.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -24,6 +24,8 @@
+ $res = sqlite_array_query("SELECT a from strings", $db, SQLITE_NUM);
+ var_dump($res);
+ 
++$db = null;
++
+ echo "DONE!\n";
+ ?>
+ --EXPECTF--
+diff -dPNur sqlite-1.0.3/tests/sqlite_016.phpt sqlite-svn/tests/sqlite_016.phpt
+--- sqlite-1.0.3/tests/sqlite_016.phpt	2003-06-26 21:32:37.000000000 +0000
++++ sqlite-svn/tests/sqlite_016.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -22,14 +22,17 @@
+ 
+ echo "====BUFFERED====\n";
+ $r = sqlite_query("SELECT a, b from strings", $db);
+-while (sqlite_has_more($r)) {
++while (sqlite_valid($r)) {
+ 	var_dump(sqlite_fetch_single($r));
+ }
+ echo "====UNBUFFERED====\n";
+ $r = sqlite_unbuffered_query("SELECT a, b from strings", $db);
+-while (sqlite_has_more($r)) {
++while (sqlite_valid($r)) {
+ 	var_dump(sqlite_fetch_single($r));
+ }
++
++sqlite_close($db);
++
+ echo "DONE!\n";
+ ?>
+ --EXPECT--
+diff -dPNur sqlite-1.0.3/tests/sqlite_018.phpt sqlite-svn/tests/sqlite_018.phpt
+--- sqlite-1.0.3/tests/sqlite_018.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_018.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,14 @@
++--TEST--
++sqlite: crash on bad queries inside sqlite_array_query()
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php
++include "blankdb.inc";
++
++sqlite_array_query($db, "SELECT foo FROM foobar");
++sqlite_close($db);
++?>
++--EXPECTF--
++Warning: sqlite_array_query(): no such table: foobar in %s on line %d
+diff -dPNur sqlite-1.0.3/tests/sqlite_019.phpt sqlite-svn/tests/sqlite_019.phpt
+--- sqlite-1.0.3/tests/sqlite_019.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_019.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,47 @@
++--TEST--
++sqlite: single query
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php
++include "blankdb.inc";
++	
++sqlite_query($db, "CREATE TABLE test_db ( id INTEGER PRIMARY KEY, data VARCHAR(100) )");
++for ($i = 0; $i < 10; $i++) {
++	sqlite_query($db, "INSERT INTO test_db (data) VALUES('{$i}data')");
++}
++sqlite_query($db, "INSERT INTO test_db (data) VALUES(NULL)");
++	                                         
++var_dump(sqlite_single_query($db, "SELECT id FROM test_db WHERE id=5"));
++var_dump(sqlite_single_query($db, "SELECT * FROM test_db WHERE id=4"));
++var_dump(sqlite_single_query($db, "SELECT data FROM test_db WHERE id=6"));
++var_dump(sqlite_single_query($db, "SELECT * FROM test_db WHERE id < 5"));
++var_dump(sqlite_single_query($db, "SELECT * FROM test db WHERE id < 4"));
++var_dump(sqlite_single_query($db, "SELECT * FROM test_db WHERE id=999999"));
++var_dump(sqlite_single_query($db, "SELECT id FROM test_db WHERE id=5", FALSE));
++
++sqlite_close($db);
++?>
++--EXPECTF--
++string(1) "5"
++string(1) "4"
++string(5) "5data"
++array(4) {
++  [0]=>
++  string(1) "1"
++  [1]=>
++  string(1) "2"
++  [2]=>
++  string(1) "3"
++  [3]=>
++  string(1) "4"
++}
++
++Warning: sqlite_single_query(): no such table: test in %s on line %d
++bool(false)
++NULL
++array(1) {
++  [0]=>
++  string(1) "5"
++}
+diff -dPNur sqlite-1.0.3/tests/sqlite_022.phpt sqlite-svn/tests/sqlite_022.phpt
+--- sqlite-1.0.3/tests/sqlite_022.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_022.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,101 @@
++--TEST--
++sqlite: sqlite_seek
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++sqlite_query("CREATE TABLE strings(a)", $db);
++
++foreach ($data as $str) {
++	sqlite_query("INSERT INTO strings VALUES('$str')", $db);
++}
++
++$res = sqlite_query("SELECT a FROM strings", $db, SQLITE_NUM);
++for ($idx = -1; $idx < 4; $idx++) {
++	echo "====SEEK:$idx====\n";
++	sqlite_seek($res, $idx);
++	var_dump(sqlite_current($res));
++}
++echo "====AGAIN====\n";
++for ($idx = -1; $idx < 4; $idx++) {
++	echo "====SEEK:$idx====\n";
++	sqlite_seek($res, $idx);
++	var_dump(sqlite_current($res));
++}
++
++sqlite_close($db);
++
++echo "====DONE!====\n";
++?>
++--EXPECTF--
++====SEEK:-1====
++
++Warning: sqlite_seek(): row -1 out of range in %ssqlite_022.php on line %d
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++====SEEK:0====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++====SEEK:1====
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++====SEEK:2====
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====SEEK:3====
++
++Warning: sqlite_seek(): row 3 out of range in %ssqlite_022.php on line %d
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====AGAIN====
++====SEEK:-1====
++
++Warning: sqlite_seek(): row -1 out of range in %ssqlite_022.php on line %d
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====SEEK:0====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++====SEEK:1====
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++====SEEK:2====
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====SEEK:3====
++
++Warning: sqlite_seek(): row 3 out of range in %ssqlite_022.php on line %d
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====DONE!====
+diff -dPNur sqlite-1.0.3/tests/sqlite_023.phpt sqlite-svn/tests/sqlite_023.phpt
+--- sqlite-1.0.3/tests/sqlite_023.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_023.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,105 @@
++--TEST--
++sqlite: sqlite_[has_]prev
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php
++include "blankdb.inc";
++
++$data = array(
++              "one",
++              "two",
++              "three"
++              );
++
++sqlite_query("CREATE TABLE strings(a)", $db);
++
++foreach ($data as $str) {
++  sqlite_query("INSERT INTO strings VALUES('$str')", $db);
++}
++
++$r = sqlite_query("SELECT a FROM strings", $db, SQLITE_NUM);
++
++echo "====TRAVERSE====\n";
++for(sqlite_rewind($r); sqlite_valid($r); sqlite_next($r)) {
++  var_dump(sqlite_current($r));
++
++}
++echo "====REVERSE====\n";
++do {
++  sqlite_prev($r);
++  var_dump(sqlite_current($r));
++} while(sqlite_has_prev($r));
++
++echo "====UNBUFFERED====\n";
++
++$r = sqlite_unbuffered_query("SELECT a FROM strings", $db, SQLITE_NUM);
++
++echo "====TRAVERSE====\n";
++for(sqlite_rewind($r); sqlite_valid($r); sqlite_next($r)) {
++  var_dump(sqlite_current($r));
++
++}
++echo "====REVERSE====\n";
++do {
++  sqlite_prev($r);
++  var_dump(sqlite_current($r));
++} while(sqlite_has_prev($r));
++
++sqlite_close($db);
++
++echo "====DONE!====\n";
++?>
++--EXPECTF--
++====TRAVERSE====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====REVERSE====
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++====UNBUFFERED====
++====TRAVERSE====
++
++Warning: sqlite_rewind(): Cannot rewind an unbuffered result set in %ssqlite_023.php on line %d
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====REVERSE====
++
++Warning: sqlite_prev(): you cannot use sqlite_prev on unbuffered querys in %ssqlite_023.php on line %d
++bool(false)
++
++Warning: sqlite_has_prev(): you cannot use sqlite_has_prev on unbuffered querys in %ssqlite_023.php on line %d
++====DONE!====
+diff -dPNur sqlite-1.0.3/tests/sqlite_024.phpt sqlite-svn/tests/sqlite_024.phpt
+--- sqlite-1.0.3/tests/sqlite_024.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_024.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,76 @@
++--TEST--
++sqlite: sqlite_fetch_object
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb.inc";
++
++class class24 {
++	function __construct() {
++		echo __METHOD__ . "\n";
++	}
++}
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++sqlite_query($db, "CREATE TABLE strings(a)");
++
++foreach ($data as $str) {
++	sqlite_query($db, "INSERT INTO strings VALUES('$str')");
++}
++
++echo "====class24====\n";
++$res = sqlite_query($db, "SELECT a FROM strings", SQLITE_ASSOC);
++while (sqlite_valid($res)) {
++	var_dump(sqlite_fetch_object($res, 'class24'));
++}
++
++echo "====stdclass====\n";
++$res = sqlite_query($db, "SELECT a FROM strings", SQLITE_ASSOC);
++while (sqlite_valid($res)) {
++	var_dump(sqlite_fetch_object($res));
++}
++
++sqlite_close($db);
++
++echo "====DONE!====\n";
++?>
++--EXPECTF--
++====class24====
++class24::__construct
++object(class24)#%d (1) {
++  ["a"]=>
++  string(3) "one"
++}
++class24::__construct
++object(class24)#%d (1) {
++  ["a"]=>
++  string(3) "two"
++}
++class24::__construct
++object(class24)#%d (1) {
++  ["a"]=>
++  string(5) "three"
++}
++====stdclass====
++object(stdClass)#%d (1) {
++  ["a"]=>
++  string(3) "one"
++}
++object(stdClass)#%d (1) {
++  ["a"]=>
++  string(3) "two"
++}
++object(stdClass)#%d (1) {
++  ["a"]=>
++  string(5) "three"
++}
++====DONE!====
+diff -dPNur sqlite-1.0.3/tests/sqlite_025.phpt sqlite-svn/tests/sqlite_025.phpt
+--- sqlite-1.0.3/tests/sqlite_025.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_025.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,38 @@
++--TEST--
++sqlite: sqlite_fetch_object in a loop
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb.inc";
++
++sqlite_query($db, "CREATE TABLE strings(a)");
++
++foreach (array("one", "two", "three") as $str) {
++	sqlite_query($db, "INSERT INTO strings VALUES('$str')");
++}
++
++$res = sqlite_query("SELECT * FROM strings", $db);
++
++while (($obj = sqlite_fetch_object($res))) {
++	var_dump($obj);
++}
++
++sqlite_close($db);
++?>
++--EXPECTF--
++object(stdClass)#1 (1) {
++  ["a"]=>
++  string(3) "one"
++}
++object(stdClass)#2 (1) {
++  ["a"]=>
++  string(3) "two"
++}
++object(stdClass)#1 (1) {
++  ["a"]=>
++  string(5) "three"
++}
+\ No newline at end of file
+diff -dPNur sqlite-1.0.3/tests/sqlite_026.phpt sqlite-svn/tests/sqlite_026.phpt
+--- sqlite-1.0.3/tests/sqlite_026.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_026.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,27 @@
++--TEST--
++sqlite: sqlite_fetch_column_types
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb.inc";
++
++sqlite_query($db, "CREATE TABLE strings(a, b INTEGER, c VARCHAR(10), d)");
++sqlite_query($db, "INSERT INTO strings VALUES('1', '2', '3', 'abc')");
++
++var_dump(sqlite_fetch_column_types($db, "strings"));
++
++sqlite_close($db);
++?>
++--EXPECT--
++array(4) {
++  ["a"]=>
++  string(0) ""
++  ["b"]=>
++  string(7) "INTEGER"
++  ["c"]=>
++  string(11) "VARCHAR(10)"
++  ["d"]=>
++  string(0) ""
++}
+diff -dPNur sqlite-1.0.3/tests/sqlite_027.phpt sqlite-svn/tests/sqlite_027.phpt
+--- sqlite-1.0.3/tests/sqlite_027.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_027.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,15 @@
++--TEST--
++sqlite: crash inside sqlite_escape_string() & sqlite_udf_encode_binary
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--INI--
++memory_limit=-1
++--FILE--
++<?php
++	var_dump(strlen(sqlite_escape_string(str_repeat("\0", 20000000))));
++	var_dump(strlen(sqlite_udf_encode_binary(str_repeat("\0", 20000000))));
++?>
++--EXPECT--
++int(20000002)
++int(20000002)
+diff -dPNur sqlite-1.0.3/tests/sqlite_closures_001.phpt sqlite-svn/tests/sqlite_closures_001.phpt
+--- sqlite-1.0.3/tests/sqlite_closures_001.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_closures_001.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,54 @@
++--TEST--
++sqlite: aggregate functions with closures
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++sqlite_query("CREATE TABLE strings(a)", $db);
++
++foreach ($data as $str) {
++	sqlite_query("INSERT INTO strings VALUES('" . sqlite_escape_string($str) . "')", $db);
++}
++
++function cat_step(&$context, $string)
++{
++	$context .= $string;
++}
++
++function cat_fin(&$context)
++{
++	return $context;
++}
++
++sqlite_create_aggregate($db, "cat", function (&$context, $string) {
++	$context .= $string;
++}, function (&$context) {
++	return $context;
++});
++
++$r = sqlite_query("SELECT cat(a) from strings", $db);
++while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
++	var_dump($row);
++}
++
++sqlite_close($db);
++
++echo "DONE!\n";
++?>
++--EXPECT--
++array(1) {
++  [0]=>
++  string(11) "onetwothree"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_closures_002.phpt sqlite-svn/tests/sqlite_closures_002.phpt
+--- sqlite-1.0.3/tests/sqlite_closures_002.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_closures_002.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,52 @@
++--TEST--
++sqlite: regular functions with closures
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb.inc";
++
++$data = array(
++	array("one", "uno"),
++	array("two", "dos"),
++	array("three", "tres"),
++	);
++
++sqlite_query("CREATE TABLE strings(a,b)", $db);
++
++foreach ($data as $row) {
++	sqlite_query("INSERT INTO strings VALUES('" . sqlite_escape_string($row[0]) . "','" . sqlite_escape_string($row[1]) . "')", $db);
++}
++
++sqlite_create_function($db, "implode", function () {
++	$args = func_get_args();
++	$sep = array_shift($args);
++	return implode($sep, $args);
++});
++
++$r = sqlite_query("SELECT implode('-', a, b) from strings", $db);
++while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
++	var_dump($row);
++}
++
++sqlite_close($db);
++
++echo "DONE!\n";
++?>
++--EXPECT--
++array(1) {
++  [0]=>
++  string(7) "one-uno"
++}
++array(1) {
++  [0]=>
++  string(7) "two-dos"
++}
++array(1) {
++  [0]=>
++  string(10) "three-tres"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_exec_basic.phpt sqlite-svn/tests/sqlite_exec_basic.phpt
+--- sqlite-1.0.3/tests/sqlite_exec_basic.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_exec_basic.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,34 @@
++--TEST--
++Test sqlite_exec() function : basic functionality 
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
++--FILE--
++<?php
++/* Prototype  : boolean sqlite_exec(string query, resource db[, string &error_message])
++ * Description: Executes a result-less query against a given database 
++ * Source code: ext/sqlite/sqlite.c
++ * Alias to functions: 
++ */
++
++echo "*** Testing sqlite_exec() : basic functionality ***\n";
++
++// set up variables
++$query = 'CREATE TABLE foobar (id INTEGER PRIMARY KEY, name CHAR(255));';
++$error_message = null;
++
++// procedural
++$db = sqlite_open(':memory:');
++var_dump( sqlite_exec($db, $query) );
++sqlite_close($db);
++
++// oo-style
++$db = new SQLiteDatabase(':memory:');
++var_dump( $db->queryExec($query, $error_message) );
++
++?>
++===DONE===
++--EXPECTF--
++*** Testing sqlite_exec() : basic functionality ***
++bool(true)
++bool(true)
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_exec_error.phpt sqlite-svn/tests/sqlite_exec_error.phpt
+--- sqlite-1.0.3/tests/sqlite_exec_error.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_exec_error.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,44 @@
++--TEST--
++Test sqlite_exec() function : error behaviour and functionality 
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
++--FILE--
++<?php
++/* Prototype  : boolean sqlite_exec(string query, resource db[, string &error_message])
++ * Description: Executes a result-less query against a given database 
++ * Source code: ext/sqlite/sqlite.c
++ * Alias to functions: 
++ */
++
++echo "*** Testing sqlite_exec() : error functionality ***\n";
++
++// set up variables
++$fail = 'CRE ATE TABLE';
++$error_message = null;
++
++// procedural
++$db = sqlite_open(':memory:');
++var_dump( sqlite_exec($db, $fail, $error_message) );
++var_dump( $error_message );
++var_dump( sqlite_exec($db) );
++sqlite_close($db);
++
++// oo-style
++$db = new SQLiteDatabase(':memory:');
++var_dump( $db->queryExec($fail, $error_message, 'fooparam') );
++
++?>
++===DONE===
++--EXPECTF--
++*** Testing sqlite_exec() : error functionality ***
++
++Warning: sqlite_exec(): near "CRE": syntax error in %s on line %d
++bool(false)
++%string|unicode%(24) "near "CRE": syntax error"
++
++Warning: sqlite_exec() expects at least 2 parameters, 1 given in %s on line %d
++NULL
++
++Warning: SQLiteDatabase::queryExec() expects at most 2 parameters, 3 given in %s on line %d
++NULL
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_last_error_basic.phpt sqlite-svn/tests/sqlite_last_error_basic.phpt
+--- sqlite-1.0.3/tests/sqlite_last_error_basic.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_last_error_basic.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,48 @@
++--TEST--
++Test sqlite_last_error() function : basic functionality 
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
++--FILE--
++<?php
++/* Prototype  : int sqlite_last_error(resource db)
++ * Description: Returns the error code of the last error for a database. 
++ * Source code: ext/sqlite/sqlite.c
++ * Alias to functions: 
++ */
++
++echo "*** Testing sqlite_last_error() : basic functionality ***\n";
++
++// set up variables
++$query = 'CREATE TAB LE foobar (id INTEGER PRIMARY KEY, name CHAR(255));';
++$query_ok = 'CREATE TABLE foobar (id INTEGER, name CHAR(255));';
++
++// procedural
++$db = sqlite_open(':memory:');
++var_dump( sqlite_last_error($db) === SQLITE_OK );
++sqlite_exec($db, $query);
++var_dump( sqlite_last_error($db) === SQLITE_ERROR );
++sqlite_exec($db, $query_ok);
++var_dump( sqlite_last_error($db) === SQLITE_OK );
++sqlite_close($db);
++
++// oo-style
++$db = new SQLiteDatabase(':memory:');
++$db->queryExec($query);
++var_dump( $db->lastError() === SQLITE_ERROR );
++$db->queryExec($query_ok);
++var_dump( $db->lastError() === SQLITE_OK );
++
++?>
++===DONE===
++--EXPECTF--
++*** Testing sqlite_last_error() : basic functionality ***
++bool(true)
++
++Warning: sqlite_exec(): near "TAB": syntax error in %s on line %d
++bool(true)
++bool(true)
++
++Warning: SQLiteDatabase::queryExec(): near "TAB": syntax error in %s on line %d
++bool(true)
++bool(true)
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_last_error_error.phpt sqlite-svn/tests/sqlite_last_error_error.phpt
+--- sqlite-1.0.3/tests/sqlite_last_error_error.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_last_error_error.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,47 @@
++--TEST--
++Test sqlite_last_error() function : error conditions 
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
++--FILE--
++<?php
++/* Prototype  : int sqlite_last_error(resource db)
++ * Description: Returns the error code of the last error for a database. 
++ * Source code: ext/sqlite/sqlite.c
++ * Alias to functions: 
++ */
++
++echo "*** Testing sqlite_last_error() : error conditions ***\n";
++
++// Zero arguments
++echo "\n-- Testing sqlite_last_error() function with Zero arguments --\n";
++var_dump( sqlite_last_error() );
++
++//Test sqlite_last_error with one more than the expected number of arguments
++echo "\n-- Testing sqlite_last_error() function with more than expected no. of arguments --\n";
++
++$db = sqlite_open(':memory:');
++$extra_arg = 10;
++var_dump( sqlite_last_error($db, $extra_arg) );
++sqlite_close($db);
++
++$db = new SQLiteDatabase(':memory:');
++var_dump( $db->lastError($extra_arg) );
++
++?>
++===DONE===
++--EXPECTF--
++*** Testing sqlite_last_error() : error conditions ***
++
++-- Testing sqlite_last_error() function with Zero arguments --
++
++Warning: sqlite_last_error() expects exactly 1 parameter, 0 given in %s on line %d
++NULL
++
++-- Testing sqlite_last_error() function with more than expected no. of arguments --
++
++Warning: sqlite_last_error() expects exactly 1 parameter, 2 given in %s on line %d
++NULL
++
++Warning: SQLiteDatabase::lastError() expects exactly 0 parameters, 1 given in %s on line %d
++NULL
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_001.phpt sqlite-svn/tests/sqlite_oo_001.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_001.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_001.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,17 @@
++--TEST--
++sqlite-oo: sqlite_open/close
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++require_once('blankdb_oo.inc');
++var_dump($db);
++$db = NULL;
++echo "Done\n";
++?>
++--EXPECTF--
++object(SQLiteDatabase)#%d (0) {
++}
++Done
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_002.phpt sqlite-svn/tests/sqlite_oo_002.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_002.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_002.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,41 @@
++--TEST--
++sqlite-oo: Simple insert/select
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++require_once('blankdb_oo.inc');
++var_dump($db);
++
++var_dump($db->query("CREATE TABLE foo(c1 date, c2 time, c3 varchar(64))"));
++var_dump($db->query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)"));
++$r = $db->query("SELECT * from foo");
++var_dump($r);
++var_dump($r->fetch());
++?>
++--EXPECTF--
++object(SQLiteDatabase)#%d (0) {
++}
++object(SQLiteResult)#%d (0) {
++}
++object(SQLiteResult)#%d (0) {
++}
++object(SQLiteResult)#%d (0) {
++}
++array(6) {
++  [0]=>
++  string(10) "2002-01-02"
++  ["c1"]=>
++  string(10) "2002-01-02"
++  [1]=>
++  string(8) "12:49:00"
++  ["c2"]=>
++  string(8) "12:49:00"
++  [2]=>
++  NULL
++  ["c3"]=>
++  NULL
++}
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_003.phpt sqlite-svn/tests/sqlite_oo_003.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_003.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_003.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,51 @@
++--TEST--
++sqlite-oo: Simple insert/select, different result representation
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE foo(c1 date, c2 time, c3 varchar(64))");
++$db->query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)");
++$r = $db->query("SELECT * from foo");
++var_dump($r->fetch(SQLITE_BOTH));
++$r = $db->query("SELECT * from foo");
++var_dump($r->fetch(SQLITE_NUM));
++$r = $db->query("SELECT * from foo");
++var_dump($r->fetch(SQLITE_ASSOC));
++?>
++--EXPECT--
++array(6) {
++  [0]=>
++  string(10) "2002-01-02"
++  ["c1"]=>
++  string(10) "2002-01-02"
++  [1]=>
++  string(8) "12:49:00"
++  ["c2"]=>
++  string(8) "12:49:00"
++  [2]=>
++  NULL
++  ["c3"]=>
++  NULL
++}
++array(3) {
++  [0]=>
++  string(10) "2002-01-02"
++  [1]=>
++  string(8) "12:49:00"
++  [2]=>
++  NULL
++}
++array(3) {
++  ["c1"]=>
++  string(10) "2002-01-02"
++  ["c2"]=>
++  string(8) "12:49:00"
++  ["c3"]=>
++  NULL
++}
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_008.phpt sqlite-svn/tests/sqlite_oo_008.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_008.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_008.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,43 @@
++--TEST--
++sqlite-oo: fetch all (buffered)
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++$r = $db->query("SELECT a from strings");
++while ($row = $r->fetch(SQLITE_NUM)) {
++	var_dump($row);
++}
++echo "DONE!\n";
++?>
++--EXPECT--
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_009.phpt sqlite-svn/tests/sqlite_oo_009.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_009.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_009.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,43 @@
++--TEST--
++sqlite-oo: fetch all (unbuffered)
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++$r = $db->unbufferedQuery("SELECT a from strings");
++while ($row = $r->fetch(SQLITE_NUM)) {
++	var_dump($row);
++}
++echo "DONE!\n";
++?>
++--EXPECT--
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_010.phpt sqlite-svn/tests/sqlite_oo_010.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_010.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_010.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,44 @@
++--TEST--
++sqlite-oo: fetch all (iterator)
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
++while ($row = $r->valid()) {
++	var_dump($r->current());
++	$r->next();
++}
++echo "DONE!\n";
++?>
++--EXPECT--
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_011.phpt sqlite-svn/tests/sqlite_oo_011.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_011.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_011.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,33 @@
++--TEST--
++sqlite-oo: returned associative column names
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE foo (c1 char, c2 char, c3 char)");
++$db->query("CREATE TABLE bar (c1 char, c2 char, c3 char)");
++$db->query("INSERT INTO foo VALUES ('1', '2', '3')");
++$db->query("INSERT INTO bar VALUES ('4', '5', '6')");
++$r = $db->query("SELECT * from foo, bar", SQLITE_ASSOC);
++var_dump($r->fetch());
++?>
++--EXPECT--
++array(6) {
++  ["foo.c1"]=>
++  string(1) "1"
++  ["foo.c2"]=>
++  string(1) "2"
++  ["foo.c3"]=>
++  string(1) "3"
++  ["bar.c1"]=>
++  string(1) "4"
++  ["bar.c2"]=>
++  string(1) "5"
++  ["bar.c3"]=>
++  string(1) "6"
++}
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_012.phpt sqlite-svn/tests/sqlite_oo_012.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_012.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_012.phpt	2012-10-09 13:36:42.721252390 +0000
+@@ -0,0 +1,35 @@
++--TEST--
++sqlite-oo: read field names
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE strings(foo VARCHAR, bar VARCHAR, baz VARCHAR)");
++
++echo "Buffered\n";
++$r = $db->query("SELECT * from strings");
++for($i=0; $i<$r->numFields(); $i++) {
++	var_dump($r->fieldName($i));
++}
++echo "Unbuffered\n";
++$r = $db->unbufferedQuery("SELECT * from strings");
++for($i=0; $i<$r->numFields(); $i++) {
++	var_dump($r->fieldName($i));
++}
++echo "DONE!\n";
++?>
++--EXPECT--
++Buffered
++string(3) "foo"
++string(3) "bar"
++string(3) "baz"
++Unbuffered
++string(3) "foo"
++string(3) "bar"
++string(3) "baz"
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_013.phpt sqlite-svn/tests/sqlite_oo_013.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_013.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_013.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,75 @@
++--TEST--
++sqlite-oo: fetch column
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	array (0 => 'one', 1 => 'two'),
++	array (0 => 'three', 1 => 'four')
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR, b VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')");
++}
++
++echo "====BUFFERED====\n";
++$r = $db->query("SELECT a, b from strings");
++while ($r->valid()) {
++	var_dump($r->current(SQLITE_NUM));
++	var_dump($r->column(0));
++	var_dump($r->column(1));
++	var_dump($r->column('a'));
++	var_dump($r->column('b'));
++	$r->next();
++}
++echo "====UNBUFFERED====\n";
++$r = $db->unbufferedQuery("SELECT a, b from strings");
++while ($r->valid()) {
++	var_dump($r->column(0));
++	var_dump($r->column('b'));
++	var_dump($r->column(1));
++	var_dump($r->column('a'));
++	$r->next();
++}
++echo "DONE!\n";
++?>
++--EXPECT--
++====BUFFERED====
++array(2) {
++  [0]=>
++  string(3) "one"
++  [1]=>
++  string(3) "two"
++}
++string(3) "one"
++string(3) "two"
++string(3) "one"
++string(3) "two"
++array(2) {
++  [0]=>
++  string(5) "three"
++  [1]=>
++  string(4) "four"
++}
++string(5) "three"
++string(4) "four"
++string(5) "three"
++string(4) "four"
++====UNBUFFERED====
++string(3) "one"
++string(3) "two"
++NULL
++NULL
++string(5) "three"
++string(4) "four"
++NULL
++NULL
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_014.phpt sqlite-svn/tests/sqlite_oo_014.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_014.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_014.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,118 @@
++--TEST--
++sqlite-oo: fetch all
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++echo "unbuffered twice\n";
++$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
++var_dump($r->fetchAll());
++var_dump($r->fetchAll());
++
++echo "unbuffered with fetch_array\n";
++$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
++var_dump($r->fetch());
++var_dump($r->fetchAll());
++
++echo "buffered\n";
++$r = $db->query("SELECT a from strings", SQLITE_NUM);
++var_dump($r->fetchAll());
++var_dump($r->fetch());
++var_dump($r->fetchAll());
++
++echo "DONE!\n";
++?>
++--EXPECTF--
++unbuffered twice
++array(3) {
++  [0]=>
++  array(1) {
++    [0]=>
++    string(3) "one"
++  }
++  [1]=>
++  array(1) {
++    [0]=>
++    string(3) "two"
++  }
++  [2]=>
++  array(1) {
++    [0]=>
++    string(5) "three"
++  }
++}
++
++Warning: SQLiteUnbuffered::fetchAll(): One or more rowsets were already returned; returning NULL this time in %ssqlite_oo_014.php on line %d
++array(0) {
++}
++unbuffered with fetch_array
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(2) {
++  [0]=>
++  array(1) {
++    [0]=>
++    string(3) "two"
++  }
++  [1]=>
++  array(1) {
++    [0]=>
++    string(5) "three"
++  }
++}
++buffered
++array(3) {
++  [0]=>
++  array(1) {
++    [0]=>
++    string(3) "one"
++  }
++  [1]=>
++  array(1) {
++    [0]=>
++    string(3) "two"
++  }
++  [2]=>
++  array(1) {
++    [0]=>
++    string(5) "three"
++  }
++}
++bool(false)
++array(3) {
++  [0]=>
++  array(1) {
++    [0]=>
++    string(3) "one"
++  }
++  [1]=>
++  array(1) {
++    [0]=>
++    string(3) "two"
++  }
++  [2]=>
++  array(1) {
++    [0]=>
++    string(5) "three"
++  }
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_015.phpt sqlite-svn/tests/sqlite_oo_015.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_015.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_015.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,47 @@
++--TEST--
++sqlite-oo: array_query
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++$res = $db->arrayQuery("SELECT a from strings", SQLITE_NUM);
++var_dump($res);
++
++echo "DONE!\n";
++?>
++--EXPECTF--
++array(3) {
++  [0]=>
++  array(1) {
++    [0]=>
++    string(3) "one"
++  }
++  [1]=>
++  array(1) {
++    [0]=>
++    string(3) "two"
++  }
++  [2]=>
++  array(1) {
++    [0]=>
++    string(5) "three"
++  }
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_016.phpt sqlite-svn/tests/sqlite_oo_016.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_016.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_016.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,42 @@
++--TEST--
++sqlite-oo: fetch single
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	array (0 => 'one', 1 => 'two'),
++	array (0 => 'three', 1 => 'four')
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR, b VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')");
++}
++
++echo "====BUFFERED====\n";
++$r = $db->query("SELECT a, b from strings");
++while ($r->valid()) {
++	var_dump($r->fetchSingle());
++}
++echo "====UNBUFFERED====\n";
++$r = $db->unbufferedQuery("SELECT a, b from strings");
++while ($r->valid()) {
++	var_dump($r->fetchSingle());
++}
++echo "DONE!\n";
++?>
++--EXPECT--
++====BUFFERED====
++string(3) "one"
++string(5) "three"
++====UNBUFFERED====
++string(3) "one"
++string(5) "three"
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_020.phpt sqlite-svn/tests/sqlite_oo_020.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_020.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_020.phpt	2012-10-09 13:36:42.721252390 +0000
+@@ -0,0 +1,66 @@
++--TEST--
++sqlite-oo: factory and exception
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++$dbname = tempnam(dirname(__FILE__), "phpsql");
++function cleanup() {
++	global $db, $dbname;
++
++	$db = NULL;
++	unlink($dbname);
++}
++register_shutdown_function("cleanup");
++
++try {
++	$db = sqlite_factory();
++} catch(SQLiteException $err) {
++	echo "Message: ".$err->getMessage()."\n";
++	echo "File: ".$err->getFile()."\n";
++	//echo "Line: ".$err->getLine()."\n";
++	//print_r($err->getTrace());
++	//echo "BackTrace: ".$err->getTraceAsString()."\n";
++}
++
++$db = sqlite_factory($dbname);
++
++$data = array(
++	array (0 => 'one', 1 => 'two'),
++	array (0 => 'three', 1 => 'four')
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR, b VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')");
++}
++
++$r = $db->unbufferedQuery("SELECT a, b from strings");
++while ($r->valid()) {
++	var_dump($r->current(SQLITE_NUM));
++	$r->next();
++}
++$r = null;
++$db = null;
++echo "DONE!\n";
++?>
++--EXPECTF--
++Message: sqlite_factory() expects at least 1 parameter, 0 given
++File: %ssqlite_oo_020.php
++array(2) {
++  [0]=>
++  string(3) "one"
++  [1]=>
++  string(3) "two"
++}
++array(2) {
++  [0]=>
++  string(5) "three"
++  [1]=>
++  string(4) "four"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_021.phpt sqlite-svn/tests/sqlite_oo_021.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_021.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_021.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,48 @@
++--TEST--
++sqlite-oo: single query
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE test_db ( id INTEGER PRIMARY KEY, data VARCHAR(100) )");
++for ($i = 0; $i < 10; $i++) {
++	$db->query("INSERT INTO test_db (data) VALUES('{$i}data')");
++}
++$db->query("INSERT INTO test_db (data) VALUES(NULL)");
++
++var_dump($db->singleQuery("SELECT id FROM test_db WHERE id=5"));
++var_dump($db->singleQuery("SELECT * FROM test_db WHERE id=4"));
++var_dump($db->singleQuery("SELECT data FROM test_db WHERE id=6"));
++var_dump($db->singleQuery("SELECT * FROM test_db WHERE id < 5"));
++var_dump($db->singleQuery("SELECT * FROM test db WHERE id < 4"));
++var_dump($db->singleQuery("SELECT * FROM test_db WHERE id=999999"));
++var_dump($db->singleQuery("SELECT id FROM test_db WHERE id=5", FALSE));
++
++echo "DONE!\n";
++?>
++--EXPECTF--
++string(1) "5"
++string(1) "4"
++string(5) "5data"
++array(4) {
++  [0]=>
++  string(1) "1"
++  [1]=>
++  string(1) "2"
++  [2]=>
++  string(1) "3"
++  [3]=>
++  string(1) "4"
++}
++
++Warning: SQLiteDatabase::singleQuery(): no such table: test in %s on line %d
++bool(false)
++NULL
++array(1) {
++  [0]=>
++  string(1) "5"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_022.phpt sqlite-svn/tests/sqlite_oo_022.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_022.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_022.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,98 @@
++--TEST--
++sqlite-oo: sqlite::seek
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++$res = $db->query("SELECT a FROM strings", SQLITE_NUM);
++for ($idx = -1; $idx < 4; $idx++) {
++	echo "====SEEK:$idx====\n";
++	$res->seek($idx);
++	var_dump($res->current());
++}
++echo "====AGAIN====\n";
++for ($idx = -1; $idx < 4; $idx++) {
++	echo "====SEEK:$idx====\n";
++	$res->seek($idx);
++	var_dump($res->current());
++}
++echo "====DONE!====\n";
++?>
++--EXPECTF--
++====SEEK:-1====
++
++Warning: SQLiteResult::seek(): row -1 out of range in %ssqlite_oo_022.php on line %d
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++====SEEK:0====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++====SEEK:1====
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++====SEEK:2====
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====SEEK:3====
++
++Warning: SQLiteResult::seek(): row 3 out of range in %ssqlite_oo_022.php on line %d
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====AGAIN====
++====SEEK:-1====
++
++Warning: SQLiteResult::seek(): row -1 out of range in %ssqlite_oo_022.php on line %d
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====SEEK:0====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++====SEEK:1====
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++====SEEK:2====
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====SEEK:3====
++
++Warning: SQLiteResult::seek(): row 3 out of range in %ssqlite_oo_022.php on line %d
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====DONE!====
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_024.phpt sqlite-svn/tests/sqlite_oo_024.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_024.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_024.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,74 @@
++--TEST--
++sqlite-oo: sqlite::fetch_object
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++class class24 {
++	function __construct() {
++		echo __METHOD__ . "\n";
++	}
++}
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++echo "====class24====\n";
++$res = $db->query("SELECT a FROM strings", SQLITE_ASSOC);
++while ($res->valid()) {
++	var_dump($res->fetchObject('class24'));
++}
++
++echo "====stdclass====\n";
++$res = $db->query("SELECT a FROM strings", SQLITE_ASSOC);
++while ($res->valid()) {
++	var_dump($res->fetchObject());
++}
++
++echo "====DONE!====\n";
++?>
++--EXPECTF--
++====class24====
++class24::__construct
++object(class24)#%d (1) {
++  ["a"]=>
++  string(3) "one"
++}
++class24::__construct
++object(class24)#%d (1) {
++  ["a"]=>
++  string(3) "two"
++}
++class24::__construct
++object(class24)#%d (1) {
++  ["a"]=>
++  string(5) "three"
++}
++====stdclass====
++object(stdClass)#%d (1) {
++  ["a"]=>
++  string(3) "one"
++}
++object(stdClass)#%d (1) {
++  ["a"]=>
++  string(3) "two"
++}
++object(stdClass)#%d (1) {
++  ["a"]=>
++  string(5) "three"
++}
++====DONE!====
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_025.phpt sqlite-svn/tests/sqlite_oo_025.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_025.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_025.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,103 @@
++--TEST--
++sqlite-oo: sqlite / foreach
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++echo "====UNBUFFERED====\n";
++$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
++//var_dump(class_implements($r));
++foreach($r as $row) {
++	var_dump($row);
++}
++echo "====NO-MORE====\n";
++foreach($r as $row) {
++	var_dump($row);
++}
++echo "====DIRECT====\n";
++foreach($db->unbufferedQuery("SELECT a from strings", SQLITE_NUM) as $row) {
++	var_dump($row);
++}
++echo "====BUFFERED====\n";
++$r = $db->query("SELECT a from strings", SQLITE_NUM);
++//var_dump(class_implements($r));
++foreach($r as $row) {
++	var_dump($row);
++}
++foreach($r as $row) {
++	var_dump($row);
++}
++echo "DONE!\n";
++?>
++--EXPECT--
++====UNBUFFERED====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====NO-MORE====
++====DIRECT====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++====BUFFERED====
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++array(1) {
++  [0]=>
++  string(3) "one"
++}
++array(1) {
++  [0]=>
++  string(3) "two"
++}
++array(1) {
++  [0]=>
++  string(5) "three"
++}
++DONE!
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_026.phpt sqlite-svn/tests/sqlite_oo_026.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_026.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_026.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,56 @@
++--TEST--
++sqlite-oo: unbuffered
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array(
++	"one",
++	"two",
++	"three"
++	);
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++}
++
++echo "====FOREACH====\n";
++$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
++foreach($r as $idx => $row) {
++	var_dump($row[0]);
++	var_dump($row[0]);
++}
++echo "====FOR====\n";
++$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
++for(;$r->valid(); $r->next()) {
++	$v = $r->column(0);
++	var_dump($v);
++	$c = $r->column(0);
++	var_dump(is_null($c) || $c==$v);
++}
++echo "===DONE===\n";
++?>
++--EXPECT--
++====FOREACH====
++string(3) "one"
++string(3) "one"
++string(3) "two"
++string(3) "two"
++string(5) "three"
++string(5) "three"
++====FOR====
++string(3) "one"
++bool(true)
++string(3) "two"
++bool(true)
++string(5) "three"
++bool(true)
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_027.phpt sqlite-svn/tests/sqlite_oo_027.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_027.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_027.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,42 @@
++--TEST--
++sqlite-oo: changes
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$data = array("one", "two", "three");
++
++$db->query("CREATE TABLE strings(a VARCHAR)");
++
++foreach ($data as $str) {
++	$db->query("INSERT INTO strings VALUES('$str')");
++	echo $db->changes() . "\n";
++}
++
++$db->query("UPDATE strings SET a='foo' WHERE a!='two'");
++echo $db->changes() . "\n";
++
++$db->query("DELETE FROM strings WHERE 1");
++echo $db->changes() . "\n";
++
++$str = '';
++foreach ($data as $s) {
++	$str .= "INSERT INTO strings VALUES('".$s."');";
++}
++$db->query($str);
++echo $db->changes() . "\n";
++
++?>
++--EXPECT--
++1
++1
++1
++2
++3
++3
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_028.phpt sqlite-svn/tests/sqlite_oo_028.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_028.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_028.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,25 @@
++--TEST--
++sqlite-oo: sqlite_fetch_column_types
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php 
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE strings(a, b INTEGER, c VARCHAR(10), d)");
++$db->query("INSERT INTO strings VALUES('1', '2', '3', 'abc')");
++
++var_dump($db->fetchColumnTypes("strings"));
++?>
++--EXPECT--
++array(4) {
++  ["a"]=>
++  string(0) ""
++  ["b"]=>
++  string(7) "INTEGER"
++  ["c"]=>
++  string(11) "VARCHAR(10)"
++  ["d"]=>
++  string(0) ""
++}
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_029.phpt sqlite-svn/tests/sqlite_oo_029.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_029.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_029.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,53 @@
++--TEST--
++sqlite-oo: call method with $this
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++?>
++--FILE--
++<?php
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE strings(key VARCHAR(10), var VARCHAR(10))");
++$db->query("INSERT INTO strings VALUES('foo', 'foo')");
++
++class sqlite_help
++{
++	function __construct($db){
++		$this->db = $db;
++		$this->db->createFunction('link_keywords', array(&$this, 'linkers'), 1);
++	}
++
++	function getSingle($key)
++	{
++		return $this->db->singleQuery('SELECT link_keywords(var) FROM strings WHERE key=\''.$key.'\'', 1);
++	}
++
++	function linkers($str)
++	{
++		$str = str_replace('foo', 'bar', $str);
++		return $str;
++	}
++
++	function free()
++	{
++		unset($this->db);
++	}
++
++	function __destruct()
++	{
++		echo "DESTRUCTED\n";
++	}
++}
++
++$obj = new sqlite_help($db);
++echo $obj->getSingle('foo')."\n";
++$obj->free();
++unset($obj);
++
++?>
++===DONE===
++--EXPECT--
++bar
++===DONE===
++DESTRUCTED
+diff -dPNur sqlite-1.0.3/tests/sqlite_oo_030.phpt sqlite-svn/tests/sqlite_oo_030.phpt
+--- sqlite-1.0.3/tests/sqlite_oo_030.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_oo_030.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,44 @@
++--TEST--
++sqlite-oo: calling static methods
++--INI--
++sqlite.assoc_case=0
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++?>
++--FILE--
++<?php
++
++require_once('blankdb_oo.inc'); 
++
++class foo {
++    static function bar($param = NULL) {
++		return $param;
++    }
++}
++
++function baz($param = NULL) {
++	return $param;
++}
++
++var_dump($db->singleQuery("select php('baz')", 1));
++var_dump($db->singleQuery("select php('baz', 1)", 1));
++var_dump($db->singleQuery("select php('baz', \"PHP\")", 1));
++var_dump($db->singleQuery("select php('foo::bar')", 1));
++var_dump($db->singleQuery("select php('foo::bar', 1)", 1));
++var_dump($db->singleQuery("select php('foo::bar', \"PHP\")", 1));
++var_dump($db->singleQuery("select php('foo::bar(\"PHP\")')", 1));
++
++?>
++===DONE===
++--EXPECTF--
++NULL
++string(1) "1"
++string(3) "PHP"
++NULL
++string(1) "1"
++string(3) "PHP"
++
++Warning: SQLiteDatabase::singleQuery(): function `foo::bar("PHP")' is not a function name in %ssqlite_oo_030.php on line %d
++bool(false)
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_popen_basic.phpt sqlite-svn/tests/sqlite_popen_basic.phpt
+--- sqlite-1.0.3/tests/sqlite_popen_basic.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_popen_basic.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,27 @@
++--TEST--
++SQLite: sqlite_popen() basic tests
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip"; ?>
++--FILE--
++<?php
++/* Prototype  : resource sqlite_popen(string filename [, int mode [, string &error_message]])
++ * Description: Opens a persistent handle to a SQLite database. Will create the database if it does not exist.
++ * Source code: ext/sqlite/sqlite.c
++ * Alias to functions:
++*/
++
++	$db1 = sqlite_popen(":memory:");
++	$db2 = sqlite_popen(":memory:");
++
++	var_dump($db1);
++	var_dump($db2);
++
++	list($resourceId1) = sscanf((string) $db1, "resource(%d) of type (sqlite database (persistent))");
++	list($resourceId2) = sscanf((string) $db2, "resource(%d) of type (sqlite database (persistent))");
++
++	var_dump($resourceId1 === $resourceId2);
++?>
++--EXPECTF--
++resource(%d) of type (sqlite database (persistent))
++resource(%d) of type (sqlite database (persistent))
++bool(true)
+diff -dPNur sqlite-1.0.3/tests/sqlite_popen_error.phpt sqlite-svn/tests/sqlite_popen_error.phpt
+--- sqlite-1.0.3/tests/sqlite_popen_error.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_popen_error.phpt	2012-10-09 13:36:42.721252390 +0000
+@@ -0,0 +1,34 @@
++--TEST--
++Test sqlite_popen() function : error conditions 
++--SKIPIF--
++<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
++--FILE--
++<?php
++/* Prototype  : resource sqlite_popen(string filename [, int mode [, string &error_message]])
++ * Description: Opens a persistent handle to a SQLite database. Will create the database if it does not exist. 
++ * Source code: ext/sqlite/sqlite.c
++ * Alias to functions: 
++ */
++
++$message = '';
++
++echo "*** Testing sqlite_popen() : error conditions ***\n";
++
++var_dump( sqlite_popen() );
++var_dump( sqlite_popen(":memory:", 0666, $message, 'foobar') );
++var_dump( sqlite_popen("", 0666, $message) );
++var_dump( $message );
++
++?>
++===DONE===
++--EXPECTF--
++*** Testing sqlite_popen() : error conditions ***
++
++Warning: sqlite_popen() expects at least 1 parameter, 0 given in %s on line %d
++NULL
++
++Warning: sqlite_popen() expects at most 3 parameters, 4 given in %s on line %d
++NULL
++bool(false)
++NULL
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_session_001.phpt sqlite-svn/tests/sqlite_session_001.phpt
+--- sqlite-1.0.3/tests/sqlite_session_001.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_session_001.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,46 @@
++--TEST--
++sqlite, session storage test
++--CREDITS--
++Mats Lindh <mats at lindh.no>
++#Testfest php.no
++--INI--
++session.save_handler = sqlite
++--SKIPIF--
++if (!extension_loaded("session"))
++{
++	die("skip Session module not loaded");
++}
++if (!extension_loaded("sqlite"))
++{
++	die("skip Session module not loaded");
++}
++--FILE--
++<?php
++/* Description: Tests that sqlite can be used as a session save handler
++* Source code: ext/sqlite/sess_sqlite.c
++*/
++
++ob_start();
++session_save_path(__DIR__ . "/sessiondb.sdb");
++
++// create the session and set a session value
++session_start();
++$_SESSION["test"] = "foo_bar";
++
++// close the session and unset the value
++session_write_close();
++unset($_SESSION["test"]);
++var_dump(isset($_SESSION["test"]));
++
++// start the session again and check that we have the proper value
++session_start();
++var_dump($_SESSION["test"]);
++ob_end_flush();
++?>
++--EXPECTF--
++bool(false)
++%unicode|string%(7) "foo_bar"
++--CLEAN--
++<?php
++	unlink(__DIR__ . "/sessiondb.sdb")
++?>
+diff -dPNur sqlite-1.0.3/tests/sqlite_session_002.phpt sqlite-svn/tests/sqlite_session_002.phpt
+--- sqlite-1.0.3/tests/sqlite_session_002.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_session_002.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,54 @@
++--TEST--
++sqlite, session destroy test
++--CREDITS--
++Mats Lindh <mats at lindh.no>
++#Testfest php.no
++--INI--
++session.save_handler = sqlite
++--SKIPIF--
++if (!extension_loaded("session"))
++{
++	die("skip Session module not loaded");
++}
++if (!extension_loaded("sqlite"))
++{
++	die("skip sqlite module not loaded");
++}
++--FILE--
++<?php
++/* Description: Tests that sqlite will destroy a session when used as a session handler
++* Source code: ext/sqlite/sess_sqlite.c
++*/
++ob_start();
++session_save_path(__DIR__ . "/sessiondb.sdb");
++
++// start a session and save a value to it before commiting the session to the database
++session_start();
++$_SESSION["test"] = "foo_bar";
++session_write_close();
++
++// remove the session value
++unset($_SESSION["test"]);
++var_dump(isset($_SESSION["test"]));
++
++// start the session again and destroy it
++session_start();
++var_dump($_SESSION["test"]);
++session_destroy();
++session_write_close();
++
++unset($_SESSION["test"]);
++
++// check that the session has been destroyed
++session_start();
++var_dump(isset($_SESSION["test"]));
++ob_end_flush();
++?>
++--EXPECTF--
++bool(false)
++%unicode|string%(7) "foo_bar"
++bool(false)
++--CLEAN--
++<?php
++	unlink(__DIR__ . "/sessiondb.sdb")
++?>
+diff -dPNur sqlite-1.0.3/tests/sqlite_spl_001.phpt sqlite-svn/tests/sqlite_spl_001.phpt
+--- sqlite-1.0.3/tests/sqlite_spl_001.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_spl_001.phpt	2012-10-09 13:36:42.730091166 +0000
+@@ -0,0 +1,125 @@
++--TEST--
++sqlite-spl: Iteration
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++if (!extension_loaded("spl")) print "skip SPL is not present"; 
++?>
++--FILE--
++<?php
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE menu(id_l int PRIMARY KEY, id_r int UNIQUE, key VARCHAR(10))");
++$db->query("INSERT INTO menu VALUES( 1, 12, 'A')"); 
++$db->query("INSERT INTO menu VALUES( 2,  9, 'B')"); 
++$db->query("INSERT INTO menu VALUES(10, 11, 'F')"); 
++$db->query("INSERT INTO menu VALUES( 3,  6, 'C')"); 
++$db->query("INSERT INTO menu VALUES( 7,  8, 'E')"); 
++$db->query("INSERT INTO menu VALUES( 4,  5, 'D')"); 
++
++class SqliteNestedsetElement
++{
++	protected $id_l;
++	protected $id_r;
++	protected $key;
++
++	function __construct($db)
++	{
++		$this->db = $db;
++	}
++	
++	function getLeft()
++	{
++		return $this->id_l;
++	}
++	
++	function getRight()
++	{
++		return $this->id_r;
++	}
++	
++	function __toString()
++	{
++		return $this->key;
++	}
++
++	function key()
++	{
++		return $this->key;
++	}
++}
++
++class SqliteNestedset implements RecursiveIterator
++{
++	protected $id;
++	protected $id_l;
++	protected $id_r;
++	protected $entry;
++
++	function __construct($db, $id_l = 1)
++	{
++		$this->db = $db;
++		$this->id_l = $id_l;
++		$this->id_r = $this->db->singleQuery('SELECT id_r FROM menu WHERE id_l='.$id_l, 1);
++		$this->id = $id_l;
++	}
++	
++	function rewind()
++	{
++		$this->id = $this->id_l;
++		$this->fetch();
++	}
++
++	function valid()
++	{
++		return is_object($this->entry);
++	}
++	
++	function current()
++	{
++		return $this->entry->__toString();
++	}
++	
++	function key()
++	{
++		return $this->entry->key();;
++	}
++	
++	function next()
++	{
++		$this->id = $this->entry->getRight() + 1;
++		$this->fetch();
++	}
++
++	protected function fetch()
++	{
++		$res = $this->db->unbufferedQuery('SELECT * FROM menu WHERE id_l='.$this->id);
++		$this->entry = $res->fetchObject('SqliteNestedsetElement', array(&$this->db));
++		unset($res);
++	}
++	
++	function hasChildren()
++	{
++		return $this->entry->getLeft() + 1 < $this->entry->getRight();
++	}
++	
++	function getChildren()
++	{
++		return new SqliteNestedset($this->db, $this->entry->getLeft() + 1, $this->entry->getRight() - 1);
++	}
++}
++
++$menu_iterator = new RecursiveIteratorIterator(new SqliteNestedset($db), RecursiveIteratorIterator::SELF_FIRST);
++foreach($menu_iterator as $entry) {
++	echo $menu_iterator->getDepth() . $entry . "\n";
++}
++?>
++===DONE===
++--EXPECT--
++0A
++1B
++2C
++3D
++2E
++1F
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_spl_002.phpt sqlite-svn/tests/sqlite_spl_002.phpt
+--- sqlite-1.0.3/tests/sqlite_spl_002.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_spl_002.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,29 @@
++--TEST--
++sqlite-spl: Countable
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++if (!extension_loaded("spl")) print "skip SPL is not present"; 
++?>
++--FILE--
++<?php
++include "blankdb_oo.inc";
++
++$db->query("CREATE TABLE menu(id_l int PRIMARY KEY, id_r int UNIQUE, key VARCHAR(10))");
++$db->query("INSERT INTO menu VALUES( 1, 12, 'A')"); 
++$db->query("INSERT INTO menu VALUES( 2,  9, 'B')"); 
++$db->query("INSERT INTO menu VALUES(10, 11, 'F')"); 
++$db->query("INSERT INTO menu VALUES( 3,  6, 'C')"); 
++$db->query("INSERT INTO menu VALUES( 7,  8, 'E')"); 
++$db->query("INSERT INTO menu VALUES( 4,  5, 'D')"); 
++
++$res = $db->query("SELECT * from menu");
++
++var_dump($res->count());
++var_dump(count($res));
++?>
++===DONE===
++--EXPECT--
++int(6)
++int(6)
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlite_spl_003.phpt sqlite-svn/tests/sqlite_spl_003.phpt
+--- sqlite-1.0.3/tests/sqlite_spl_003.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlite_spl_003.phpt	2012-10-09 13:36:42.740092676 +0000
+@@ -0,0 +1,28 @@
++--TEST--
++sqlite-spl: Exception
++--SKIPIF--
++<?php # vim:ft=php
++if (!extension_loaded("sqlite")) print "skip"; 
++if (!extension_loaded("spl")) print "skip SPL is not present"; 
++?>
++--FILE--
++<?php
++
++try
++{
++	$db = sqlite_factory();
++}
++catch(SQLiteException $e)
++{
++	$parents = class_parents($e);
++	if (array_key_exists('RuntimeException', $parents))
++	{
++		echo "GOOD\n";
++	}
++}
++
++?>
++===DONE===
++--EXPECT--
++GOOD
++===DONE===
+diff -dPNur sqlite-1.0.3/tests/sqlitedatabase_arrayquery.phpt sqlite-svn/tests/sqlitedatabase_arrayquery.phpt
+--- sqlite-1.0.3/tests/sqlitedatabase_arrayquery.phpt	1970-01-01 00:00:00.000000000 +0000
++++ sqlite-svn/tests/sqlitedatabase_arrayquery.phpt	2012-10-09 13:36:42.721252390 +0000
+@@ -0,0 +1,23 @@
++--TEST--
++Testing SQLiteDatabase::ArrayQuery with NULL-byte string
++--SKIPIF--
++<?php
++if (!extension_loaded("sqlite")) print "skip";
++?>
++--FILE--
++<?php
++
++$method = new ReflectionMethod('sqlitedatabase::arrayquery');
++
++$class = $method->getDeclaringClass()->newInstanceArgs(array(':memory:'));
++
++$p = "\0";
++
++$method->invokeArgs($class, array_fill(0, 2, $p));
++$method->invokeArgs($class, array_fill(0, 1, $p));
++
++?>
++--EXPECTF--
++Warning: SQLiteDatabase::arrayQuery() expects parameter 2 to be long, string given in %s on line %d
++
++Warning: SQLiteDatabase::arrayQuery(): Cannot execute empty query. in %s on line %d
-- 
cgit v1.2.3