diff options
Diffstat (limited to 'dev-php/pecl-sqlite/files/sqlite-svn.patch')
-rw-r--r-- | dev-php/pecl-sqlite/files/sqlite-svn.patch | 12200 |
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 |