summaryrefslogtreecommitdiffstats
path: root/dev-php/pecl-sqlite/files
diff options
context:
space:
mode:
Diffstat (limited to 'dev-php/pecl-sqlite/files')
-rw-r--r--dev-php/pecl-sqlite/files/sqlite-svn.patch12200
1 files changed, 12200 insertions, 0 deletions
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