From: Wez Furlong Date: Sun, 27 Feb 2005 05:20:19 +0000 (+0000) Subject: upgrade bundled sqlite to sqlite 3.1.3 X-Git-Tag: RELEASE_0_3~170 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae5649598dcbb3b3b105344452c782bf0f289739;p=php upgrade bundled sqlite to sqlite 3.1.3 --- diff --git a/ext/pdo_sqlite/config.m4 b/ext/pdo_sqlite/config.m4 index 90e986c0a6..ea319006a4 100644 --- a/ext/pdo_sqlite/config.m4 +++ b/ext/pdo_sqlite/config.m4 @@ -72,23 +72,27 @@ if test "$PHP_PDO_SQLITE" != "no"; then sqlite/src/table.c sqlite/src/tokenize.c \ sqlite/src/trigger.c sqlite/src/update.c sqlite/src/utf.c sqlite/src/util.c \ sqlite/src/vacuum.c sqlite/src/vdbeapi.c sqlite/src/vdbeaux.c sqlite/src/vdbe.c \ - sqlite/src/vdbemem.c sqlite/src/where.c sqlite/src/parse.c sqlite/src/opcodes.c" + sqlite/src/vdbemem.c sqlite/src/where.c sqlite/src/parse.c sqlite/src/opcodes.c \ + sqlite/src/alter.c sqlite/src/experimental.c" PHP_NEW_EXTENSION(pdo_sqlite, $php_pdo_sqlite_sources_core $pdo_sqlite_sources, - $ext_shared,,-I@ext_srcdir@/sqlite/src -DPDO_SQLITE_BUNDLED=1 -I$pdo_inc_path) + $ext_shared,,-I@ext_srcdir@/sqlite/src -DPDO_SQLITE_BUNDLED=1 -DSQLITE_OMIT_CURSOR -I$pdo_inc_path) PHP_ADD_BUILD_DIR($ext_builddir/sqlite) PHP_ADD_BUILD_DIR($ext_builddir/sqlite/src) AC_CHECK_SIZEOF(char *,4) AC_DEFINE(SQLITE_PTR_SZ, SIZEOF_CHAR_P, [Size of a pointer]) PDO_SQLITE_VERSION=`cat $ext_srcdir/sqlite/VERSION` - sed -e s/--VERS--/$PDO_SQLITE_VERSION/ $ext_srcdir/sqlite/src/sqlite.h.in > $ext_srcdir/sqlite3.h + PDO_SQLITE_VERSION_NUMBER=`echo $PDO_SQLITE_VERSION | awk -F. '{printf("%d%03d%03d", $1, $2, $3)}'` + sed -e s/--VERS--/$PDO_SQLITE_VERSION/ -e s/--VERSION-NUMBER--/$PDO_SQLITE_VERSION_NUMBER/ $ext_srcdir/sqlite/src/sqlite.h.in > $ext_srcdir/sqlite3.h if ! test -f $ext_srcdir/sqlite/src/parse.h ; then $CC -o $ext_srcdir/sqlite/tool/lemon $ext_srcdir/sqlite/tool/lemon.c $ext_srcdir/sqlite/tool/lemon $ext_srcdir/sqlite/src/parse.y cat $ext_srcdir/sqlite/src/parse.h $ext_srcdir/sqlite/src/vdbe.c | awk -f $ext_srcdir/sqlite/mkopcodeh.awk > $ext_srcdir/sqlite/src/opcodes.h sort -n +2 $ext_srcdir/sqlite/src/opcodes.h | awk -f $ext_srcdir/sqlite/mkopcodec.awk > $ext_srcdir/sqlite/src/opcodes.c + $CC -o $ext_srcdir/sqlite/tool/mkkeywordhash $ext_srcdir/sqlite/tool/mkkeywordhash.c + $ext_srcdir/sqlite/tool/mkkeywordhash > $ext_srcdir/keywordhash.h fi if test "$ext_shared" = "no" -o "$ext_srcdir" != "$abs_srcdir"; then diff --git a/ext/pdo_sqlite/package.xml b/ext/pdo_sqlite/package.xml index 97bf1c8415..9f86503d93 100755 --- a/ext/pdo_sqlite/package.xml +++ b/ext/pdo_sqlite/package.xml @@ -72,8 +72,10 @@ + + @@ -81,6 +83,7 @@ + diff --git a/ext/pdo_sqlite/sqlite/Makefile.in b/ext/pdo_sqlite/sqlite/Makefile.in index 3136476bcf..198a7877c1 100644 --- a/ext/pdo_sqlite/sqlite/Makefile.in +++ b/ext/pdo_sqlite/sqlite/Makefile.in @@ -26,29 +26,21 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ # will run on the target platform. (BCC and TCC are usually the # same unless your are cross-compiling.) # -TCC = @TARGET_CC@ @TARGET_CFLAGS@ -I. -I${TOP}/src -DNDEBUG +TCC = @TARGET_CC@ @TARGET_CFLAGS@ -I. -I${TOP}/src -# Some standard variables and programs +# Define -DNDEBUG to compile without debugging (i.e., for production usage) +# Omitting the define will cause extra debugging code to be inserted and +# includes extra comments when "EXPLAIN stmt" is used. # -prefix = @prefix@ -exec_prefix = @exec_prefix@ -libdir = @libdir@ -INSTALL = @INSTALL@ -LIBTOOL = ./libtool -RELEASE = @ALLOWRELEASE@ - -# libtool compile/link/install -LTCOMPILE = $(LIBTOOL) --mode=compile $(TCC) -LTLINK = $(LIBTOOL) --mode=link $(TCC) -LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) +TCC += @TARGET_DEBUG@ # Compiler options needed for programs that use the TCL library. # -TCL_FLAGS = @TARGET_TCL_INC@ +TCC += @TCL_INCLUDE_SPEC@ # The library that programs using TCL must link against. # -LIBTCL = @TARGET_TCL_LIBS@ +LIBTCL = @TCL_LIB_SPEC@ @TCL_LIBS@ # Compiler options needed for programs that use the readline() library. # @@ -74,22 +66,64 @@ LIBPTHREAD=@TARGET_THREAD_LIB@ # TEMP_STORE = -DTEMP_STORE=@TEMP_STORE@ +# Version numbers and release number for the SQLite being compiled. +# +VERSION = @VERSION@ +VERSION_NUMBER = @VERSION_NUMBER@ +RELEASE = @RELEASE@ + +# Filename extensions +# +BEXE = @BUILD_EXEEXT@ +TEXE = @TARGET_EXEEXT@ + +# The following variable is "1" if the configure script was able to locate +# the tclConfig.sh file. It is an empty string otherwise. When this +# variable is "1", the TCL extension library (libtclsqlite3.so) is built +# and installed. +# +HAVE_TCL = @HAVE_TCL@ + +# The suffix used on shared libraries. Ex: ".dll", ".so", ".dylib" +# +SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ + +# The directory into which to store package information for + +# Some standard variables and programs +# +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +INSTALL = @INSTALL@ +LIBTOOL = ./libtool +ALLOWRELEASE = @ALLOWRELEASE@ + +# libtool compile/link/install +LTCOMPILE = $(LIBTOOL) --mode=compile $(TCC) +LTLINK = $(LIBTOOL) --mode=link $(TCC) +LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) + # You should not have to change anything below this line ############################################################################### +OPTS += -DSQLITE_OMIT_CURSOR # Cursors do not work at this time +TCC += -DSQLITE_OMIT_CURSOR + # Object files for the SQLite library. # -LIBOBJ = attach.lo auth.lo btree.lo build.lo date.lo delete.lo \ - expr.lo func.lo hash.lo insert.lo \ - main.lo opcodes.lo os_mac.lo os_unix.lo os_win.lo \ +LIBOBJ = alter.lo attach.lo auth.lo btree.lo build.lo date.lo \ + delete.lo expr.lo func.lo hash.lo insert.lo \ + main.lo opcodes.lo os_unix.lo os_win.lo \ pager.lo parse.lo pragma.lo printf.lo random.lo \ - select.lo table.lo tokenize.lo trigger.lo update.lo util.lo vacuum.lo \ - vdbe.lo vdbeapi.lo vdbeaux.lo vdbemem.lo \ + select.lo table.lo tokenize.lo trigger.lo update.lo \ + util.lo vacuum.lo vdbe.lo vdbeapi.lo vdbeaux.lo vdbemem.lo \ where.lo utf.lo legacy.lo # All of the source code files. # SRC = \ + $(TOP)/src/alter.c \ $(TOP)/src/attach.c \ $(TOP)/src/auth.c \ $(TOP)/src/btree.c \ @@ -104,7 +138,6 @@ SRC = \ $(TOP)/src/insert.c \ $(TOP)/src/legacy.c \ $(TOP)/src/main.c \ - $(TOP)/src/os_mac.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ @@ -137,8 +170,8 @@ SRC = \ # TESTSRC = \ $(TOP)/src/btree.c \ + $(TOP)/src/date.c \ $(TOP)/src/func.c \ - $(TOP)/src/os_mac.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ @@ -164,7 +197,6 @@ HDR = \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ - $(TOP)/src/os_mac.h \ $(TOP)/src/os_unix.h \ $(TOP)/src/os_win.h \ $(TOP)/src/sqliteInt.h \ @@ -180,7 +212,7 @@ VDBEHDR = \ # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # -all: sqlite3.h libsqlite3.la sqlite3@TARGET_EXEEXT@ +all: sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la) Makefile: $(TOP)/Makefile.in ./config.status @@ -194,14 +226,15 @@ last_change: $(SRC) libsqlite3.la: $(LIBOBJ) $(LTLINK) -o libsqlite3.la $(LIBOBJ) $(LIBPTHREAD) \ - ${RELEASE} -rpath $(libdir) -version-info "8:6:8" + ${ALLOWRELEASE} -rpath $(libdir) -version-info "8:6:8" libtclsqlite3.la: tclsqlite.lo libsqlite3.la $(LTLINK) -o libtclsqlite3.la tclsqlite.lo \ - libsqlite3.la $(LIBTCL) $(LIBPTHREAD) -rpath $(libdir)/sqlite \ + $(LIBOBJ) @TCL_STUB_LIB_SPEC@ $(LIBPTHREAD) \ + -rpath $(libdir)/sqlite \ -version-info "8:6:8" -sqlite3@TARGET_EXEEXT@: $(TOP)/src/shell.c libsqlite3.la sqlite3.h +sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h $(LTLINK) $(READLINE_FLAGS) $(LIBPTHREAD) \ -o sqlite3 $(TOP)/src/shell.c libsqlite3.la $(LIBREADLINE) @@ -211,23 +244,26 @@ sqlite3@TARGET_EXEEXT@: $(TOP)/src/shell.c libsqlite3.la sqlite3.h # files are automatically generated. This target takes care of # all that automatic generation. # -target_source: $(SRC) $(VDBEHDR) +target_source: $(SRC) parse.c opcodes.c keywordhash.h $(VDBEHDR) rm -rf tsrc mkdir -p tsrc cp $(SRC) $(VDBEHDR) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - cp parse.c opcodes.c tsrc + cp parse.c opcodes.c keywordhash.h tsrc cp $(TOP)/sqlite3.def tsrc # Rules to build the LEMON compiler generator # -lemon@BUILD_EXEEXT@: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c +lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o lemon $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . # Rules to build individual files # +alter.lo: $(TOP)/src/alter.c $(HDR) + $(LTCOMPILE) -c $(TOP)/src/alter.c + attach.lo: $(TOP)/src/attach.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/attach.c @@ -287,14 +323,11 @@ opcodes.lo: opcodes.c $(LTCOMPILE) -c opcodes.c opcodes.c: opcodes.h $(TOP)/mkopcodec.awk - sort -n +2 opcodes.h | awk -f $(TOP)/mkopcodec.awk >opcodes.c + sort -n -b +2 opcodes.h | awk -f $(TOP)/mkopcodec.awk >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >opcodes.h -os_mac.lo: $(TOP)/src/os_mac.c $(HDR) - $(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_mac.c - os_unix.lo: $(TOP)/src/os_unix.c $(HDR) $(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_unix.c @@ -306,15 +339,15 @@ parse.lo: parse.c $(HDR) parse.h: parse.c -parse.c: $(TOP)/src/parse.y lemon@BUILD_EXEEXT@ +parse.c: $(TOP)/src/parse.y lemon$(BEXE) cp $(TOP)/src/parse.y . - ./lemon parse.y + ./lemon $(OPTS) parse.y pragma.lo: $(TOP)/src/pragma.c $(HDR) - $(LTCOMPILE) $(TCL_FLAGS) -c $(TOP)/src/pragma.c + $(LTCOMPILE) -c $(TOP)/src/pragma.c printf.lo: $(TOP)/src/printf.c $(HDR) - $(LTCOMPILE) $(TCL_FLAGS) -c $(TOP)/src/printf.c + $(LTCOMPILE) -c $(TOP)/src/printf.c random.lo: $(TOP)/src/random.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/random.c @@ -323,18 +356,22 @@ select.lo: $(TOP)/src/select.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/select.c sqlite3.h: $(TOP)/src/sqlite.h.in - sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \ - $(TOP)/src/sqlite.h.in >sqlite3.h + sed -e s/--VERS--/$(RELEASE)/ $(TOP)/src/sqlite.h.in | \ + sed -e s/--VERSION-NUMBER--/$(VERSION_NUMBER)/ >sqlite3.h table.lo: $(TOP)/src/table.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/table.c tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c + $(LTCOMPILE) -c $(TOP)/src/tclsqlite.c -tokenize.lo: $(TOP)/src/tokenize.c $(HDR) +tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR) $(LTCOMPILE) -c $(TOP)/src/tokenize.c +keywordhash.h: $(TOP)/tool/mkkeywordhash.c + $(BCC) -o mkkeywordhash$(BEXE) $(OPTS) $(TOP)/tool/mkkeywordhash.c + ./mkkeywordhash$(BEXE) >keywordhash.h + trigger.lo: $(TOP)/src/trigger.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/trigger.c @@ -365,33 +402,49 @@ vdbemem.lo: $(TOP)/src/vdbemem.c $(VDBEHDR) where.lo: $(TOP)/src/where.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/where.c -tclsqlite-sh.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) $(TCL_FLAGS) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c +tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) + $(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c + +tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR) + $(LTCOMPILE) -DTCL_USE_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c -tclsqlite3: tclsqlite-sh.lo libsqlite3.la - $(LTLINK) $(TCL_FLAGS) -o tclsqlite3 tclsqlite-sh.lo \ +tclsqlite3: tclsqlite-shell.lo libsqlite3.la + $(LTLINK) -o tclsqlite3 tclsqlite-shell.lo \ libsqlite3.la $(LIBTCL) -testfixture@TARGET_EXEEXT@: $(TOP)/src/tclsqlite.c libtclsqlite3.la libsqlite3.la $(TESTSRC) - $(LTLINK) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1\ +testfixture$(TEXE): $(TOP)/src/tclsqlite.c libtclsqlite3.la libsqlite3.la $(TESTSRC) + $(LTLINK) -DTCLSH=1 -DSQLITE_TEST=1\ $(THREADSAFE) $(TEMP_STORE)\ -o testfixture $(TESTSRC) $(TOP)/src/tclsqlite.c \ - libtclsqlite3.la libsqlite3.la $(LIBTCL) + libtclsqlite3.la $(LIBTCL) -crashtest@TARGET_EXEEXT@: $(TOP)/src/tclsqlite.c libsqlite3.la $(TESTSRC) $(TOP)/src/os_test.c - $(LTLINK) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 \ +crashtest$(TEXE): $(TOP)/src/tclsqlite.c libsqlite3.la $(TESTSRC) $(TOP)/src/os_test.c + $(LTLINK) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 \ -o crashtest \ $(TESTSRC) $(TOP)/src/os_test.c $(TOP)/src/tclsqlite.c \ libsqlite3.la $(LIBTCL) $(THREADLIB) -fulltest: testfixture@TARGET_EXEEXT@ sqlite3@TARGET_EXEEXT@ crashtest@TARGET_EXEEXT@ +fulltest: testfixture$(TEXE) sqlite3$(TEXE) crashtest$(TEXE) ./testfixture $(TOP)/test/all.test -test: testfixture@TARGET_EXEEXT@ sqlite3@TARGET_EXEEXT@ +test: testfixture$(TEXE) sqlite3$(TEXE) ./testfixture $(TOP)/test/quick.test +sqlite3_analyzer$(TEXE): $(TOP)/src/tclsqlite.c libtclsqlite3.la \ + $(TESTSRC) $(TOP)/tool/spaceanal.tcl + sed \ + -e '/^#/d' \ + -e 's,\\,\\\\,g' \ + -e 's,",\\",g' \ + -e 's,^,",' \ + -e 's,$$,\\n",' \ + $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h + $(LTLINK) -DTCLSH=2 -DSQLITE_TEST=1\ + $(THREADSAFE) $(TEMP_STORE)\ + -o sqlite3_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \ + libtclsqlite3.la $(LIBTCL) # Rules used to build documentation # @@ -401,6 +454,9 @@ arch.html: $(TOP)/www/arch.tcl arch2.gif: $(TOP)/www/arch2.gif cp $(TOP)/www/arch2.gif . +autoinc.html: $(TOP)/www/autoinc.tcl + tclsh $(TOP)/www/autoinc.tcl >autoinc.html + c_interface.html: $(TOP)/www/c_interface.tcl tclsh $(TOP)/www/c_interface.tcl >c_interface.html @@ -413,6 +469,9 @@ capi3ref.html: $(TOP)/www/capi3ref.tcl changes.html: $(TOP)/www/changes.tcl tclsh $(TOP)/www/changes.tcl >changes.html +compile.html: $(TOP)/www/compile.tcl + tclsh $(TOP)/www/compile.tcl >compile.html + copyright.html: $(TOP)/www/copyright.tcl tclsh $(TOP)/www/copyright.tcl >copyright.html @@ -456,6 +515,9 @@ index.html: $(TOP)/www/index.tcl last_change lang.html: $(TOP)/www/lang.tcl tclsh $(TOP)/www/lang.tcl >lang.html +pragma.html: $(TOP)/www/pragma.tcl + tclsh $(TOP)/www/pragma.tcl >pragma.html + lockingv3.html: $(TOP)/www/lockingv3.tcl tclsh $(TOP)/www/lockingv3.tcl >lockingv3.html @@ -503,11 +565,13 @@ version3.html: $(TOP)/www/version3.tcl # DOC = \ arch.html \ - arch2.gif \ + arch.png \ + autoinc.html \ c_interface.html \ capi3.html \ capi3ref.html \ changes.html \ + compile.html \ copyright.html \ copyright-release.html \ copyright-release.pdf \ @@ -527,6 +591,7 @@ DOC = \ oldnews.html \ omitted.html \ opcode.html \ + pragma.html \ quickstart.html \ speed.html \ sqlite.gif \ @@ -534,13 +599,13 @@ DOC = \ support.html \ tclsqlite.html \ vdbe.html \ - version3.html + version3.html doc: common.tcl $(DOC) mkdir -p doc mv $(DOC) doc -install: sqlite3 libsqlite3.la sqlite3.h +install: sqlite3 libsqlite3.la sqlite3.h ${HAVE_TCL:1=tcl_install} $(INSTALL) -d $(DESTDIR)$(libdir) $(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir) $(INSTALL) -d $(DESTDIR)$(exec_prefix)/bin @@ -550,14 +615,18 @@ install: sqlite3 libsqlite3.la sqlite3.h $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig; $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(libdir)/pkgconfig; +tcl_install: libtclsqlite3.la + tclsh $(TOP)/tclinstaller.tcl $(VERSION) + clean: - rm -f *.lo *.la *.o sqlite3@TARGET_EXEEXT@ libsqlite3.la + rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la rm -f sqlite3.h opcodes.* rm -rf .libs .deps - rm -f lemon@BUILD_EXEEXT@ lempar.c parse.* sqlite*.tar.gz + rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz + rm -f mkkeywordhash$(BEXE) keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out - rm -f testfixture@TARGET_EXEEXT@ test.db + rm -f testfixture$(TEXE) test.db rm -rf doc rm -f common.tcl rm -f sqlite3.dll sqlite3.lib diff --git a/ext/pdo_sqlite/sqlite/VERSION b/ext/pdo_sqlite/sqlite/VERSION index 67786e246e..ff365e06b9 100644 --- a/ext/pdo_sqlite/sqlite/VERSION +++ b/ext/pdo_sqlite/sqlite/VERSION @@ -1 +1 @@ -3.0.8 +3.1.3 diff --git a/ext/pdo_sqlite/sqlite/configure b/ext/pdo_sqlite/sqlite/configure index 183977d168..779a859463 100755 --- a/ext/pdo_sqlite/sqlite/configure +++ b/ext/pdo_sqlite/sqlite/configure @@ -463,7 +463,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CPP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA program_prefix VERSION BUILD_CC BUILD_CFLAGS BUILD_LIBS TARGET_CC TARGET_CFLAGS TARGET_LINK TARGET_LFLAGS TARGET_RANLIB TARGET_AR THREADSAFE TARGET_THREAD_LIB ALLOWRELEASE TEMP_STORE BUILD_EXEEXT OS_UNIX OS_WIN TARGET_EXEEXT TARGET_LIBS TARGET_TCL_LIBS TARGET_TCL_INC TARGET_READLINE_LIBS TARGET_READLINE_INC TARGET_HAVE_READLINE LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CPP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA program_prefix VERSION VERSION_NUMBER RELEASE BUILD_CC BUILD_CFLAGS BUILD_LIBS TARGET_CC TARGET_CFLAGS TARGET_LINK TARGET_LFLAGS TARGET_RANLIB TARGET_AR THREADSAFE TARGET_THREAD_LIB ALLOWRELEASE TEMP_STORE BUILD_EXEEXT OS_UNIX OS_WIN TARGET_EXEEXT TARGET_LIBS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIBS TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC HAVE_TCL TARGET_READLINE_LIBS TARGET_READLINE_INC TARGET_HAVE_READLINE TARGET_DEBUG LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1028,6 +1028,8 @@ Optional Features: --enable-threadsafe Support threadsafe operation --enable-releasemode Support libtool link to release mode --enable-tempstore Use an in-ram database for temporary tables (never,no,yes,always) + --disable-tcl do not build TCL extension + --enable-debug enable debugging & verbose explain Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1038,6 +1040,7 @@ Optional Packages: --with-tags[=TAGS] include additional configurations [automatic] --with-hints=FILE Read configuration options from FILE + --with-tcl=DIR directory containing tcl configuration (tclConfig.sh) Some influential environment variables: CC C compiler command @@ -3052,7 +3055,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 3055 "configure"' > conftest.$ac_ext + echo '#line 3058 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4515,7 +4518,7 @@ fi # Provide some information about the compiler. -echo "$as_me:4518:" \ +echo "$as_me:4521:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -5549,11 +5552,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5552: $lt_compile\"" >&5) + (eval echo "\"\$as_me:5555: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:5556: \$? = $ac_status" >&5 + echo "$as_me:5559: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -5782,11 +5785,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5785: $lt_compile\"" >&5) + (eval echo "\"\$as_me:5788: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:5789: \$? = $ac_status" >&5 + echo "$as_me:5792: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -5842,11 +5845,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5845: $lt_compile\"" >&5) + (eval echo "\"\$as_me:5848: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:5849: \$? = $ac_status" >&5 + echo "$as_me:5852: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8026,7 +8029,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:10309: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:10310: \$? = $ac_status" >&5 + echo "$as_me:10313: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -10363,11 +10366,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10366: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10369: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10370: \$? = $ac_status" >&5 + echo "$as_me:10373: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11724,7 +11727,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:12655: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12656: \$? = $ac_status" >&5 + echo "$as_me:12659: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -12709,11 +12712,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12712: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12715: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12716: \$? = $ac_status" >&5 + echo "$as_me:12719: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14743,11 +14746,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14746: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14749: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14750: \$? = $ac_status" >&5 + echo "$as_me:14753: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14976,11 +14979,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14979: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14982: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14983: \$? = $ac_status" >&5 + echo "$as_me:14986: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -15036,11 +15039,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15039: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15042: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15043: \$? = $ac_status" >&5 + echo "$as_me:15046: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17220,7 +17223,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5 -echo $ECHO_N "checking for sin... $ECHO_C" >&6 -if test "${ac_cv_func_sin+set}" = set; then + use_tcl=yes +fi; +if test "${use_tcl}" = "yes" ; then + +# Check whether --with-tcl or --without-tcl was given. +if test "${with_tcl+set}" = set; then + withval="$with_tcl" + with_tclconfig=${withval} +fi; + echo "$as_me:$LINENO: checking for Tcl configuration" >&5 +echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 + if test "${ac_cv_c_tclconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define sin to an innocuous variant, in case declares sin. - For example, HP-UX 11i declares gettimeofday. */ -#define sin innocuous_sin -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char sin (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef sin + # First check to see if --with-tcl was specified. + if test x"${with_tclconfig}" != x ; then + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` + else + { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 +echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} + { (exit 1); exit 1; }; } + fi + fi + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` + do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char sin (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_sin) || defined (__stub___sin) -choke me -#else -char (*f) () = sin; -#endif -#ifdef __cplusplus -} -#endif + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + `ls -d ${libdir} 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` + do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi -int -main () -{ -return f != sin; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_sin=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` + do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi -ac_cv_func_sin=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 -echo "${ECHO_T}$ac_cv_func_sin" >&6 -if test $ac_cv_func_sin = yes; then - LIBS="" -else - LIBS="-lm" fi -echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ + if test x"${ac_cv_c_tclconfig}" = x ; then + use_tcl=no + { echo "$as_me:$LINENO: WARNING: Can't find Tcl configuration definitions" >&5 +echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;} + { echo "$as_me:$LINENO: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&5 +echo "$as_me: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&2;} + { echo "$as_me:$LINENO: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&5 +echo "$as_me: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&2;} + else + TCL_BIN_DIR=${ac_cv_c_tclconfig} + echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 +echo "${ECHO_T}found $TCL_BIN_DIR/tclConfig.sh" >&6 + + echo "$as_me:$LINENO: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 +echo $ECHO_N "checking for existence of $TCL_BIN_DIR/tclConfig.sh... $ECHO_C" >&6 + if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then + echo "$as_me:$LINENO: result: loading" >&5 +echo "${ECHO_T}loading" >&6 + . $TCL_BIN_DIR/tclConfig.sh + else + echo "$as_me:$LINENO: result: file not found" >&5 +echo "${ECHO_T}file not found" >&6 + fi -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + # + # If the TCL_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TCL_LIB_SPEC will be set to the value + # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC + # instead of TCL_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + # + + if test -f $TCL_BIN_DIR/Makefile ; then + TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} + TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} + TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} + fi -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDL 1 -_ACEOF + # + # eval is required to do the TCL_DBGX substitution + # - LIBS="-ldl $LIBS" + eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" + eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" -fi + eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" + eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" + eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" - otherlibs=$LIBS - if test "$extra" != ""; then - LIBS=$extra - else - LIBS="" - echo "$as_me:$LINENO: checking for library containing Tcl_Init" >&5 -echo $ECHO_N "checking for library containing Tcl_Init... $ECHO_C" >&6 -if test "${ac_cv_search_Tcl_Init+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_Tcl_Init=no -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char Tcl_Init (); -int -main () -{ -Tcl_Init (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_Tcl_Init="none required" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_Tcl_Init" = no; then - for ac_lib in tcl8.4 tcl8.3 tcl84 tcl83 tcl; do - LIBS="-l$ac_lib $otherlibs $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char Tcl_Init (); -int -main () -{ -Tcl_Init (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_Tcl_Init="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_Tcl_Init" >&5 -echo "${ECHO_T}$ac_cv_search_Tcl_Init" >&6 -if test "$ac_cv_search_Tcl_Init" != no; then - test "$ac_cv_search_Tcl_Init" = "none required" || LIBS="$ac_cv_search_Tcl_Init $LIBS" -fi - fi - TARGET_TCL_LIBS="$LIBS $otherlibs" -fi -########## -# Figure out where to get the TCL header files. -# -echo "$as_me:$LINENO: checking TCL header files" >&5 -echo $ECHO_N "checking TCL header files... $ECHO_C" >&6 -found=no -if test "$config_TARGET_TCL_INC" != ""; then - TARGET_TCL_INC=$config_TARGET_TCL_INC - found=yes -else - if test "$with_tcl" != ""; then - TARGET_TCL_INC="-I$with_tcl/generic -I$with_tcl/$tclsubdir" - found=yes - else - TARGET_TCL_INC="" - found=no - fi -fi -if test "$found" = "yes"; then - echo "$as_me:$LINENO: result: $TARGET_TCL_INC" >&5 -echo "${ECHO_T}$TARGET_TCL_INC" >&6 -else - echo "$as_me:$LINENO: result: not specified: still searching..." >&5 -echo "${ECHO_T}not specified: still searching..." >&6 - if test "${ac_cv_header_tcl_h+set}" = set; then - echo "$as_me:$LINENO: checking for tcl.h" >&5 -echo $ECHO_N "checking for tcl.h... $ECHO_C" >&6 -if test "${ac_cv_header_tcl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_tcl_h" >&5 -echo "${ECHO_T}$ac_cv_header_tcl_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking tcl.h usability" >&5 -echo $ECHO_N "checking tcl.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 -# Is the header present? -echo "$as_me:$LINENO: checking tcl.h presence" >&5 -echo $ECHO_N "checking tcl.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: tcl.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: tcl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: tcl.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: tcl.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: tcl.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: tcl.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: tcl.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: tcl.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: tcl.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: tcl.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: tcl.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: tcl.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: tcl.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: tcl.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: tcl.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: tcl.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for tcl.h" >&5 -echo $ECHO_N "checking for tcl.h... $ECHO_C" >&6 -if test "${ac_cv_header_tcl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_tcl_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_tcl_h" >&5 -echo "${ECHO_T}$ac_cv_header_tcl_h" >&6 -fi -if test $ac_cv_header_tcl_h = yes; then - found=yes -fi + fi fi -if test "$found" = "no"; then - for dir in /usr/local /usr/X11 /usr/X11R6 /usr/pkg /usr/contrib /usr; do - as_ac_File=`echo "ac_cv_file_$dir/include/tcl.h" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $dir/include/tcl.h" >&5 -echo $ECHO_N "checking for $dir/include/tcl.h... $ECHO_C" >&6 -if eval "test \"\${$as_ac_File+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - test "$cross_compiling" = yes && - { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 -echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} - { (exit 1); exit 1; }; } -if test -r "$dir/include/tcl.h"; then - eval "$as_ac_File=yes" +if test "${use_tcl}" = "no" ; then + HAVE_TCL="" else - eval "$as_ac_File=no" -fi -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_File'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_File'}'`" >&6 -if test `eval echo '${'$as_ac_File'}'` = yes; then - found=yes -fi - - if test "$found" = "yes"; then - TARGET_TCL_INC="-I$dir/include" - break - fi - done -fi -if test "$found" = "no"; then - TARGET_TCL_INC="-DNO_TCL=1" + HAVE_TCL=1 fi @@ -20568,6 +20226,22 @@ fi +######### +# check for debug enabled +# Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + use_debug=$enableval +else + use_debug=no +fi; +if test "${use_debug}" = "yes" ; then + TARGET_DEBUG="" +else + TARGET_DEBUG="-DNDEBUG" +fi + + ######### # Figure out whether or not we have a "usleep()" function. # @@ -21344,6 +21018,8 @@ s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@program_prefix@,$program_prefix,;t t s,@VERSION@,$VERSION,;t t +s,@VERSION_NUMBER@,$VERSION_NUMBER,;t t +s,@RELEASE@,$RELEASE,;t t s,@BUILD_CC@,$BUILD_CC,;t t s,@BUILD_CFLAGS@,$BUILD_CFLAGS,;t t s,@BUILD_LIBS@,$BUILD_LIBS,;t t @@ -21362,11 +21038,22 @@ s,@OS_UNIX@,$OS_UNIX,;t t s,@OS_WIN@,$OS_WIN,;t t s,@TARGET_EXEEXT@,$TARGET_EXEEXT,;t t s,@TARGET_LIBS@,$TARGET_LIBS,;t t -s,@TARGET_TCL_LIBS@,$TARGET_TCL_LIBS,;t t -s,@TARGET_TCL_INC@,$TARGET_TCL_INC,;t t +s,@TCL_VERSION@,$TCL_VERSION,;t t +s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t +s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t +s,@TCL_LIBS@,$TCL_LIBS,;t t +s,@TCL_INCLUDE_SPEC@,$TCL_INCLUDE_SPEC,;t t +s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t +s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t +s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t +s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t +s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t +s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t +s,@HAVE_TCL@,$HAVE_TCL,;t t s,@TARGET_READLINE_LIBS@,$TARGET_READLINE_LIBS,;t t s,@TARGET_READLINE_INC@,$TARGET_READLINE_INC,;t t s,@TARGET_HAVE_READLINE@,$TARGET_HAVE_READLINE,;t t +s,@TARGET_DEBUG@,$TARGET_DEBUG,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF diff --git a/ext/pdo_sqlite/sqlite/configure.ac b/ext/pdo_sqlite/sqlite/configure.ac index 20cd5a8ccd..6137f39d20 100644 --- a/ext/pdo_sqlite/sqlite/configure.ac +++ b/ext/pdo_sqlite/sqlite/configure.ac @@ -1,9 +1,4 @@ # -# This file describes a "configure" script that is used to build -# makefiles for a particular platform. Process this file using -# Autoconf version 1.13 in order to generate that script. All -# lines of this file up to the AC_INIT macro are ignored. -# # The build process allows for using a cross-compiler. But the default # action is to target the same platform that we are running on. The # configure script needs to discover the following properties of the @@ -62,18 +57,11 @@ # into *.o files. Do not include TARGET_TCL_INC in this list. # Makefiles might add additional switches such as "-I.". # -# TARGET_TCL_LIBS -# -# This is the library directives passed to the target linker -# that cause the executable to link against Tcl. This might -# be a switch like "-ltcl8.0" or pathnames of library file -# like "../../src/libtcl8.0.a". -# -# TARGET_TCL_INC +# TCL_* # -# This variables define the directory that contain header -# files for Tcl. If the compiler is able to find -# on its own, then this can be blank. +# Lots of values are read in from the tclConfig.sh script, +# if that script is available. This values are used for +# constructing and installing the TCL extension. # # TARGET_READLINE_LIBS # @@ -118,16 +106,6 @@ # where FILE is the name of the file that sets the environment # variables. FILE should be an absolute pathname. # -# If you have a Tcl/Tk/BLT source distribution available, then the -# files in that distribution will be used instead of any other -# Tcl/Tk/BLT files the script might discover if you tell the configure -# script about the source tree. Use commandline options: -# -# --with-tcl=PATH --with-tk=PATH --with-blt=PATH -# -# Or set environment variables config_WITH_TCL, config_WITH_TK, or -# config_WITH_BLT. -# # This configure.in file is easy to reuse on other projects. Just # change the argument to AC_INIT(). And disable any features that # you don't need (for example BLT) by erasing or commenting out @@ -154,11 +132,17 @@ if test "$program_prefix" = "NONE"; then fi AC_SUBST(program_prefix) -if test -f VERSION; then - VERSION=`cat VERSION` - echo "Version set to $VERSION" -fi +VERSION=[`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'`] +echo "Version set to $VERSION" AC_SUBST(VERSION) +RELEASE=`cat $srcdir/VERSION` +echo "Release set to $RELEASE" +AC_SUBST(RELEASE) +VERSION_NUMBER=`cat $srcdir/VERSION \ + | sed 's/[^0-9]/ /g' \ + | awk '{printf "%d%03d%03d",$1,$2,$3}'` +echo "Version number set to $VERSION_NUMBER" +AC_SUBST(VERSION_NUMBER) ######### # Check to see if the --with-hints=FILE option is used. If there is none, @@ -410,65 +394,146 @@ fi AC_SUBST(TARGET_LIBS) ########## -# Figure out what C libraries are required to compile Tcl programs. -# -if test "$config_TARGET_TCL_LIBS" != ""; then - TARGET_TCL_LIBS="$config_TARGET_TCL_LIBS" -else - if test "$with_tcl" != ""; then - extra=`echo $with_tcl/$tclsubdir/libtcl8*.a` - fi - CC=$TARGET_CC - AC_CHECK_FUNC(sin, LIBS="", LIBS="-lm") - AC_CHECK_LIB(dl, dlopen) - otherlibs=$LIBS - if test "$extra" != ""; then - LIBS=$extra - else - LIBS="" - AC_SEARCH_LIBS(Tcl_Init, dnl - tcl8.4 tcl8.3 tcl84 tcl83 tcl,,,$otherlibs) - fi - TARGET_TCL_LIBS="$LIBS $otherlibs" -fi -AC_SUBST(TARGET_TCL_LIBS) +# Figure out all the parameters needed to compile against Tcl. +# +# This code is derived from the SC_PATH_TCLCONFIG and SC_LOAD_TCLCONFIG +# macros in the in the tcl.m4 file of the standard TCL distribution. +# Those macros could not be used directly since we have to make some +# minor changes to accomodate systems that do not have TCL installed. +# +AC_ARG_ENABLE(tcl, [ --disable-tcl do not build TCL extension], + [use_tcl=$enableval],[use_tcl=yes]) +if test "${use_tcl}" = "yes" ; then + AC_ARG_WITH(tcl, [ --with-tcl=DIR directory containing tcl configuration (tclConfig.sh)], with_tclconfig=${withval}) + AC_MSG_CHECKING([for Tcl configuration]) + AC_CACHE_VAL(ac_cv_c_tclconfig,[ + # First check to see if --with-tcl was specified. + if test x"${with_tclconfig}" != x ; then + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` + else + AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) + fi + fi + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` + do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi -########## -# Figure out where to get the TCL header files. -# -AC_MSG_CHECKING([TCL header files]) -found=no -if test "$config_TARGET_TCL_INC" != ""; then - TARGET_TCL_INC=$config_TARGET_TCL_INC - found=yes -else - if test "$with_tcl" != ""; then - TARGET_TCL_INC="-I$with_tcl/generic -I$with_tcl/$tclsubdir" - found=yes + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + `ls -d ${libdir} 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` + do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` + do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi + ]) + + if test x"${ac_cv_c_tclconfig}" = x ; then + use_tcl=no + AC_MSG_WARN(Can't find Tcl configuration definitions) + AC_MSG_WARN(*** Without Tcl the regression tests cannot be executed ***) + AC_MSG_WARN(*** Consider using --with-tcl=... to define location of Tcl ***) else - TARGET_TCL_INC="" - found=no + TCL_BIN_DIR=${ac_cv_c_tclconfig} + AC_MSG_RESULT(found $TCL_BIN_DIR/tclConfig.sh) + + AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh]) + if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then + AC_MSG_RESULT([loading]) + . $TCL_BIN_DIR/tclConfig.sh + else + AC_MSG_RESULT([file not found]) + fi + + # + # If the TCL_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TCL_LIB_SPEC will be set to the value + # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC + # instead of TCL_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + # + + if test -f $TCL_BIN_DIR/Makefile ; then + TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} + TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} + TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} + fi + + # + # eval is required to do the TCL_DBGX substitution + # + + eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" + eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" + + eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" + eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" + eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" + + AC_SUBST(TCL_VERSION) + AC_SUBST(TCL_BIN_DIR) + AC_SUBST(TCL_SRC_DIR) + AC_SUBST(TCL_LIBS) + AC_SUBST(TCL_INCLUDE_SPEC) + + AC_SUBST(TCL_LIB_FILE) + AC_SUBST(TCL_LIB_FLAG) + AC_SUBST(TCL_LIB_SPEC) + + AC_SUBST(TCL_STUB_LIB_FILE) + AC_SUBST(TCL_STUB_LIB_FLAG) + AC_SUBST(TCL_STUB_LIB_SPEC) fi fi -if test "$found" = "yes"; then - AC_MSG_RESULT($TARGET_TCL_INC) +if test "${use_tcl}" = "no" ; then + HAVE_TCL="" else - AC_MSG_RESULT(not specified: still searching...) - AC_CHECK_HEADER(tcl.h, [found=yes]) + HAVE_TCL=1 fi -if test "$found" = "no"; then - for dir in /usr/local /usr/X11 /usr/X11R6 /usr/pkg /usr/contrib /usr; do - AC_CHECK_FILE($dir/include/tcl.h, found=yes) - if test "$found" = "yes"; then - TARGET_TCL_INC="-I$dir/include" - break - fi - done -fi -if test "$found" = "no"; then - TARGET_TCL_INC="-DNO_TCL=1" -fi -AC_SUBST(TARGET_TCL_INC) +AC_SUBST(HAVE_TCL) ########## # Figure out what C libraries are required to compile programs @@ -526,6 +591,17 @@ fi AC_SUBST(TARGET_READLINE_INC) AC_SUBST(TARGET_HAVE_READLINE) +######### +# check for debug enabled +AC_ARG_ENABLE(debug, [ --enable-debug enable debugging & verbose explain], + [use_debug=$enableval],[use_debug=no]) +if test "${use_debug}" = "yes" ; then + TARGET_DEBUG="" +else + TARGET_DEBUG="-DNDEBUG" +fi +AC_SUBST(TARGET_DEBUG) + ######### # Figure out whether or not we have a "usleep()" function. # diff --git a/ext/pdo_sqlite/sqlite/main.mk b/ext/pdo_sqlite/sqlite/main.mk index e79e0926ba..f6fc40c136 100644 --- a/ext/pdo_sqlite/sqlite/main.mk +++ b/ext/pdo_sqlite/sqlite/main.mk @@ -54,9 +54,9 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src # Object files for the SQLite library. # -LIBOBJ+= attach.o auth.o btree.o build.o date.o delete.o \ +LIBOBJ+= alter.o attach.o auth.o btree.o build.o date.o delete.o \ expr.o func.o hash.o insert.o \ - main.o opcodes.o os_mac.o os_unix.o os_win.o \ + main.o opcodes.o os_unix.o os_win.o \ pager.o parse.o pragma.o printf.o random.o \ select.o table.o tclsqlite.o tokenize.o trigger.o \ update.o util.o vacuum.o \ @@ -66,6 +66,7 @@ LIBOBJ+= attach.o auth.o btree.o build.o date.o delete.o \ # All of the source code files. # SRC = \ + $(TOP)/src/alter.c \ $(TOP)/src/attach.c \ $(TOP)/src/auth.c \ $(TOP)/src/btree.c \ @@ -80,7 +81,6 @@ SRC = \ $(TOP)/src/insert.c \ $(TOP)/src/legacy.c \ $(TOP)/src/main.c \ - $(TOP)/src/os_mac.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ @@ -113,8 +113,8 @@ SRC = \ # TESTSRC = \ $(TOP)/src/btree.c \ + $(TOP)/src/date.c \ $(TOP)/src/func.c \ - $(TOP)/src/os_mac.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ $(TOP)/src/pager.c \ @@ -140,7 +140,6 @@ HDR = \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ - $(TOP)/src/os_mac.h \ $(TOP)/src/os_unix.h \ $(TOP)/src/os_win.h \ $(TOP)/src/sqliteInt.h \ @@ -181,12 +180,12 @@ objects: $(LIBOBJ_ORIG) # files are automatically generated. This target takes care of # all that automatic generation. # -target_source: $(SRC) $(VDBEHDR) opcodes.c +target_source: $(SRC) $(VDBEHDR) opcodes.c keywordhash.h rm -rf tsrc mkdir tsrc cp $(SRC) $(VDBEHDR) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - cp parse.c opcodes.c tsrc + cp parse.c opcodes.c keywordhash.h tsrc cp $(TOP)/sqlite3.def tsrc # Rules to build the LEMON compiler generator @@ -197,6 +196,9 @@ lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c # Rules to build individual files # +alter.o: $(TOP)/src/alter.c $(HDR) + $(TCCX) -c $(TOP)/src/alter.c + attach.o: $(TOP)/src/attach.c $(HDR) $(TCCX) -c $(TOP)/src/attach.c @@ -256,14 +258,11 @@ opcodes.o: opcodes.c $(TCCX) -c opcodes.c opcodes.c: opcodes.h $(TOP)/mkopcodec.awk - sort -n +2 opcodes.h | awk -f $(TOP)/mkopcodec.awk >opcodes.c + sort -n -b +2 opcodes.h | awk -f $(TOP)/mkopcodec.awk >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >opcodes.h -os_mac.o: $(TOP)/src/os_mac.c $(HDR) - $(TCCX) -c $(TOP)/src/os_mac.c - os_unix.o: $(TOP)/src/os_unix.c $(HDR) $(TCCX) -c $(TOP)/src/os_unix.c @@ -277,7 +276,7 @@ parse.h: parse.c parse.c: $(TOP)/src/parse.y lemon cp $(TOP)/src/parse.y . - ./lemon parse.y + ./lemon $(OPTS) parse.y pragma.o: $(TOP)/src/pragma.c $(HDR) $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/pragma.c @@ -293,7 +292,7 @@ select.o: $(TOP)/src/select.c $(HDR) sqlite3.h: $(TOP)/src/sqlite.h.in sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \ - -e s/--ENCODING--/$(ENCODING)/ \ + -e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | awk '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \ $(TOP)/src/sqlite.h.in >sqlite3.h table.o: $(TOP)/src/table.c $(HDR) @@ -302,9 +301,13 @@ table.o: $(TOP)/src/table.c $(HDR) tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c -tokenize.o: $(TOP)/src/tokenize.c $(HDR) +tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) $(TCCX) -c $(TOP)/src/tokenize.c +keywordhash.h: $(TOP)/tool/mkkeywordhash.c + $(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c + ./mkkeywordhash >keywordhash.h + trigger.o: $(TOP)/src/trigger.c $(HDR) $(TCCX) -c $(TOP)/src/trigger.c @@ -367,7 +370,7 @@ sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) \ -e 's,^,",' \ -e 's,$$,\\n",' \ $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h - $(TCCX) $(TCL_FLAGS) -DTCLSH=2 -DSQLITE_TEST=1 -static -o \ + $(TCCX) $(TCL_FLAGS) -DTCLSH=2 -DSQLITE_TEST=1 -o \ sqlite3_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) @@ -379,6 +382,9 @@ arch.html: $(TOP)/www/arch.tcl arch.png: $(TOP)/www/arch.png cp $(TOP)/www/arch.png . +autoinc.html: $(TOP)/www/autoinc.tcl + tclsh $(TOP)/www/autoinc.tcl >autoinc.html + c_interface.html: $(TOP)/www/c_interface.tcl tclsh $(TOP)/www/c_interface.tcl >c_interface.html @@ -391,6 +397,9 @@ capi3ref.html: $(TOP)/www/capi3ref.tcl changes.html: $(TOP)/www/changes.tcl tclsh $(TOP)/www/changes.tcl >changes.html +compile.html: $(TOP)/www/compile.tcl + tclsh $(TOP)/www/compile.tcl >compile.html + copyright.html: $(TOP)/www/copyright.tcl tclsh $(TOP)/www/copyright.tcl >copyright.html @@ -432,7 +441,10 @@ index.html: $(TOP)/www/index.tcl last_change tclsh $(TOP)/www/index.tcl >index.html lang.html: $(TOP)/www/lang.tcl - tclsh $(TOP)/www/lang.tcl >lang.html + tclsh $(TOP)/www/lang.tcl doc >lang.html + +pragma.html: $(TOP)/www/pragma.tcl + tclsh $(TOP)/www/pragma.tcl >pragma.html lockingv3.html: $(TOP)/www/lockingv3.tcl tclsh $(TOP)/www/lockingv3.tcl >lockingv3.html @@ -476,16 +488,21 @@ vdbe.html: $(TOP)/www/vdbe.tcl version3.html: $(TOP)/www/version3.tcl tclsh $(TOP)/www/version3.tcl >version3.html +whentouse.html: $(TOP)/www/whentouse.tcl + tclsh $(TOP)/www/whentouse.tcl >whentouse.html + # Files to be published on the website. # DOC = \ arch.html \ arch.png \ + autoinc.html \ c_interface.html \ capi3.html \ capi3ref.html \ changes.html \ + compile.html \ copyright.html \ copyright-release.html \ copyright-release.pdf \ @@ -505,6 +522,7 @@ DOC = \ oldnews.html \ omitted.html \ opcode.html \ + pragma.html \ quickstart.html \ speed.html \ sqlite.gif \ @@ -512,7 +530,8 @@ DOC = \ support.html \ tclsqlite.html \ vdbe.html \ - version3.html + version3.html \ + whentouse.html doc: common.tcl $(DOC) mkdir -p doc @@ -527,7 +546,7 @@ install: sqlite3 libsqlite3.a sqlite3.h clean: rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* - rm -f lemon lempar.c parse.* sqlite*.tar.gz + rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -rf tsrc diff --git a/ext/pdo_sqlite/sqlite/mkopcodec.awk b/ext/pdo_sqlite/sqlite/mkopcodec.awk index 6119272bd7..bf6bfbeb37 100644 --- a/ext/pdo_sqlite/sqlite/mkopcodec.awk +++ b/ext/pdo_sqlite/sqlite/mkopcodec.awk @@ -10,13 +10,19 @@ # BEGIN { print "/* Automatically generated. Do not edit */" - print "/* See the mkopcodec.h script for details. */" + print "/* See the mkopcodec.awk script for details. */" + printf "#if !defined(SQLITE_OMIT_EXPLAIN)" + printf " || !defined(NDEBUG)" + printf " || defined(VDBE_PROFILE)" + print " || defined(SQLITE_DEBUG)" print "const char *const sqlite3OpcodeNames[] = { \"?\"," } -/^#define OP_/ { +/define OP_/ { sub("OP_","",$2) - print " \"" $2 "\"," + i++ + printf " /* %3d */ \"%s\",\n", $3, $2 } END { print "};" + print "#endif" } diff --git a/ext/pdo_sqlite/sqlite/mkopcodeh.awk b/ext/pdo_sqlite/sqlite/mkopcodeh.awk index ead07d5ff9..641b987a81 100644 --- a/ext/pdo_sqlite/sqlite/mkopcodeh.awk +++ b/ext/pdo_sqlite/sqlite/mkopcodeh.awk @@ -1,5 +1,7 @@ #!/usr/bin/awk -f # +# Generate the file opcodes.h. +# # This AWK script scans a concatenation of the parse.h output file from the # parser and the vdbe.c source file in order to generate the opcodes numbers # for all opcodes. @@ -12,6 +14,15 @@ # the OP_ is the same as the TK_ value. If missing, the OP_ value is assigned # a small integer that is different from every other OP_ value. # +# We go to the trouble of making some OP_ value the same as TK_ values +# as an optimization. During parsing, things like expression operators +# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth. Later +# during code generation, we need to generate corresponding opcodes like +# OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide, +# code to translation from one to the other is avoided. This makes the +# code generator run (infinitesimally) faster and more importantly it makes +# the total library smaller. +# # Remember the TK_ values from the parse.h file /^#define TK_/ { @@ -28,6 +39,7 @@ if($i=="same" && $(i+1)=="as"){ op[name] = tk[$(i+2)] used[op[name]] = 1 + sameas[op[name]] = $(i+2) } } } @@ -35,6 +47,7 @@ # Assign numbers to all opcodes and output the result. END { cnt = 0 + max = 0 print "/* Automatically generated. Do not edit */" print "/* See the mkopcodeh.awk script for details */" for(name in op){ @@ -43,6 +56,23 @@ END { while( used[cnt] ) cnt++ op[name] = cnt } - printf "#define %-30s %d\n", name, op[name] + used[op[name]] = 1; + if( op[name]>max ) max = op[name] + printf "#define %-25s %15d", name, op[name] + if( sameas[op[name]] ) { + printf " /* same as %-12s*/", sameas[op[name]] + } + printf "\n" + + } + seenUnused = 0; + for(i=1; i 'CREATE TABLE def(a, b, c)' +** +** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') +** -> 'CREATE INDEX i ON def(a, b, c)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char const *zSql = sqlite3_value_text(argv[0]); + unsigned char const *zTableName = sqlite3_value_text(argv[1]); + + int token; + Token tname; + char const *zCsr = zSql; + int len = 0; + char *zRet; + + /* The principle used to locate the table name in the CREATE TABLE + ** statement is that the table name is the first token that is immediatedly + ** followed by a left parenthesis - TK_LP. + */ + if( zSql ){ + do { + /* Store the token that zCsr points to in tname. */ + tname.z = zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and it's length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + } while( token==TK_SPACE ); + assert( len>0 ); + } while( token!=TK_LP ); + + zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, + zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, sqlite3FreeX); + } +} + +#ifndef SQLITE_OMIT_TRIGGER +/* This function is used by SQL generated to implement the ALTER TABLE +** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER +** statement. The second is a table name. The table name in the CREATE +** TRIGGER statement is replaced with the second argument and the result +** returned. This is analagous to renameTableFunc() above, except for CREATE +** TRIGGER, not CREATE INDEX and CREATE TABLE. +*/ +static void renameTriggerFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char const *zSql = sqlite3_value_text(argv[0]); + unsigned char const *zTableName = sqlite3_value_text(argv[1]); + + int token; + Token tname; + int dist = 3; + char const *zCsr = zSql; + int len = 0; + char *zRet; + + /* The principle used to locate the table name in the CREATE TRIGGER + ** statement is that the table name is the first token that is immediatedly + ** preceded by either TK_ON or TK_DOT and immediatedly followed by one + ** of TK_WHEN, TK_BEGIN or TK_FOR. + */ + if( zSql ){ + do { + /* Store the token that zCsr points to in tname. */ + tname.z = zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and it's length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + }while( token==TK_SPACE ); + assert( len>0 ); + + /* Variable 'dist' stores the number of tokens read since the most + ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN + ** token is read and 'dist' equals 2, the condition stated above + ** to be met. + ** + ** Note that ON cannot be a database, table or column name, so + ** there is no need to worry about syntax like + ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. + */ + dist++; + if( token==TK_DOT || token==TK_ON ){ + dist = 0; + } + } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); + + /* Variable tname now contains the token that is the old table-name + ** in the CREATE TRIGGER statement. + */ + zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, + zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, sqlite3FreeX); + } +} +#endif /* !SQLITE_OMIT_TRIGGER */ + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +void sqlite3AlterFunctions(sqlite3 *db){ + static const struct { + char *zName; + signed char nArg; + void (*xFunc)(sqlite3_context*,int,sqlite3_value **); + } aFuncs[] = { + { "sqlite_rename_table", 2, renameTableFunc}, +#ifndef SQLITE_OMIT_TRIGGER + { "sqlite_rename_trigger", 2, renameTriggerFunc}, +#endif + }; + int i; + + for(i=0; idb; /* Database connection */ + Vdbe *v; +#ifndef SQLITE_OMIT_TRIGGER + char *zTempTrig = 0; /* Where clause to locate temp triggers */ +#endif + + assert( pSrc->nSrc==1 ); + + pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); + if( !pTab ) goto exit_rename_table; + iDb = pTab->iDb; + zDb = db->aDb[iDb].zName; + + /* Get a NULL terminated version of the new table name. */ + zName = sqlite3NameFromToken(pName); + if( !zName ) goto exit_rename_table; + + /* Check that a table or index named 'zName' does not already exist + ** in database iDb. If so, this is an error. + */ + if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ + sqlite3ErrorMsg(pParse, + "there is already another table or index with this name: %s", zName); + goto exit_rename_table; + } + + /* Make sure it is not a system table being altered, or a reserved name + ** that the table is being renamed to. + */ + if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); + goto exit_rename_table; + } + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ + goto exit_rename_table; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_table; + } +#endif + + /* Begin a transaction and code the VerifyCookie for database iDb. + ** Then modify the schema cookie (since the ALTER TABLE modifies the + ** schema). + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto exit_rename_table; + } + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3ChangeCookie(db, v, iDb); + + /* Modify the sqlite_master table to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET " +#ifdef SQLITE_OMIT_TRIGGER + "sql = sqlite_rename_table(sql, %Q), " +#else + "sql = CASE " + "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" + "ELSE sqlite_rename_table(sql, %Q) END, " +#endif + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) " + "ELSE name END " + "WHERE tbl_name=%Q AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, SCHEMA_TABLE(iDb), zName, zName, zName, +#ifndef SQLITE_OMIT_TRIGGER +zName, +#endif + zName, strlen(pTab->zName), pTab->zName + ); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If the sqlite_sequence table exists in this database, then update + ** it with the new table name. + */ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, + "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q", + zDb, zName, pTab->zName); + } +#endif + +#ifndef SQLITE_OMIT_TRIGGER + /* If there are TEMP triggers on this table, modify the sqlite_temp_master + ** table. Don't do this if the table being ALTERed is itself located in + ** the temp database. + */ + if( iDb!=1 ){ + Trigger *pTrig; + char *tmp = 0; + for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ + if( pTrig->iDb==1 ){ + if( !zTempTrig ){ + zTempTrig = + sqlite3MPrintf("type = 'trigger' AND (name=%Q", pTrig->name); + }else{ + tmp = zTempTrig; + zTempTrig = sqlite3MPrintf("%s OR name=%Q", zTempTrig, pTrig->name); + sqliteFree(tmp); + } + } + } + if( zTempTrig ){ + tmp = zTempTrig; + zTempTrig = sqlite3MPrintf("%s)", zTempTrig); + sqliteFree(tmp); + sqlite3NestedParse(pParse, + "UPDATE sqlite_temp_master SET " + "sql = sqlite_rename_trigger(sql, %Q), " + "tbl_name = %Q " + "WHERE %s;", zName, zName, zTempTrig); + } + } +#endif + + /* Drop the elements of the in-memory schema that refered to the table + ** renamed and load the new versions from the database. + */ + if( pParse->nErr==0 ){ +#ifndef SQLITE_OMIT_TRIGGER + Trigger *pTrig; + for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ + assert( pTrig->iDb==iDb || pTrig->iDb==1 ); + sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0); + } +#endif + sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); + zWhere = sqlite3MPrintf("tbl_name=%Q", zName); + sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC); +#ifndef SQLITE_OMIT_TRIGGER + if( zTempTrig ){ + sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zTempTrig, P3_DYNAMIC); + } + }else{ + sqliteFree(zTempTrig); +#endif + } + +exit_rename_table: + sqlite3SrcListDelete(pSrc); + sqliteFree(zName); +} +#endif /* SQLITE_ALTER_TABLE */ diff --git a/ext/pdo_sqlite/sqlite/src/attach.c b/ext/pdo_sqlite/sqlite/src/attach.c index 2f0899865c..79c325f4c1 100644 --- a/ext/pdo_sqlite/sqlite/src/attach.c +++ b/ext/pdo_sqlite/sqlite/src/attach.c @@ -38,6 +38,7 @@ void sqlite3Attach( v = sqlite3GetVdbe(pParse); if( !v ) return; + sqlite3VdbeAddOp(v, OP_Expire, 1, 0); sqlite3VdbeAddOp(v, OP_Halt, 0, 0); if( pParse->explain ) return; db = pParse->db; @@ -160,6 +161,7 @@ void sqlite3Detach(Parse *pParse, Token *pDbname){ v = sqlite3GetVdbe(pParse); if( !v ) return; + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); sqlite3VdbeAddOp(v, OP_Halt, 0, 0); if( pParse->explain ) return; db = pParse->db; @@ -251,11 +253,14 @@ int sqlite3FixSrcList( pFix->zType, pFix->pName, pItem->zDatabase); return 1; } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; +#endif } return 0; } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) int sqlite3FixSelect( DbFixer *pFix, /* Context of the fixation */ Select *pSelect /* The SELECT statement to be fixed to one database */ @@ -309,6 +314,9 @@ int sqlite3FixExprList( } return 0; } +#endif + +#ifndef SQLITE_OMIT_TRIGGER int sqlite3FixTriggerStep( DbFixer *pFix, /* Context of the fixation */ TriggerStep *pStep /* The trigger step be fixed to one database */ @@ -327,3 +335,4 @@ int sqlite3FixTriggerStep( } return 0; } +#endif diff --git a/ext/pdo_sqlite/sqlite/src/auth.c b/ext/pdo_sqlite/sqlite/src/auth.c index b251eacfdf..d4b7a61bd3 100644 --- a/ext/pdo_sqlite/sqlite/src/auth.c +++ b/ext/pdo_sqlite/sqlite/src/auth.c @@ -76,6 +76,7 @@ int sqlite3_set_authorizer( ){ db->xAuth = xAuth; db->pAuthArg = pArg; + sqlite3ExpirePreparedStatements(db); return SQLITE_OK; } @@ -114,10 +115,10 @@ void sqlite3AuthRead( if( db->xAuth==0 ) return; assert( pExpr->op==TK_COLUMN ); - for(iSrc=0; iSrcnSrc; iSrc++){ + for(iSrc=0; pTabList && iSrcnSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break; } - if( iSrc>=0 && iSrcnSrc ){ + if( iSrc>=0 && pTabList && iSrcnSrc ){ pTab = pTabList->a[iSrc].pTab; }else if( (pStack = pParse->trigStack)!=0 ){ /* This must be an attempt to read the NEW or OLD pseudo-tables diff --git a/ext/pdo_sqlite/sqlite/src/btree.c b/ext/pdo_sqlite/sqlite/src/btree.c index fe8754e01d..b4ea019b6e 100644 --- a/ext/pdo_sqlite/sqlite/src/btree.c +++ b/ext/pdo_sqlite/sqlite/src/btree.c @@ -211,6 +211,11 @@ #include "os.h" #include +/* +** This macro rounds values up so that if the value is an address it +** is guaranteed to be an address that is aligned to an 8-byte boundary. +*/ +#define FORCE_ALIGNMENT(X) (((X)+7)&~7) /* The following value is the maximum cell size assuming a maximum page ** size give above. @@ -299,7 +304,11 @@ struct Btree { u8 minEmbedFrac; /* Minimum payload as % of total page size */ u8 minLeafFrac; /* Minimum leaf payload as % of total page size */ u8 pageSizeFixed; /* True if the page size can no longer be changed */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 autoVacuum; /* True if database supports auto-vacuum */ +#endif u16 pageSize; /* Total number of bytes on a page */ + u16 psAligned; /* pageSize rounded up to a multiple of 8 */ u16 usableSize; /* Number of usable bytes on each page */ int maxLocal; /* Maximum local payload in non-LEAFDATA tables */ int minLocal; /* Minimum local payload in non-LEAFDATA tables */ @@ -347,15 +356,26 @@ struct BtCursor { CellInfo info; /* A parse of the cell we are pointing at */ u8 wrFlag; /* True if writable */ u8 isValid; /* TRUE if points to a valid entry */ - u8 status; /* Set to SQLITE_ABORT if cursors is invalidated */ }; +/* +** The TRACE macro will print high-level status information about the +** btree operation when the global variable sqlite3_btree_trace is +** enabled. +*/ +#if SQLITE_TEST +# define TRACE(X) if( sqlite3_btree_trace )\ + { sqlite3DebugPrintf X; fflush(stdout); } +#else +# define TRACE(X) +#endif +int sqlite3_btree_trace=0; /* True to enable tracing */ + /* ** Forward declaration */ static int checkReadLocks(Btree*,Pgno,BtCursor*); - /* ** Read or write a two- and four-byte big-endian integer values. */ @@ -385,6 +405,136 @@ static void put4byte(unsigned char *p, u32 v){ #define getVarint32 sqlite3GetVarint32 #define putVarint sqlite3PutVarint +/* The database page the PENDING_BYTE occupies. This page is never used. +** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They +** should possibly be consolidated (presumably in pager.h). +*/ +#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1) + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** These macros define the location of the pointer-map entry for a +** database page. The first argument to each is the number of usable +** bytes on each page of the database (often 1024). The second is the +** page number to look up in the pointer map. +** +** PTRMAP_PAGENO returns the database page number of the pointer-map +** page that stores the required pointer. PTRMAP_PTROFFSET returns +** the offset of the requested map entry. +** +** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, +** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be +** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements +** this test. +*/ +#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2) +#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5) +#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno) + +/* +** The pointer map is a lookup table that identifies the parent page for +** each child page in the database file. The parent page is the page that +** contains a pointer to the child. Every page in the database contains +** 0 or 1 parent pages. (In this context 'database page' refers +** to any page that is not part of the pointer map itself.) Each pointer map +** entry consists of a single byte 'type' and a 4 byte parent page number. +** The PTRMAP_XXX identifiers below are the valid types. +** +** The purpose of the pointer map is to facility moving pages from one +** position in the file to another as part of autovacuum. When a page +** is moved, the pointer in its parent must be updated to point to the +** new location. The pointer map is used to locate the parent page quickly. +** +** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not +** used in this case. +** +** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number +** is not used in this case. +** +** PTRMAP_OVERFLOW1: The database page is the first page in a list of +** overflow pages. The page number identifies the page that +** contains the cell with a pointer to this overflow page. +** +** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of +** overflow pages. The page-number identifies the previous +** page in the overflow page list. +** +** PTRMAP_BTREE: The database page is a non-root btree page. The page number +** identifies the parent page in the btree. +*/ +#define PTRMAP_ROOTPAGE 1 +#define PTRMAP_FREEPAGE 2 +#define PTRMAP_OVERFLOW1 3 +#define PTRMAP_OVERFLOW2 4 +#define PTRMAP_BTREE 5 + +/* +** Write an entry into the pointer map. +** +** This routine updates the pointer map entry for page number 'key' +** so that it maps to type 'eType' and parent page number 'pgno'. +** An error code is returned if something goes wrong, otherwise SQLITE_OK. +*/ +static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){ + u8 *pPtrmap; /* The pointer map page */ + Pgno iPtrmap; /* The pointer map page number */ + int offset; /* Offset in pointer map page */ + int rc; + + assert( pBt->autoVacuum ); + if( key==0 ){ + return SQLITE_CORRUPT; + } + iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key); + rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap); + if( rc!=SQLITE_OK ){ + return rc; + } + offset = PTRMAP_PTROFFSET(pBt->usableSize, key); + + if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ + TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); + rc = sqlite3pager_write(pPtrmap); + if( rc==SQLITE_OK ){ + pPtrmap[offset] = eType; + put4byte(&pPtrmap[offset+1], parent); + } + } + + sqlite3pager_unref(pPtrmap); + return rc; +} + +/* +** Read an entry from the pointer map. +** +** This routine retrieves the pointer map entry for page 'key', writing +** the type and parent page number to *pEType and *pPgno respectively. +** An error code is returned if something goes wrong, otherwise SQLITE_OK. +*/ +static int ptrmapGet(Btree *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ + int iPtrmap; /* Pointer map page index */ + u8 *pPtrmap; /* Pointer map page data */ + int offset; /* Offset of entry in pointer map */ + int rc; + + iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key); + rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap); + if( rc!=0 ){ + return rc; + } + + offset = PTRMAP_PTROFFSET(pBt->usableSize, key); + if( pEType ) *pEType = pPtrmap[offset]; + if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); + + sqlite3pager_unref(pPtrmap); + if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT; + return SQLITE_OK; +} + +#endif /* SQLITE_OMIT_AUTOVACUUM */ + /* ** Given a btree page and a cell index (0 means the first cell on ** the page, 1 means the second cell, and so forth) return a pointer @@ -514,6 +664,36 @@ static int cellSizePtr(MemPage *pPage, u8 *pCell){ return info.nSize; } +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** If the cell pCell, part of page pPage contains a pointer +** to an overflow page, insert an entry into the pointer-map +** for the overflow page. +*/ +static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ + if( pCell ){ + CellInfo info; + parseCellPtr(pPage, pCell, &info); + if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ + Pgno ovfl = get4byte(&pCell[info.iOverflow]); + return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno); + } + } + return SQLITE_OK; +} +/* +** If the cell with index iCell on page pPage contains a pointer +** to an overflow page, insert an entry into the pointer-map +** for the overflow page. +*/ +static int ptrmapPutOvfl(MemPage *pPage, int iCell){ + u8 *pCell; + pCell = findOverflowCell(pPage, iCell); + return ptrmapPutOvflPtr(pPage, pCell); +} +#endif + + /* ** Do sanity checking on a page. Throw an exception if anything is ** not right. @@ -533,7 +713,7 @@ static void _pageIntegrity(MemPage *pPage){ used = sqliteMallocRaw( pPage->pBt->pageSize ); if( used==0 ) return; usableSize = pPage->pBt->usableSize; - assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] ); + assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->psAligned] ); hdr = pPage->hdrOffset; assert( hdr==(pPage->pgno==1 ? 100 : 0) ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); @@ -824,7 +1004,6 @@ static int initPage( MemPage *pParent /* The parent. Might be NULL */ ){ int pc; /* Address of a freeblock within pPage->aData[] */ - int i; /* Loop counter */ int hdr; /* Offset to beginning of page header */ u8 *data; /* Equal to pPage->aData */ Btree *pBt; /* The main btree structure */ @@ -837,7 +1016,7 @@ static int initPage( assert( pBt!=0 ); assert( pParent==0 || pParent->pBt==pBt ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); - assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] ); + assert( pPage->aData == &((unsigned char*)pPage)[-pBt->psAligned] ); if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ /* The parent page should never change unless the file is corrupt */ return SQLITE_CORRUPT; /* bkpt-CORRUPT */ @@ -868,17 +1047,12 @@ static int initPage( /* Compute the total free space on the page */ pc = get2byte(&data[hdr+1]); nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell); - i = 0; while( pc>0 ){ int next, size; if( pc>usableSize-4 ){ /* Free block is off the page */ return SQLITE_CORRUPT; /* bkpt-CORRUPT */ } - if( i++>SQLITE_MAX_PAGE_SIZE/4 ){ - /* The free block list forms an infinite loop */ - return SQLITE_CORRUPT; /* bkpt-CORRUPT */ - } next = get2byte(&data[pc]); size = get2byte(&data[pc+2]); if( next>0 && next<=pc+size+3 ){ @@ -910,7 +1084,7 @@ static void zeroPage(MemPage *pPage, int flags){ int first; assert( sqlite3pager_pagenumber(data)==pPage->pgno ); - assert( &data[pBt->pageSize] == (unsigned char*)pPage ); + assert( &data[pBt->psAligned] == (unsigned char*)pPage ); assert( sqlite3pager_iswriteable(data) ); memset(&data[hdr], 0, pBt->usableSize - hdr); data[hdr] = flags; @@ -939,7 +1113,7 @@ static int getPage(Btree *pBt, Pgno pgno, MemPage **ppPage){ MemPage *pPage; rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData); if( rc ) return rc; - pPage = (MemPage*)&aData[pBt->pageSize]; + pPage = (MemPage*)&aData[pBt->psAligned]; pPage->aData = aData; pPage->pBt = pBt; pPage->pgno = pgno; @@ -978,7 +1152,7 @@ static void releasePage(MemPage *pPage){ if( pPage ){ assert( pPage->aData ); assert( pPage->pBt ); - assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage ); + assert( &pPage->aData[pPage->pBt->psAligned]==(unsigned char*)pPage ); sqlite3pager_unref(pPage->aData); } } @@ -989,7 +1163,7 @@ static void releasePage(MemPage *pPage){ ** happens. */ static void pageDestructor(void *pData, int pageSize){ - MemPage *pPage = (MemPage*)&((char*)pData)[pageSize]; + MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)]; if( pPage->pParent ){ MemPage *pParent = pPage->pParent; pPage->pParent = 0; @@ -1007,7 +1181,7 @@ static void pageDestructor(void *pData, int pageSize){ ** page to agree with the restored data. */ static void pageReinit(void *pData, int pageSize){ - MemPage *pPage = (MemPage*)&((char*)pData)[pageSize]; + MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)]; if( pPage->isInit ){ pPage->isInit = 0; initPage(pPage, pPage->pParent); @@ -1049,8 +1223,7 @@ int sqlite3BtreeOpen( *ppBtree = 0; return SQLITE_NOMEM; } - rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, - (flags & BTREE_OMIT_JOURNAL)==0); + rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags); if( rc!=SQLITE_OK ){ if( pBt->pPager ) sqlite3pager_close(pBt->pPager); sqliteFree(pBt); @@ -1069,6 +1242,21 @@ int sqlite3BtreeOpen( pBt->maxEmbedFrac = 64; /* 25% */ pBt->minEmbedFrac = 32; /* 12.5% */ pBt->minLeafFrac = 32; /* 12.5% */ +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the magic name ":memory:" will create an in-memory database, then + ** do not set the auto-vacuum flag, even if SQLITE_DEFAULT_AUTOVACUUM + ** is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined, + ** then ":memory:" is just a regular file-name. Respect the auto-vacuum + ** default in this case. + */ +#ifndef SQLITE_OMIT_MEMORYDB + if( zFilename && strcmp(zFilename,":memory:") ){ +#else + if( zFilename ){ +#endif + pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM; + } +#endif nReserve = 0; }else{ nReserve = zDbHeader[20]; @@ -1076,8 +1264,12 @@ int sqlite3BtreeOpen( pBt->minEmbedFrac = zDbHeader[22]; pBt->minLeafFrac = zDbHeader[23]; pBt->pageSizeFixed = 1; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); +#endif } pBt->usableSize = pBt->pageSize - nReserve; + pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize); sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize); *ppBtree = pBt; return SQLITE_OK; @@ -1131,13 +1323,28 @@ int sqlite3BtreeSetCacheSize(Btree *pBt, int mxPage){ ** is a very low but non-zero probability of damage. Level 3 reduces the ** probability of damage to near zero but with a write performance reduction. */ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){ sqlite3pager_set_safety_level(pBt->pPager, level); return SQLITE_OK; } +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Change the default pages size and the number of reserved bytes per page. +** +** The page size must be a power of 2 between 512 and 65536. If the page +** size supplied does not meet this constraint then the page size is not +** changed. +** +** Page sizes are constrained to be a power of two so that the region +** of the database file used for locking (beginning at PENDING_BYTE, +** the first byte past the 1GB boundary, 0x40000000) needs to occur +** at the beginning of a page. +** +** If parameter nReserve is less than zero, then the number of reserved +** bytes per page is left unchanged. */ int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){ if( pBt->pageSizeFixed ){ @@ -1146,8 +1353,10 @@ int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){ if( nReserve<0 ){ nReserve = pBt->pageSize - pBt->usableSize; } - if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ){ + if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && + ((pageSize-1)&pageSize)==0 ){ pBt->pageSize = pageSize; + pBt->psAligned = FORCE_ALIGNMENT(pageSize); sqlite3pager_set_pagesize(pBt->pPager, pageSize); } pBt->usableSize = pBt->pageSize - nReserve; @@ -1163,6 +1372,38 @@ int sqlite3BtreeGetPageSize(Btree *pBt){ int sqlite3BtreeGetReserve(Btree *pBt){ return pBt->pageSize - pBt->usableSize; } +#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */ + +/* +** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' +** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it +** is disabled. The default value for the auto-vacuum property is +** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. +*/ +int sqlite3BtreeSetAutoVacuum(Btree *pBt, int autoVacuum){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return SQLITE_READONLY; +#else + if( pBt->pageSizeFixed ){ + return SQLITE_READONLY; + } + pBt->autoVacuum = (autoVacuum?1:0); + return SQLITE_OK; +#endif +} + +/* +** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** enabled 1 is returned. Otherwise 0. +*/ +int sqlite3BtreeGetAutoVacuum(Btree *pBt){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return 0; +#else + return pBt->autoVacuum; +#endif +} + /* ** Get a reference to pPage1 of the database file. This will @@ -1199,9 +1440,13 @@ static int lockBtree(Btree *pBt){ if( pBt->usableSize<500 ){ goto page1_init_failed; } + pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize); pBt->maxEmbedFrac = page1[21]; pBt->minEmbedFrac = page1[22]; pBt->minLeafFrac = page1[23]; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); +#endif } /* maxLocal is the maximum amount of payload to store locally for @@ -1248,7 +1493,7 @@ static void unlockBtreeIfUnused(Btree *pBt){ if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){ if( pBt->pPage1->aData==0 ){ MemPage *pPage = pBt->pPage1; - pPage->aData = &((char*)pPage)[-pBt->pageSize]; + pPage->aData = &((char*)pPage)[-pBt->psAligned]; pPage->pBt = pBt; pPage->pgno = 1; } @@ -1284,6 +1529,11 @@ static int newDatabase(Btree *pBt){ memset(&data[24], 0, 100-24); zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); pBt->pageSizeFixed = 1; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + put4byte(&data[36 + 4*4], 1); + } +#endif return SQLITE_OK; } @@ -1348,6 +1598,304 @@ int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){ return rc; } +#ifndef SQLITE_OMIT_AUTOVACUUM + +/* +** Set the pointer-map entries for all children of page pPage. Also, if +** pPage contains cells that point to overflow pages, set the pointer +** map entries for the overflow pages as well. +*/ +static int setChildPtrmaps(MemPage *pPage){ + int i; /* Counter variable */ + int nCell; /* Number of cells in page pPage */ + int rc = SQLITE_OK; /* Return code */ + Btree *pBt = pPage->pBt; + int isInitOrig = pPage->isInit; + Pgno pgno = pPage->pgno; + + initPage(pPage, 0); + nCell = pPage->nCell; + + for(i=0; ileaf ){ + Pgno childPgno = get4byte(pCell); + rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); + if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out; + } + } + + if( !pPage->leaf ){ + Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); + } + +set_child_ptrmaps_out: + pPage->isInit = isInitOrig; + return rc; +} + +/* +** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow +** page, is a pointer to page iFrom. Modify this pointer so that it points to +** iTo. Parameter eType describes the type of pointer to be modified, as +** follows: +** +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** page of pPage. +** +** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow +** page pointed to by one of the cells on pPage. +** +** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next +** overflow page in the list. +*/ +static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ + if( eType==PTRMAP_OVERFLOW2 ){ + /* The pointer is always the first 4 bytes of the page in this case. */ + if( get4byte(pPage->aData)!=iFrom ){ + return SQLITE_CORRUPT; + } + put4byte(pPage->aData, iTo); + }else{ + int isInitOrig = pPage->isInit; + int i; + int nCell; + + initPage(pPage, 0); + nCell = pPage->nCell; + + for(i=0; iaData[pPage->hdrOffset+8])!=iFrom ){ + return SQLITE_CORRUPT; + } + put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); + } + + pPage->isInit = isInitOrig; + } + return SQLITE_OK; +} + + +/* +** Move the open database page pDbPage to location iFreePage in the +** database. The pDbPage reference remains valid. +*/ +static int relocatePage( + Btree *pBt, /* Btree */ + MemPage *pDbPage, /* Open page to move */ + u8 eType, /* Pointer map 'type' entry for pDbPage */ + Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ + Pgno iFreePage /* The location to move pDbPage to */ +){ + MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ + Pgno iDbPage = pDbPage->pgno; + Pager *pPager = pBt->pPager; + int rc; + + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); + + /* Move page iDbPage from it's current location to page number iFreePage */ + TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", + iDbPage, iFreePage, iPtrPage, eType)); + rc = sqlite3pager_movepage(pPager, pDbPage->aData, iFreePage); + if( rc!=SQLITE_OK ){ + return rc; + } + pDbPage->pgno = iFreePage; + + /* If pDbPage was a btree-page, then it may have child pages and/or cells + ** that point to overflow pages. The pointer map entries for all these + ** pages need to be changed. + ** + ** If pDbPage is an overflow page, then the first 4 bytes may store a + ** pointer to a subsequent overflow page. If this is the case, then + ** the pointer map needs to be updated for the subsequent overflow page. + */ + if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ + rc = setChildPtrmaps(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + Pgno nextOvfl = get4byte(pDbPage->aData); + if( nextOvfl!=0 ){ + rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } + + /* Fix the database pointer on page iPtrPage that pointed at iDbPage so + ** that it points at iFreePage. Also fix the pointer map entry for + ** iPtrPage. + */ + if( eType!=PTRMAP_ROOTPAGE ){ + rc = getPage(pBt, iPtrPage, &pPtrPage); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3pager_write(pPtrPage->aData); + if( rc!=SQLITE_OK ){ + releasePage(pPtrPage); + return rc; + } + rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); + releasePage(pPtrPage); + if( rc==SQLITE_OK ){ + rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage); + } + } + return rc; +} + +/* Forward declaration required by autoVacuumCommit(). */ +static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8); + +/* +** This routine is called prior to sqlite3pager_commit when a transaction +** is commited for an auto-vacuum database. +*/ +static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){ + Pager *pPager = pBt->pPager; + Pgno nFreeList; /* Number of pages remaining on the free-list. */ + int nPtrMap; /* Number of pointer-map pages deallocated */ + Pgno origSize; /* Pages in the database file */ + Pgno finSize; /* Pages in the database file after truncation */ + int rc; /* Return code */ + u8 eType; + int pgsz = pBt->pageSize; /* Page size for this database */ + Pgno iDbPage; /* The database page to move */ + MemPage *pDbMemPage = 0; /* "" */ + Pgno iPtrPage; /* The page that contains a pointer to iDbPage */ + Pgno iFreePage; /* The free-list page to move iDbPage to */ + MemPage *pFreeMemPage = 0; /* "" */ + +#ifndef NDEBUG + int nRef = *sqlite3pager_stats(pPager); +#endif + + assert( pBt->autoVacuum ); + if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){ + return SQLITE_CORRUPT; + } + + /* Figure out how many free-pages are in the database. If there are no + ** free pages, then auto-vacuum is a no-op. + */ + nFreeList = get4byte(&pBt->pPage1->aData[36]); + if( nFreeList==0 ){ + *nTrunc = 0; + return SQLITE_OK; + } + + origSize = sqlite3pager_pagecount(pPager); + nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5); + finSize = origSize - nFreeList - nPtrMap; + if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){ + finSize--; + if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){ + finSize--; + } + } + TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize)); + + /* Variable 'finSize' will be the size of the file in pages after + ** the auto-vacuum has completed (the current file size minus the number + ** of pages on the free list). Loop through the pages that lie beyond + ** this mark, and if they are not already on the free list, move them + ** to a free page earlier in the file (somewhere before finSize). + */ + for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){ + /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */ + if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){ + continue; + } + + rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage); + if( rc!=SQLITE_OK ) goto autovacuum_out; + assert( eType!=PTRMAP_ROOTPAGE ); + + /* If iDbPage is free, do not swap it. */ + if( eType==PTRMAP_FREEPAGE ){ + continue; + } + rc = getPage(pBt, iDbPage, &pDbMemPage); + if( rc!=SQLITE_OK ) goto autovacuum_out; + + /* Find the next page in the free-list that is not already at the end + ** of the file. A page can be pulled off the free list using the + ** allocatePage() routine. + */ + do{ + if( pFreeMemPage ){ + releasePage(pFreeMemPage); + pFreeMemPage = 0; + } + rc = allocatePage(pBt, &pFreeMemPage, &iFreePage, 0, 0); + if( rc!=SQLITE_OK ){ + releasePage(pDbMemPage); + goto autovacuum_out; + } + assert( iFreePage<=origSize ); + }while( iFreePage>finSize ); + releasePage(pFreeMemPage); + pFreeMemPage = 0; + + rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage); + releasePage(pDbMemPage); + if( rc!=SQLITE_OK ) goto autovacuum_out; + } + + /* The entire free-list has been swapped to the end of the file. So + ** truncate the database file to finSize pages and consider the + ** free-list empty. + */ + rc = sqlite3pager_write(pBt->pPage1->aData); + if( rc!=SQLITE_OK ) goto autovacuum_out; + put4byte(&pBt->pPage1->aData[32], 0); + put4byte(&pBt->pPage1->aData[36], 0); + if( rc!=SQLITE_OK ) goto autovacuum_out; + *nTrunc = finSize; + +autovacuum_out: + assert( nRef==*sqlite3pager_stats(pPager) ); + if( rc!=SQLITE_OK ){ + sqlite3pager_rollback(pPager); + } + return rc; +} +#endif + /* ** Commit the transaction currently in progress. ** @@ -1381,25 +1929,6 @@ static int countWriteCursors(Btree *pBt){ } #endif -#if 0 -/* -** Invalidate all cursors -*/ -static void invalidateCursors(Btree *pBt){ - BtCursor *pCur; - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - MemPage *pPage = pCur->pPage; - if( pPage /* && !pPage->isInit */ ){ - pageIntegrity(pPage); - releasePage(pPage); - pCur->pPage = 0; - pCur->isValid = 0; - pCur->status = SQLITE_ABORT; - } - } -} -#endif - #ifdef SQLITE_TEST /* ** Print debugging information about all cursors to standard output. @@ -1618,7 +2147,6 @@ int sqlite3BtreeCursor( pCur->pPrev = 0; pBt->pCursor = pCur; pCur->isValid = 0; - pCur->status = SQLITE_OK; *ppCur = pCur; return SQLITE_OK; @@ -1845,9 +2373,7 @@ static int getPayload( ** the available payload. */ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - if( pCur->isValid==0 ){ - return pCur->status; - } + assert( pCur->isValid ); assert( pCur->pPage!=0 ); assert( pCur->pPage->intKey==0 ); assert( pCur->idx>=0 && pCur->idxpPage->nCell ); @@ -1864,9 +2390,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ ** the available payload. */ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - if( !pCur->isValid ){ - return pCur->status ? pCur->status : SQLITE_INTERNAL; - } + assert( pCur->isValid ); assert( pCur->pPage!=0 ); assert( pCur->idx>=0 && pCur->idxpPage->nCell ); return getPayload(pCur, offset, amt, pBuf, 1); @@ -2104,9 +2628,6 @@ static int moveToRightmost(BtCursor *pCur){ */ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ int rc; - if( pCur->status ){ - return pCur->status; - } rc = moveToRoot(pCur); if( rc ) return rc; if( pCur->isValid==0 ){ @@ -2126,9 +2647,6 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ */ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ int rc; - if( pCur->status ){ - return pCur->status; - } rc = moveToRoot(pCur); if( rc ) return rc; if( pCur->isValid==0 ){ @@ -2171,10 +2689,6 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ */ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ int rc; - - if( pCur->status ){ - return pCur->status; - } rc = moveToRoot(pCur); if( rc ) return rc; assert( pCur->pPage ); @@ -2184,13 +2698,16 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ assert( pCur->pPage->nCell==0 ); return SQLITE_OK; } - for(;;){ + for(;;){ int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->pPage; int c = -1; /* pRes return if table is empty must be -1 */ lwr = 0; upr = pPage->nCell-1; + if( !pPage->intKey && pKey==0 ){ + return SQLITE_CORRUPT; + } pageIntegrity(pPage); while( lwr<=upr ){ void *pCellKey; @@ -2288,6 +2805,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ } assert( pPage->isInit ); assert( pCur->idxnCell ); + pCur->idx++; pCur->info.nSize = 0; if( pCur->idx>=pPage->nCell ){ @@ -2337,6 +2855,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ *pRes = 1; return SQLITE_OK; } + pPage = pCur->pPage; assert( pPage->isInit ); assert( pCur->idx>=0 ); @@ -2357,7 +2876,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ } pCur->idx--; pCur->info.nSize = 0; - if( pPage->leafData ){ + if( pPage->leafData && !pPage->leaf ){ rc = sqlite3BtreePrevious(pCur, pRes); }else{ rc = SQLITE_OK; @@ -2367,19 +2886,6 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ return rc; } -/* -** The TRACE macro will print high-level status information about the -** btree operation when the global variable sqlite3_btree_trace is -** enabled. -*/ -#if SQLITE_TEST -# define TRACE(X) if( sqlite3_btree_trace )\ - { sqlite3DebugPrintf X; fflush(stdout); } -#else -# define TRACE(X) -#endif -int sqlite3_btree_trace=0; /* True to enable tracing */ - /* ** Allocate a new page from the database file. ** @@ -2396,8 +2902,18 @@ int sqlite3_btree_trace=0; /* True to enable tracing */ ** locate a page close to the page number "nearby". This can be used in an ** attempt to keep related pages close to each other in the database file, ** which in turn can make database access faster. +** +** If the "exact" parameter is not 0, and the page-number nearby exists +** anywhere on the free-list, then it is guarenteed to be returned. This +** is only used by auto-vacuum databases when allocating a new table. */ -static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno, Pgno nearby){ +static int allocatePage( + Btree *pBt, + MemPage **ppPage, + Pgno *pPgno, + Pgno nearby, + u8 exact +){ MemPage *pPage1; int rc; int n; /* Number of pages on the freelist */ @@ -2407,72 +2923,200 @@ static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno, Pgno nearby){ n = get4byte(&pPage1->aData[36]); if( n>0 ){ /* There are pages on the freelist. Reuse one of those pages. */ - MemPage *pTrunk; + MemPage *pTrunk = 0; + Pgno iTrunk; + MemPage *pPrevTrunk = 0; + u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ + + /* If the 'exact' parameter was true and a query of the pointer-map + ** shows that the page 'nearby' is somewhere on the free-list, then + ** the entire-list will be searched for that page. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( exact ){ + u8 eType; + assert( nearby>0 ); + assert( pBt->autoVacuum ); + rc = ptrmapGet(pBt, nearby, &eType, 0); + if( rc ) return rc; + if( eType==PTRMAP_FREEPAGE ){ + searchList = 1; + } + *pPgno = nearby; + } +#endif + + /* Decrement the free-list count by 1. Set iTrunk to the index of the + ** first free-list trunk page. iPrevTrunk is initially 1. + */ rc = sqlite3pager_write(pPage1->aData); if( rc ) return rc; put4byte(&pPage1->aData[36], n-1); - rc = getPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk); - if( rc ) return rc; - rc = sqlite3pager_write(pTrunk->aData); - if( rc ){ - releasePage(pTrunk); - return rc; - } - k = get4byte(&pTrunk->aData[4]); - if( k==0 ){ - /* The trunk has no leaves. So extract the trunk page itself and - ** use it as the newly allocated page */ - *pPgno = get4byte(&pPage1->aData[32]); - memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); - *ppPage = pTrunk; - TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); - }else if( k>pBt->usableSize/4 - 8 ){ - /* Value of k is out of range. Database corruption */ - return SQLITE_CORRUPT; /* bkpt-CORRUPT */ - }else{ - /* Extract a leaf from the trunk */ - int closest; - unsigned char *aData = pTrunk->aData; - if( nearby>0 ){ - int i, dist; - closest = 0; - dist = get4byte(&aData[8]) - nearby; - if( dist<0 ) dist = -dist; - for(i=1; iaData[0]); }else{ - closest = 0; + iTrunk = get4byte(&pPage1->aData[32]); } - *pPgno = get4byte(&aData[8+closest*4]); - if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){ - /* Free page off the end of the file */ - return SQLITE_CORRUPT; /* bkpt-CORRUPT */ + rc = getPage(pBt, iTrunk, &pTrunk); + if( rc ){ + releasePage(pPrevTrunk); + return rc; } - TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d: %d more free pages\n", - *pPgno, closest+1, k, pTrunk->pgno, n-1)); - if( closestaData); + if( rc ){ + releasePage(pTrunk); + releasePage(pPrevTrunk); + return rc; } - put4byte(&aData[4], k-1); - rc = getPage(pBt, *pPgno, ppPage); - releasePage(pTrunk); - if( rc==SQLITE_OK ){ - sqlite3pager_dont_rollback((*ppPage)->aData); - rc = sqlite3pager_write((*ppPage)->aData); + + k = get4byte(&pTrunk->aData[4]); + if( k==0 && !searchList ){ + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly + ** allocated page */ + assert( pPrevTrunk==0 ); + *pPgno = iTrunk; + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + *ppPage = pTrunk; + pTrunk = 0; + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); + }else if( k>pBt->usableSize/4 - 8 ){ + /* Value of k is out of range. Database corruption */ + return SQLITE_CORRUPT; /* bkpt-CORRUPT */ +#ifndef SQLITE_OMIT_AUTOVACUUM + }else if( searchList && nearby==iTrunk ){ + /* The list is being searched and this trunk page is the page + ** to allocate, regardless of whether it has leaves. + */ + assert( *pPgno==iTrunk ); + *ppPage = pTrunk; + searchList = 0; + if( k==0 ){ + if( !pPrevTrunk ){ + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + }else{ + memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); + } + }else{ + /* The trunk page is required by the caller but it contains + ** pointers to free-list leaves. The first leaf becomes a trunk + ** page in this case. + */ + MemPage *pNewTrunk; + Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); + rc = getPage(pBt, iNewTrunk, &pNewTrunk); + if( rc!=SQLITE_OK ){ + releasePage(pTrunk); + releasePage(pPrevTrunk); + return rc; + } + rc = sqlite3pager_write(pNewTrunk->aData); + if( rc!=SQLITE_OK ){ + releasePage(pNewTrunk); + releasePage(pTrunk); + releasePage(pPrevTrunk); + return rc; + } + memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); + put4byte(&pNewTrunk->aData[4], k-1); + memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + if( !pPrevTrunk ){ + put4byte(&pPage1->aData[32], iNewTrunk); + }else{ + put4byte(&pPrevTrunk->aData[0], iNewTrunk); + } + releasePage(pNewTrunk); + } + pTrunk = 0; + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); +#endif + }else{ + /* Extract a leaf from the trunk */ + int closest; + Pgno iPage; + unsigned char *aData = pTrunk->aData; + if( nearby>0 ){ + int i, dist; + closest = 0; + dist = get4byte(&aData[8]) - nearby; + if( dist<0 ) dist = -dist; + for(i=1; isqlite3pager_pagecount(pBt->pPager) ){ + /* Free page off the end of the file */ + return SQLITE_CORRUPT; /* bkpt-CORRUPT */ + } + TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" + ": %d more free pages\n", + *pPgno, closest+1, k, pTrunk->pgno, n-1)); + if( closestaData); + rc = sqlite3pager_write((*ppPage)->aData); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + } + searchList = 0; + } } - } + releasePage(pPrevTrunk); + }while( searchList ); + releasePage(pTrunk); }else{ /* There are no pages on the freelist, so create a new page at the ** end of the file */ *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1; + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){ + /* If *pPgno refers to a pointer-map page, allocate two new pages + ** at the end of the file instead of one. The first allocated page + ** becomes a new pointer-map page, the second is used by the caller. + */ + TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno)); + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + (*pPgno)++; + } +#endif + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); rc = getPage(pBt, *pPgno, ppPage); if( rc ) return rc; rc = sqlite3pager_write((*ppPage)->aData); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); } + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); return rc; } @@ -2498,6 +3142,16 @@ static int freePage(MemPage *pPage){ n = get4byte(&pPage1->aData[36]); put4byte(&pPage1->aData[36], n+1); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, write an entry in the pointer-map + ** to indicate that the page is free. + */ + if( pBt->autoVacuum ){ + rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0); + if( rc ) return rc; + } +#endif + if( n==0 ){ /* This is the first free page */ rc = sqlite3pager_write(pPage->aData); @@ -2552,6 +3206,9 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ ovflPgno = get4byte(&pCell[info.iOverflow]); while( ovflPgno!=0 ){ MemPage *pOvfl; + if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){ + return SQLITE_CORRUPT; + } rc = getPage(pBt, ovflPgno, &pOvfl); if( rc ) return rc; ovflPgno = get4byte(pOvfl->aData); @@ -2628,10 +3285,23 @@ static int fillInCell( while( nPayload>0 ){ if( spaceLeft==0 ){ - rc = allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl); +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ +#endif + rc = allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, and the second or subsequent + ** overflow page is being allocated, add an entry to the pointer-map + ** for that page now. The entry for the first overflow page will be + ** added later, by the insertCell() routine. + */ + if( pBt->autoVacuum && pgnoPtrmap!=0 && rc==SQLITE_OK ){ + rc = ptrmapPut(pBt, pgnoOvfl, PTRMAP_OVERFLOW2, pgnoPtrmap); + } +#endif if( rc ){ releasePage(pToRelease); - clearCell(pPage, pCell); + /* clearCell(pPage, pCell); */ return rc; } put4byte(pPrior, pgnoOvfl); @@ -2665,15 +3335,15 @@ static int fillInCell( ** given in the second argument so that MemPage.pParent holds the ** pointer in the third argument. */ -static void reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ +static int reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ MemPage *pThis; unsigned char *aData; - if( pgno==0 ) return; + if( pgno==0 ) return SQLITE_OK; assert( pBt->pPager!=0 ); aData = sqlite3pager_lookup(pBt->pPager, pgno); if( aData ){ - pThis = (MemPage*)&aData[pBt->pageSize]; + pThis = (MemPage*)&aData[pBt->psAligned]; assert( pThis->aData==aData ); if( pThis->isInit ){ if( pThis->pParent!=pNewParent ){ @@ -2685,8 +3355,17 @@ static void reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ } sqlite3pager_unref(aData); } + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno); + } +#endif + return SQLITE_OK; } + + /* ** Change the pParent pointer of all children of pPage to point back ** to pPage. @@ -2697,17 +3376,26 @@ static void reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ ** This routine gets called after you memcpy() one page into ** another. */ -static void reparentChildPages(MemPage *pPage){ +static int reparentChildPages(MemPage *pPage){ int i; - Btree *pBt; + Btree *pBt = pPage->pBt; + int rc = SQLITE_OK; + + if( pPage->leaf ) return SQLITE_OK; - if( pPage->leaf ) return; - pBt = pPage->pBt; for(i=0; inCell; i++){ - reparentPage(pBt, get4byte(findCell(pPage,i)), pPage, i); + u8 *pCell = findCell(pPage, i); + if( !pPage->leaf ){ + rc = reparentPage(pBt, get4byte(pCell), pPage, i); + if( rc!=SQLITE_OK ) return rc; + } } - reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), pPage, i); - pPage->idxShift = 0; + if( !pPage->leaf ){ + rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), + pPage, i); + pPage->idxShift = 0; + } + return rc; } /* @@ -2753,13 +3441,19 @@ static void dropCell(MemPage *pPage, int idx, int sz){ ** in pTemp or the original pCell) and also record its index. ** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. +** +** If nSkip is non-zero, then do not copy the first nSkip bytes of the +** cell. The caller will overwrite them after this function returns. If +** nSkip is non-zero, then pCell may not point to an invalid memory location +** (but pCell+nSkip is always valid). */ -static void insertCell( +static int insertCell( MemPage *pPage, /* Page into which we are copying */ int i, /* New cell becomes the i-th cell of the page */ u8 *pCell, /* Content of the new cell */ int sz, /* Bytes of content in pCell */ - u8 *pTemp /* Temp storage space for pCell, if needed */ + u8 *pTemp, /* Temp storage space for pCell, if needed */ + u8 nSkip /* Do not write the first nSkip bytes of the cell */ ){ int idx; /* Where to write new cell content in data[] */ int j; /* Loop counter */ @@ -2776,7 +3470,7 @@ static void insertCell( assert( sqlite3pager_iswriteable(pPage->aData) ); if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ - memcpy(pTemp, pCell, sz); + memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); pCell = pTemp; } j = pPage->nOverflow++; @@ -2801,7 +3495,7 @@ static void insertCell( assert( end <= get2byte(&data[hdr+5]) ); pPage->nCell++; pPage->nFree -= 2; - memcpy(&data[idx], pCell, sz); + memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){ ptr[0] = ptr[-2]; ptr[1] = ptr[-1]; @@ -2810,7 +3504,23 @@ static void insertCell( put2byte(&data[hdr+3], pPage->nCell); pPage->idxShift = 1; pageIntegrity(pPage); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + CellInfo info; + parseCellPtr(pPage, pCell, &info); + if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ + Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); + int rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno); + if( rc!=SQLITE_OK ) return rc; + } + } +#endif } + + return SQLITE_OK; } /* @@ -2855,14 +3565,6 @@ static void assemblePage( pPage->nCell = nCell; } -/* -** GCC does not define the offsetof() macro so we'll have to do it -** ourselves. -*/ -#ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) -#endif - /* ** The following parameters determine how many adjacent pages get involved ** in a balancing operation. NN is the number of neighbors on either side @@ -2879,7 +3581,110 @@ static void assemblePage( #define NB (NN*2+1) /* Total pages involved in the balance */ /* Forward reference */ -static int balance(MemPage*); +static int balance(MemPage*, int); + +#ifndef SQLITE_OMIT_QUICKBALANCE +/* +** This version of balance() handles the common special case where +** a new entry is being inserted on the extreme right-end of the +** tree, in other words, when the new entry will become the largest +** entry in the tree. +** +** Instead of trying balance the 3 right-most leaf pages, just add +** a new page to the right-hand side and put the one new entry in +** that page. This leaves the right side of the tree somewhat +** unbalanced. But odds are that we will be inserting new entries +** at the end soon afterwards so the nearly empty page will quickly +** fill up. On average. +** +** pPage is the leaf page which is the right-most page in the tree. +** pParent is its parent. pPage must have a single overflow entry +** which is also the right-most entry on the page. +*/ +static int balance_quick(MemPage *pPage, MemPage *pParent){ + int rc; + MemPage *pNew; + Pgno pgnoNew; + u8 *pCell; + int szCell; + CellInfo info; + Btree *pBt = pPage->pBt; + int parentIdx = pParent->nCell; /* pParent new divider cell index */ + int parentSize; /* Size of new divider cell */ + u8 parentCell[64]; /* Space for the new divider cell */ + + /* Allocate a new page. Insert the overflow cell from pPage + ** into it. Then remove the overflow cell from pPage. + */ + rc = allocatePage(pBt, &pNew, &pgnoNew, 0, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + pCell = pPage->aOvfl[0].pCell; + szCell = cellSizePtr(pPage, pCell); + zeroPage(pNew, pPage->aData[0]); + assemblePage(pNew, 1, &pCell, &szCell); + pPage->nOverflow = 0; + + /* Set the parent of the newly allocated page to pParent. */ + pNew->pParent = pParent; + sqlite3pager_ref(pParent->aData); + + /* pPage is currently the right-child of pParent. Change this + ** so that the right-child is the new page allocated above and + ** pPage is the next-to-right child. + */ + assert( pPage->nCell>0 ); + parseCellPtr(pPage, findCell(pPage, pPage->nCell-1), &info); + rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, &parentSize); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( parentSize<64 ); + rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4); + if( rc!=SQLITE_OK ){ + return rc; + } + put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno); + put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. + */ + if( pBt->autoVacuum ){ + rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapPutOvfl(pNew, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + } +#endif + + /* Release the reference to the new page and balance the parent page, + ** in case the divider cell inserted caused it to become overfull. + */ + releasePage(pNew); + return balance(pParent, 0); +} +#endif /* SQLITE_OMIT_QUICKBALANCE */ + +/* +** The ISAUTOVACUUM macro is used within balance_nonroot() to determine +** if the database supports auto-vacuum or not. Because it is used +** within an expression that is an argument to another macro +** (sqliteMallocRaw), it is not possible to use conditional compilation. +** So, this macro is defined instead. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define ISAUTOVACUUM (pBt->autoVacuum) +#else +#define ISAUTOVACUUM 0 +#endif /* ** This routine redistributes Cells on pPage and up to NN*2 siblings @@ -2941,6 +3746,9 @@ static int balance_nonroot(MemPage *pPage){ int *szCell; /* Local size of all cells in apCell[] */ u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ u8 *aSpace; /* Space to hold copies of dividers cells */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 *aFrom = 0; +#endif /* ** Find the parent page. @@ -2953,6 +3761,31 @@ static int balance_nonroot(MemPage *pPage){ assert( pParent ); TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); +#ifndef SQLITE_OMIT_QUICKBALANCE + /* + ** A special case: If a new entry has just been inserted into a + ** table (that is, a btree with integer keys and all data at the leaves) + ** an the new entry is the right-most entry in the tree (it has the + ** largest key) then use the special balance_quick() routine for + ** balancing. balance_quick() is much faster and results in a tighter + ** packing of data in the common case. + */ + if( pPage->leaf && + pPage->intKey && + pPage->leafData && + pPage->nOverflow==1 && + pPage->aOvfl[0].idx==pPage->nCell && + pPage->pParent->pgno!=1 && + get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno + ){ + /* + ** TODO: Check the siblings to the left of pPage. It may be that + ** they are not full and no new page is required. + */ + return balance_quick(pPage, pParent); + } +#endif + /* ** Allocate space for memory structures */ @@ -2960,7 +3793,8 @@ static int balance_nonroot(MemPage *pPage){ apCell = sqliteMallocRaw( (mxCellPerPage+2)*NB*(sizeof(u8*)+sizeof(int)) + sizeof(MemPage)*NB - + pBt->pageSize*(5+NB) + + pBt->psAligned*(5+NB) + + (ISAUTOVACUUM ? (mxCellPerPage+2)*NN*2 : 0) ); if( apCell==0 ){ return SQLITE_NOMEM; @@ -2968,9 +3802,14 @@ static int balance_nonroot(MemPage *pPage){ szCell = (int*)&apCell[(mxCellPerPage+2)*NB]; aCopy[0] = (u8*)&szCell[(mxCellPerPage+2)*NB]; for(i=1; ipageSize+sizeof(MemPage)]; + aCopy[i] = &aCopy[i-1][pBt->psAligned+sizeof(MemPage)]; + } + aSpace = &aCopy[NB-1][pBt->psAligned+sizeof(MemPage)]; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + aFrom = &aSpace[5*pBt->psAligned]; } - aSpace = &aCopy[NB-1][pBt->pageSize+sizeof(MemPage)]; +#endif /* ** Find the cell in the parent page whose left child points back @@ -3041,10 +3880,10 @@ static int balance_nonroot(MemPage *pPage){ ** process of being overwritten. */ for(i=0; ipageSize]; - p->aData = &((u8*)p)[-pBt->pageSize]; - memcpy(p->aData, apOld[i]->aData, pBt->pageSize + sizeof(MemPage)); - p->aData = &((u8*)p)[-pBt->pageSize]; + MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->psAligned]; + p->aData = &((u8*)p)[-pBt->psAligned]; + memcpy(p->aData, apOld[i]->aData, pBt->psAligned + sizeof(MemPage)); + p->aData = &((u8*)p)[-pBt->psAligned]; } /* @@ -3072,6 +3911,18 @@ static int balance_nonroot(MemPage *pPage){ for(j=0; jautoVacuum ){ + int a; + aFrom[nCell] = i; + for(a=0; anOverflow; a++){ + if( pOld->aOvfl[a].pCell==apCell[nCell] ){ + aFrom[nCell] = 0xFF; + break; + } + } + } +#endif nCell++; } if( ipageSize*5 ); + assert( iSpace<=pBt->psAligned*5 ); memcpy(pTemp, apDiv[i], sz); apCell[nCell] = pTemp+leafCorrection; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + aFrom[nCell] = 0xFF; + } +#endif dropCell(pParent, nxDiv, sz); szCell[nCell] -= leafCorrection; assert( get4byte(pTemp)==pgnoOld[i] ); @@ -3179,9 +4035,10 @@ static int balance_nonroot(MemPage *pPage){ pNew = apNew[i] = apOld[i]; pgnoNew[i] = pgnoOld[i]; apOld[i] = 0; - sqlite3pager_write(pNew->aData); + rc = sqlite3pager_write(pNew->aData); + if( rc ) goto balance_cleanup; }else{ - rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1]); + rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0); if( rc ) goto balance_cleanup; apNew[i] = pNew; } @@ -3243,19 +4100,42 @@ static int balance_nonroot(MemPage *pPage){ nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0, nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0)); - /* ** Evenly distribute the data in apCell[] across the new pages. ** Insert divider cells into pParent as necessary. */ j = 0; for(i=0; ipgno==pgnoNew[i] ); assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]); - j = cntNew[i]; assert( pNew->nCell>0 ); assert( pNew->nOverflow==0 ); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If this is an auto-vacuum database, update the pointer map entries + ** that point to the siblings that were rearranged. These can be: left + ** children of cells, the right-child of the page, or overflow pages + ** pointed to by cells. + */ + if( pBt->autoVacuum ){ + for(k=j; kpgno!=pNew->pgno ){ + rc = ptrmapPutOvfl(pNew, k-j); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } + } + } +#endif + + j = cntNew[i]; + + /* If the sibling page assembled above was not the right-most sibling, + ** insert a divider cell into the parent page. + */ if( iaData[8], pCell, 4); pTemp = 0; }else if( leafData ){ + /* If the tree is a leaf-data tree, and the siblings are leaves, + ** then there is no divider cell in apCell[]. Instead, the divider + ** cell consists of the integer key for the right-most cell of + ** the sibling-page assembled above only. + */ CellInfo info; j--; parseCellPtr(pNew, apCell[j], &info); pCell = &aSpace[iSpace]; fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz); iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); + assert( iSpace<=pBt->psAligned*5 ); pTemp = 0; }else{ pCell -= 4; pTemp = &aSpace[iSpace]; iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); + assert( iSpace<=pBt->psAligned*5 ); } - insertCell(pParent, nxDiv, pCell, sz, pTemp); + rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); + if( rc!=SQLITE_OK ) goto balance_cleanup; put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If this is an auto-vacuum database, and not a leaf-data tree, + ** then update the pointer map with an entry for the overflow page + ** that the cell just inserted points to (if any). + */ + if( pBt->autoVacuum && !leafData ){ + rc = ptrmapPutOvfl(pParent, nxDiv); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } +#endif j++; nxDiv++; } @@ -3303,19 +4201,21 @@ static int balance_nonroot(MemPage *pPage){ ** Reparent children of all cells. */ for(i=0; iisInit ); /* assert( pPage->isInit ); // No! pPage might have been added to freelist */ /* pageIntegrity(pPage); // No! pPage might have been added to freelist */ - rc = balance(pParent); + rc = balance(pParent, 0); /* ** Cleanup before returning. @@ -3390,6 +4290,9 @@ static int balance_shallower(MemPage *pPage){ szCell[i] = cellSizePtr(pChild, apCell[i]); } assemblePage(pPage, pChild->nCell, apCell, szCell); + /* Copy the right-pointer of the child to the parent. */ + put4byte(&pPage->aData[pPage->hdrOffset+8], + get4byte(&pChild->aData[pChild->hdrOffset+8])); freePage(pChild); TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno)); }else{ @@ -3407,7 +4310,20 @@ static int balance_shallower(MemPage *pPage){ TRACE(("BALANCE: transfer child %d into root %d\n", pChild->pgno, pPage->pgno)); } - reparentChildPages(pPage); + rc = reparentChildPages(pPage); + assert( pPage->nOverflow==0 ); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + int i; + for(i=0; inCell; i++){ + rc = ptrmapPutOvfl(pPage, i); + if( rc!=SQLITE_OK ){ + goto end_shallow_balance; + } + } + } +#endif + if( rc!=SQLITE_OK ) goto end_shallow_balance; releasePage(pChild); } end_shallow_balance: @@ -3439,7 +4355,7 @@ static int balance_deeper(MemPage *pPage){ assert( pPage->pParent==0 ); assert( pPage->nOverflow>0 ); pBt = pPage->pBt; - rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno); + rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); if( rc ) return rc; assert( sqlite3pager_iswriteable(pChild->aData) ); usableSize = pBt->usableSize; @@ -3449,6 +4365,7 @@ static int balance_deeper(MemPage *pPage){ cdata = pChild->aData; memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr); memcpy(&cdata[brk], &data[brk], usableSize-brk); + assert( pChild->isInit==0 ); rc = initPage(pChild, pPage); if( rc ) return rc; memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0])); @@ -3460,6 +4377,19 @@ static int balance_deeper(MemPage *pPage){ zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild); TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno)); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + int i; + rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno); + if( rc ) return rc; + for(i=0; inCell; i++){ + rc = ptrmapPutOvfl(pChild, i); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } +#endif rc = balance_nonroot(pChild); releasePage(pChild); return rc; @@ -3469,17 +4399,18 @@ static int balance_deeper(MemPage *pPage){ ** Decide if the page pPage needs to be balanced. If balancing is ** required, call the appropriate balancing routine. */ -static int balance(MemPage *pPage){ +static int balance(MemPage *pPage, int insert){ int rc = SQLITE_OK; if( pPage->pParent==0 ){ if( pPage->nOverflow>0 ){ rc = balance_deeper(pPage); } - if( pPage->nCell==0 ){ + if( rc==SQLITE_OK && pPage->nCell==0 ){ rc = balance_shallower(pPage); } }else{ - if( pPage->nOverflow>0 || pPage->nFree>pPage->pBt->usableSize*2/3 ){ + if( pPage->nOverflow>0 || + (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){ rc = balance_nonroot(pPage); } } @@ -3535,9 +4466,6 @@ int sqlite3BtreeInsert( unsigned char *oldCell; unsigned char *newCell = 0; - if( pCur->status ){ - return pCur->status; /* A rollback destroyed this cursor */ - } if( pBt->inTrans!=TRANS_WRITE ){ /* Must start a transaction before doing an insert */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; @@ -3584,11 +4512,14 @@ int sqlite3BtreeInsert( }else{ assert( pPage->leaf ); } - insertCell(pPage, pCur->idx, newCell, szNew, 0); - rc = balance(pPage); + rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0); + if( rc!=SQLITE_OK ) goto end_insert; + rc = balance(pPage, 1); /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ /* fflush(stdout); */ - moveToRoot(pCur); + if( rc==SQLITE_OK ){ + moveToRoot(pCur); + } end_insert: sqliteFree(newCell); return rc; @@ -3606,9 +4537,6 @@ int sqlite3BtreeDelete(BtCursor *pCur){ Btree *pBt = pCur->pBt; assert( pPage->isInit ); - if( pCur->status ){ - return pCur->status; /* A rollback destroyed this cursor */ - } if( pBt->inTrans!=TRANS_WRITE ){ /* Must start a transaction before doing a delete */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; @@ -3625,11 +4553,18 @@ int sqlite3BtreeDelete(BtCursor *pCur){ } rc = sqlite3pager_write(pPage->aData); if( rc ) return rc; + + /* Locate the cell within it's page and leave pCell pointing to the + ** data. The clearCell() call frees any overflow pages associated with the + ** cell. The cell itself is still intact. + */ pCell = findCell(pPage, pCur->idx); if( !pPage->leaf ){ pgnoChild = get4byte(pCell); } - clearCell(pPage, pCell); + rc = clearCell(pPage, pCell); + if( rc ) return rc; + if( !pPage->leaf ){ /* ** The entry we are about to delete is not a leaf so if we do not @@ -3662,19 +4597,20 @@ int sqlite3BtreeDelete(BtCursor *pCur){ assert( MX_CELL_SIZE(pBt)>=szNext+4 ); tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) ); if( tempCell==0 ) return SQLITE_NOMEM; - insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell); + rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0); + if( rc!=SQLITE_OK ) return rc; put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); - rc = balance(pPage); + rc = balance(pPage, 0); sqliteFree(tempCell); if( rc ) return rc; dropCell(leafCur.pPage, leafCur.idx, szNext); - rc = balance(leafCur.pPage); + rc = balance(leafCur.pPage, 0); releaseTempCursor(&leafCur); }else{ TRACE(("DELETE: table=%d delete from leaf %d\n", pCur->pgnoRoot, pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); - rc = balance(pPage); + rc = balance(pPage, 0); } moveToRoot(pCur); return rc; @@ -3699,11 +4635,102 @@ int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){ /* Must start a transaction first */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; } - if( pBt->readOnly ){ - return SQLITE_READONLY; + assert( !pBt->readOnly ); + + /* It is illegal to create a table if any cursors are open on the + ** database. This is because in auto-vacuum mode the backend may + ** need to move a database page to make room for the new root-page. + ** If an open cursor was using the page a problem would occur. + */ + if( pBt->pCursor ){ + return SQLITE_LOCKED; } - rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1); + +#ifdef SQLITE_OMIT_AUTOVACUUM + rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0); if( rc ) return rc; +#else + if( pBt->autoVacuum ){ + Pgno pgnoMove; /* Move a page here to make room for the root-page */ + MemPage *pPageMove; /* The page to move to. */ + + /* Read the value of meta[3] from the database to determine where the + ** root page of the new table should go. meta[3] is the largest root-page + ** created so far, so the new root-page is (meta[3]+1). + */ + rc = sqlite3BtreeGetMeta(pBt, 4, &pgnoRoot); + if( rc!=SQLITE_OK ) return rc; + pgnoRoot++; + + /* The new root-page may not be allocated on a pointer-map page, or the + ** PENDING_BYTE page. + */ + if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) || + pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ + pgnoRoot++; + } + assert( pgnoRoot>=3 ); + + /* Allocate a page. The page that currently resides at pgnoRoot will + ** be moved to the allocated page (unless the allocated page happens + ** to reside at pgnoRoot). + */ + rc = allocatePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1); + if( rc!=SQLITE_OK ){ + return rc; + } + + if( pgnoMove!=pgnoRoot ){ + u8 eType; + Pgno iPtrPage; + + releasePage(pPageMove); + rc = getPage(pBt, pgnoRoot, &pRoot); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); + assert( eType!=PTRMAP_ROOTPAGE ); + assert( eType!=PTRMAP_FREEPAGE ); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove); + releasePage(pRoot); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = getPage(pBt, pgnoRoot, &pRoot); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3pager_write(pRoot->aData); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + }else{ + pRoot = pPageMove; + } + + /* Update the pointer-map and meta-data with the new root-page number. */ + rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0); + if( rc ){ + releasePage(pRoot); + return rc; + } + rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot); + if( rc ){ + releasePage(pRoot); + return rc; + } + + }else{ + rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ) return rc; + } +#endif assert( sqlite3pager_iswriteable(pRoot->aData) ); zeroPage(pRoot, flags | PTF_LEAF); sqlite3pager_unref(pRoot->aData); @@ -3726,6 +4753,10 @@ static int clearDatabasePage( unsigned char *pCell; int i; + if( pgno>sqlite3pager_pagecount(pBt->pPager) ){ + return SQLITE_CORRUPT; + } + rc = getAndInitPage(pBt, pgno, &pPage, pParent); if( rc ) return rc; rc = sqlite3pager_write(pPage->aData); @@ -3787,29 +4818,119 @@ int sqlite3BtreeClearTable(Btree *pBt, int iTable){ ** ** This routine will fail with SQLITE_LOCKED if there are any open ** cursors on the table. +** +** If AUTOVACUUM is enabled and the page at iTable is not the last +** root page in the database file, then the last root page +** in the database file is moved into the slot formerly occupied by +** iTable and that last slot formerly occupied by the last root page +** is added to the freelist instead of iTable. In this say, all +** root pages are kept at the beginning of the database file, which +** is necessary for AUTOVACUUM to work right. *piMoved is set to the +** page number that used to be the last root page in the file before +** the move. If no page gets moved, *piMoved is set to 0. +** The last root page is recorded in meta[3] and the value of +** meta[3] is updated by this procedure. */ -int sqlite3BtreeDropTable(Btree *pBt, int iTable){ +int sqlite3BtreeDropTable(Btree *pBt, int iTable, int *piMoved){ int rc; - MemPage *pPage; - BtCursor *pCur; + MemPage *pPage = 0; + if( pBt->inTrans!=TRANS_WRITE ){ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; } - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( pCur->pgnoRoot==(Pgno)iTable ){ - return SQLITE_LOCKED; /* Cannot drop a table that has a cursor */ - } + + /* It is illegal to drop a table if any cursors are open on the + ** database. This is because in auto-vacuum mode the backend may + ** need to move another root-page to fill a gap left by the deleted + ** root page. If an open cursor was using this page a problem would + ** occur. + */ + if( pBt->pCursor ){ + return SQLITE_LOCKED; } + rc = getPage(pBt, (Pgno)iTable, &pPage); if( rc ) return rc; rc = sqlite3BtreeClearTable(pBt, iTable); if( rc ) return rc; + + *piMoved = 0; + if( iTable>1 ){ +#ifdef SQLITE_OMIT_AUTOVACUUM rc = freePage(pPage); + releasePage(pPage); +#else + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + rc = sqlite3BtreeGetMeta(pBt, 4, &maxRootPgno); + if( rc!=SQLITE_OK ){ + releasePage(pPage); + return rc; + } + + if( iTable==maxRootPgno ){ + /* If the table being dropped is the table with the largest root-page + ** number in the database, put the root page on the free list. + */ + rc = freePage(pPage); + releasePage(pPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + /* The table being dropped does not have the largest root-page + ** number in the database. So move the page that does into the + ** gap left by the deleted root-page. + */ + MemPage *pMove; + releasePage(pPage); + rc = getPage(pBt, maxRootPgno, &pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = getPage(pBt, maxRootPgno, &pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = freePage(pMove); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + *piMoved = maxRootPgno; + } + + /* Set the new 'max-root-page' value in the database header. This + ** is the old value less one, less one more if that happens to + ** be a root-page number, less one again if that is the + ** PENDING_BYTE_PAGE. + */ + maxRootPgno--; + if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){ + maxRootPgno--; + } + if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){ + maxRootPgno--; + } + assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); + + rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno); + }else{ + rc = freePage(pPage); + releasePage(pPage); + } +#endif }else{ + /* If sqlite3BtreeDropTable was called on page 1. */ zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); + releasePage(pPage); } - releasePage(pPage); return rc; } @@ -3834,9 +4955,12 @@ int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){ *pMeta = get4byte(&pP1[36 + idx*4]); sqlite3pager_unref(pP1); - /* The current implementation is unable to handle writes to an autovacuumed - ** database. So make such a database readonly. */ + /* If autovacuumed is disabled in this build but we are trying to + ** access an autovacuumed database, then make the database readonly. + */ +#ifdef SQLITE_OMIT_AUTOVACUUM if( idx==4 && *pMeta>0 ) pBt->readOnly = 1; +#endif return SQLITE_OK; } @@ -3869,12 +4993,12 @@ int sqlite3BtreeFlags(BtCursor *pCur){ return pPage ? pPage->aData[pPage->hdrOffset] : 0; } +#ifdef SQLITE_DEBUG /* ** Print a disassembly of the given page on standard output. This routine ** is used for debugging and testing only. */ -#ifdef SQLITE_TEST -int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ +static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){ int rc; MemPage *pPage; int i, j, c; @@ -3890,7 +5014,7 @@ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ rc = getPage(pBt, (Pgno)pgno, &pPage); isInit = pPage->isInit; if( pPage->isInit==0 ){ - initPage(pPage, 0); + initPage(pPage, pParent); } if( rc ){ return rc; @@ -3960,16 +5084,19 @@ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ if( recursive && !pPage->leaf ){ for(i=0; iisInit = isInit; sqlite3pager_unref(data); fflush(stdout); return SQLITE_OK; } +int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ + return btreePageDump(pBt, pgno, recursive, 0); +} #endif #ifdef SQLITE_TEST @@ -4058,6 +5185,7 @@ struct IntegrityCk { char *zErrMsg; /* An error message. NULL of no errors seen. */ }; +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Append a message to the error message string. */ @@ -4083,7 +5211,9 @@ static void checkAppendMsg( } sqliteFree(zMsg2); } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. @@ -4105,6 +5235,37 @@ static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){ return (pCheck->anRef[iPage]++)>1; } +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Check that the entry in the pointer-map for page iChild maps to +** page iParent, pointer type ptrType. If not, append an error message +** to pCheck. +*/ +static void checkPtrmap( + IntegrityCk *pCheck, /* Integrity check context */ + Pgno iChild, /* Child page number */ + u8 eType, /* Expected pointer map type */ + Pgno iParent, /* Expected pointer map parent page number */ + char *zContext /* Context description (used for error msg) */ +){ + int rc; + u8 ePtrmapType; + Pgno iPtrmapParent; + + rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); + if( rc!=SQLITE_OK ){ + checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild); + return; + } + + if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ + checkAppendMsg(pCheck, zContext, + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", + iChild, eType, iParent, ePtrmapType, iPtrmapParent); + } +} +#endif + /* ** Check the integrity of the freelist or of an overflow page list. ** Verify that the number of pages on the list is N. @@ -4134,22 +5295,47 @@ static void checkList( } if( isFreeList ){ int n = get4byte(&pOvfl[4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext); + } +#endif if( n>pCheck->pBt->usableSize/4-8 ){ checkAppendMsg(pCheck, zContext, "freelist leaf count too big on page %d", iPage); N--; }else{ for(i=0; ipBt->autoVacuum ){ + checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext); + } +#endif + checkRef(pCheck, iFreePage, zContext); } N -= n; } } +#ifndef SQLITE_OMIT_AUTOVACUUM + else{ + /* If this database supports auto-vacuum and iPage is not the last + ** page in this overflow list, check that the pointer-map entry for + ** the following page matches iPage. + */ + if( pCheck->pBt->autoVacuum && N>0 ){ + i = get4byte(pOvfl); + checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext); + } + } +#endif iPage = get4byte(pOvfl); sqlite3pager_unref(pOvfl); } } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages @@ -4189,6 +5375,8 @@ static int checkTreePage( char zContext[100]; char *hit; + sprintf(zContext, "Page %d: ", iPage); + /* Check that the page exists */ cur.pBt = pBt = pCheck->pBt; @@ -4225,13 +5413,24 @@ static int checkTreePage( if( !pPage->intKey ) sz += info.nKey; if( sz>info.nLocal ){ int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4); - checkList(pCheck, 0, get4byte(&pCell[info.iOverflow]),nPage,zContext); + Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext); + } +#endif + checkList(pCheck, 0, pgnoOvfl, nPage, zContext); } /* Check sanity of left child page. */ if( !pPage->leaf ){ pgno = get4byte(pCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext); + } +#endif d2 = checkTreePage(pCheck,pgno,pPage,zContext,0,0,0,0); if( i>0 && d2!=depth ){ checkAppendMsg(pCheck, zContext, "Child page depth differs"); @@ -4242,6 +5441,11 @@ static int checkTreePage( if( !pPage->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); sprintf(zContext, "On page %d at right child: ", iPage); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0); + } +#endif checkTreePage(pCheck, pgno, pPage, zContext,0,0,0,0); } @@ -4258,13 +5462,23 @@ static int checkTreePage( int pc = get2byte(&data[cellStart+i*2]); int size = cellSizePtr(pPage, &data[pc]); int j; - for(j=pc+size-1; j>=pc; j--) hit[j]++; + if( (pc+size-1)>=usableSize || pc<0 ){ + checkAppendMsg(pCheck, 0, + "Corruption detected in cell %d on page %d",i,iPage,0); + }else{ + for(j=pc+size-1; j>=pc; j--) hit[j]++; + } } for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i=i; j--) hit[j]++; + if( (i+size-1)>=usableSize || i<0 ){ + checkAppendMsg(pCheck, 0, + "Corruption detected in cell %d on page %d",i,iPage,0); + }else{ + for(j=i+size-1; j>=i; j--) hit[j]++; + } i = get2byte(&data[i]); } for(i=cnt=0; ipageSize + 1; + i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ){ sCheck.anRef[i] = 1; } @@ -4331,15 +5552,34 @@ char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ */ for(i=0; iautoVacuum && aRoot[i]>1 ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0); + } +#endif checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0); } /* Make sure every page in the file is referenced */ for(i=1; i<=sCheck.nPage; i++){ +#ifdef SQLITE_OMIT_AUTOVACUUM if( sCheck.anRef[i]==0 ){ checkAppendMsg(&sCheck, 0, "Page %d is never used", i); } +#else + /* If the database supports auto-vacuum, make sure no tables contain + ** references to pointer-map pages. + */ + if( sCheck.anRef[i]==0 && + (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, 0, "Page %d is never used", i); + } + if( sCheck.anRef[i]!=0 && + (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); + } +#endif } /* Make sure this analysis did not leave any unref() pages @@ -4357,6 +5597,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ sqliteFree(sCheck.anRef); return sCheck.zErrMsg; } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* ** Return the full pathname of the underlying database file. @@ -4384,6 +5625,7 @@ const char *sqlite3BtreeGetJournalname(Btree *pBt){ return sqlite3pager_journalname(pBt->pPager); } +#ifndef SQLITE_OMIT_VACUUM /* ** Copy the complete content of pBtFrom into pBtTo. A transaction ** must be active for both files. @@ -4425,6 +5667,7 @@ int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){ } return rc; } +#endif /* SQLITE_OMIT_VACUUM */ /* ** Return non-zero if a transaction is active. @@ -4456,7 +5699,15 @@ int sqlite3BtreeIsInStmt(Btree *pBt){ */ int sqlite3BtreeSync(Btree *pBt, const char *zMaster){ if( pBt->inTrans==TRANS_WRITE ){ - return sqlite3pager_sync(pBt->pPager, zMaster); +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno nTrunc = 0; + if( pBt->autoVacuum ){ + int rc = autoVacuumCommit(pBt, &nTrunc); + if( rc!=SQLITE_OK ) return rc; + } + return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc); +#endif + return sqlite3pager_sync(pBt->pPager, zMaster, 0); } return SQLITE_OK; } diff --git a/ext/pdo_sqlite/sqlite/src/btree.h b/ext/pdo_sqlite/sqlite/src/btree.h index 48524aefc1..d4ee97ef38 100644 --- a/ext/pdo_sqlite/sqlite/src/btree.h +++ b/ext/pdo_sqlite/sqlite/src/btree.h @@ -23,6 +23,14 @@ */ #define SQLITE_N_BTREE_META 10 +/* +** If defined as non-zero, auto-vacuum is enabled by default. Otherwise +** it must be turned on for each database using "PRAGMA auto_vacuum = 1". +*/ +#ifndef SQLITE_DEFAULT_AUTOVACUUM + #define SQLITE_DEFAULT_AUTOVACUUM 0 +#endif + /* ** Forward declarations of structure */ @@ -38,9 +46,13 @@ int sqlite3BtreeOpen( /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the ** following values. +** +** NOTE: These values must match the corresponding PAGER_ values in +** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */ -#define BTREE_MEMORY 2 /* In-memory DB. No argument */ +#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ +#define BTREE_MEMORY 4 /* In-memory DB. No argument */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*); @@ -49,6 +61,8 @@ int sqlite3BtreeSetSafetyLevel(Btree*,int); int sqlite3BtreeSetPageSize(Btree*,int,int); int sqlite3BtreeGetPageSize(Btree*); int sqlite3BtreeGetReserve(Btree*); +int sqlite3BtreeSetAutoVacuum(Btree *, int); +int sqlite3BtreeGetAutoVacuum(Btree *); int sqlite3BtreeBeginTrans(Btree*,int); int sqlite3BtreeCommit(Btree*); int sqlite3BtreeRollback(Btree*); @@ -72,7 +86,7 @@ int sqlite3BtreeCopyFile(Btree *, Btree *); #define BTREE_ZERODATA 2 /* Table has keys only - no data */ #define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */ -int sqlite3BtreeDropTable(Btree*, int); +int sqlite3BtreeDropTable(Btree*, int, int*); int sqlite3BtreeClearTable(Btree*, int); int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); @@ -117,8 +131,12 @@ struct Pager *sqlite3BtreePager(Btree*); #ifdef SQLITE_TEST int sqlite3BtreeCursorInfo(BtCursor*, int*, int); void sqlite3BtreeCursorList(Btree*); -int sqlite3BtreePageDump(Btree*, int, int recursive); #endif +#ifdef SQLITE_DEBUG +int sqlite3BtreePageDump(Btree*, int, int recursive); +#else +#define sqlite3BtreePageDump(X,Y,Z) SQLITE_OK +#endif #endif /* _BTREE_H_ */ diff --git a/ext/pdo_sqlite/sqlite/src/build.c b/ext/pdo_sqlite/sqlite/src/build.c index 3e5e08a541..1908a47118 100644 --- a/ext/pdo_sqlite/sqlite/src/build.c +++ b/ext/pdo_sqlite/sqlite/src/build.c @@ -21,7 +21,6 @@ ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK -** PRAGMA ** ** $Id$ */ @@ -30,9 +29,7 @@ /* ** This routine is called when a new SQL statement is beginning to -** be parsed. Check to see if the schema for the database needs -** to be read from the SQLITE_MASTER and SQLITE_TEMP_MASTER tables. -** If it does, then read it. +** be parsed. Initialize the pParse structure as needed. */ void sqlite3BeginParse(Parse *pParse, int explainFlag){ pParse->explain = explainFlag; @@ -54,6 +51,13 @@ void sqlite3FinishCoding(Parse *pParse){ Vdbe *v; if( sqlite3_malloc_failed ) return; + if( pParse->nested ) return; + if( !pParse->pVdbe ){ + if( pParse->rc==SQLITE_OK && pParse->nErr ){ + pParse->rc = SQLITE_ERROR; + } + return; + } /* Begin by generating some termination code at the end of the ** vdbe program @@ -85,7 +89,7 @@ void sqlite3FinishCoding(Parse *pParse){ ** statement as its P3 argument. This does not change the functionality ** of the program. ** - ** This is used to implement sqlite3_trace() functionality. + ** This is used to implement sqlite3_trace(). */ sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql); } @@ -97,8 +101,8 @@ void sqlite3FinishCoding(Parse *pParse){ FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3, - pParse->nTab+3, pParse->explain); - pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE; + pParse->nTab+3, pParse->nMaxDepth+1, pParse->explain); + pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else if( pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; @@ -106,12 +110,47 @@ void sqlite3FinishCoding(Parse *pParse){ pParse->nTab = 0; pParse->nMem = 0; pParse->nSet = 0; - pParse->nAgg = 0; pParse->nVar = 0; pParse->cookieMask = 0; pParse->cookieGoto = 0; } +/* +** Run the parser and code generator recursively in order to generate +** code for the SQL statement given onto the end of the pParse context +** currently under construction. When the parser is run recursively +** this way, the final OP_Halt is not appended and other initialization +** and finalization steps are omitted because those are handling by the +** outermost parser. +** +** Not everything is nestable. This facility is designed to permit +** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use +** care if you decide to try to use this routine for some other purposes. +*/ +void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ + va_list ap; + char *zSql; + int rc; +# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) + char saveBuf[SAVE_SZ]; + + if( pParse->nErr ) return; + assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ + va_start(ap, zFormat); + zSql = sqlite3VMPrintf(zFormat, ap); + va_end(ap); + if( zSql==0 ){ + return; /* A malloc must have failed */ + } + pParse->nested++; + memcpy(saveBuf, &pParse->nVar, SAVE_SZ); + memset(&pParse->nVar, 0, SAVE_SZ); + rc = sqlite3RunParser(pParse, zSql, 0); + sqliteFree(zSql); + memcpy(&pParse->nVar, saveBuf, SAVE_SZ); + pParse->nested--; +} + /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -279,8 +318,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ sqlite3HashClear(&pDb->aFKey); sqlite3HashClear(&pDb->idxHash); for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - Trigger *pTrigger = sqliteHashData(pElem); - sqlite3DeleteTrigger(pTrigger); + sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem)); } sqlite3HashClear(&temp2); sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0); @@ -289,6 +327,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ sqlite3DeleteTable(db, pTab); } sqlite3HashClear(&temp1); + pDb->pSeqTab = 0; DbClearProperty(db, i, DB_SchemaLoaded); if( iDb>0 ) return; } @@ -356,7 +395,7 @@ static void sqliteResetColumnNames(Table *pTable){ assert( pTable!=0 ); for(i=0, pCol=pTable->aCol; inCol; i++, pCol++){ sqliteFree(pCol->zName); - sqliteFree(pCol->zDflt); + sqlite3ExprDelete(pCol->pDflt); sqliteFree(pCol->zType); } sqliteFree(pTable->aCol); @@ -393,6 +432,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ sqliteDeleteIndex(db, pIndex); } +#ifndef SQLITE_OMIT_FOREIGN_KEY /* Delete all foreign keys associated with this table. The keys ** should have already been unlinked from the db->aFKey hash table */ @@ -403,6 +443,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); sqliteFree(pFKey); } +#endif /* Delete the Table structure itself. */ @@ -428,6 +469,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ pDb = &db->aDb[iDb]; p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0); if( p ){ +#ifndef SQLITE_OMIT_FOREIGN_KEY for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){ int nTo = strlen(pF1->zTo) + 1; pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo); @@ -440,6 +482,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ } } } +#endif sqlite3DeleteTable(db, p); } db->flags |= SQLITE_InternChanges; @@ -482,16 +525,23 @@ void sqlite3OpenMasterTable(Vdbe *v, int iDb){ ** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ -int findDb(sqlite3 *db, Token *pName){ - int i; - Db *pDb; - for(pDb=db->aDb, i=0; inDb; i++, pDb++){ - if( pName->n==strlen(pDb->zName) && - 0==sqlite3StrNICmp(pDb->zName, pName->z, pName->n) ){ - return i; +static int findDb(sqlite3 *db, Token *pName){ + int i = -1; /* Database number */ + int n; /* Number of characters in the name */ + Db *pDb; /* A database whose name space is being searched */ + char *zName; /* Name we are searching for */ + + zName = sqlite3NameFromToken(pName); + if( zName ){ + n = strlen(zName); + for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ + if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){ + break; + } } + sqliteFree(zName); } - return -1; + return i; } /* The table or view or trigger name is passed to this routine via tokens @@ -544,7 +594,8 @@ int sqlite3TwoPartName( ** is reserved for internal use. */ int sqlite3CheckObjectName(Parse *pParse, const char *zName){ - if( !pParse->db->init.busy && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ + if( !pParse->db->init.busy && pParse->nested==0 + && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; } @@ -578,7 +629,7 @@ void sqlite3StartTable( ){ Table *pTable; Index *pIdx; - char *zName; + char *zName = 0; /* The name of the new table */ sqlite3 *db = pParse->db; Vdbe *v; int iDb; /* Database number to create the table in */ @@ -606,7 +657,6 @@ void sqlite3StartTable( if( isTemp && iDb>1 ){ /* If creating a temp table, the name may not be qualified */ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); - pParse->nErr++; return; } if( isTemp ) iDb = 1; @@ -615,8 +665,7 @@ void sqlite3StartTable( zName = sqlite3NameFromToken(pName); if( zName==0 ) return; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - sqliteFree(zName); - return; + goto begin_table_error; } if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION @@ -625,8 +674,7 @@ void sqlite3StartTable( int code; char *zDb = db->aDb[iDb].zName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ - sqliteFree(zName); - return; + goto begin_table_error; } if( isView ){ if( isTemp ){ @@ -642,8 +690,7 @@ void sqlite3StartTable( } } if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ - sqliteFree(zName); - return; + goto begin_table_error; } } #endif @@ -652,25 +699,24 @@ void sqlite3StartTable( ** index or table name in the same database. Issue an error message if ** it does. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto begin_table_error; + } pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName); if( pTable ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); - sqliteFree(zName); - return; + goto begin_table_error; } if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 && ( iDb==0 || !db->init.busy) ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); - sqliteFree(zName); - return; + goto begin_table_error; } pTable = sqliteMalloc( sizeof(Table) ); if( pTable==0 ){ pParse->rc = SQLITE_NOMEM; pParse->nErr++; - sqliteFree(zName); - return; + goto begin_table_error; } pTable->zName = zName; pTable->nCol = 0; @@ -681,6 +727,16 @@ void sqlite3StartTable( if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; + /* If this is the magic sqlite_sequence table used by autoincrement, + ** then record a pointer to this table in the main database structure + ** so that INSERT can find the table easily. + */ +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( strcmp(zName, "sqlite_sequence")==0 ){ + db->aDb[iDb].pSeqTab = pTable; + } +#endif + /* Begin generating the code that will insert the table record into ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any @@ -690,24 +746,68 @@ void sqlite3StartTable( ** now. */ if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ + int lbl; sqlite3BeginWriteOperation(pParse, 0, iDb); - /* Every time a new table is created the file-format - ** and encoding meta-values are set in the database, in - ** case this is the first table created. + + /* If the file format and encoding in the database have not been set, + ** set them now. */ + sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */ + lbl = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp(v, OP_If, 0, lbl); sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4); + sqlite3VdbeResolveLabel(v, lbl); + /* This just creates a place-holder record in the sqlite_master table. + ** The record created does not contain anything yet. It will be replaced + ** by the real entry in code generated at sqlite3EndTable(). + ** + ** The rowid for the new entry is left on the top of the stack. + ** The rowid value is needed by the code that sqlite3EndTable will + ** generate. + */ +#ifndef SQLITE_OMIT_VIEW + if( isView ){ + sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + }else +#endif + { + sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0); + } sqlite3OpenMasterTable(v, iDb); sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); + sqlite3VdbeAddOp(v, OP_Close, 0, 0); + sqlite3VdbeAddOp(v, OP_Pull, 1, 0); } + + /* Normal (non-error) return. */ + return; + + /* If an error occurs, we jump here */ +begin_table_error: + sqliteFree(zName); + return; } +/* +** This macro is used to compare two strings in a case-insensitive manner. +** It is slightly faster than calling sqlite3StrICmp() directly, but +** produces larger code. +** +** WARNING: This macro is not compatible with the strcmp() family. It +** returns true if the two strings are equal, otherwise false. +*/ +#define STRICMP(x, y) (\ +sqlite3UpperToLower[*(unsigned char *)(x)]== \ +sqlite3UpperToLower[*(unsigned char *)(y)] \ +&& sqlite3StrICmp((x)+1,(y)+1)==0 ) + /* ** Add a new column to the table currently being constructed. ** @@ -725,7 +825,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){ z = sqlite3NameFromToken(pName); if( z==0 ) return; for(i=0; inCol; i++){ - if( sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ + if( STRICMP(z, p->aCol[i].zName) ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqliteFree(z); return; @@ -764,6 +864,55 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ if( i>=0 ) p->aCol[i].notNull = onError; } +/* +** Scan the column type name zType (length nType) and return the +** associated affinity type. +** +** This routine does a case-independent search of zType for the +** substrings in the following table. If one of the substrings is +** found, the corresponding affinity is returned. If zType contains +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', +** SQLITE_AFF_INTEGER is returned. +** +** Substring | Affinity +** -------------------------------- +** 'INT' | SQLITE_AFF_INTEGER +** 'CHAR' | SQLITE_AFF_TEXT +** 'CLOB' | SQLITE_AFF_TEXT +** 'TEXT' | SQLITE_AFF_TEXT +** 'BLOB' | SQLITE_AFF_NONE +** +** If none of the substrings in the above table are found, +** SQLITE_AFF_NUMERIC is returned. +*/ +static char sqlite3AffinityType(const char *zType, int nType){ + u32 h = 0; + char aff = SQLITE_AFF_NUMERIC; + const unsigned char *zIn = zType; + const unsigned char *zEnd = (zIn+nType); + + while( zIn!=zEnd ){ + h = (h<<8) + sqlite3UpperToLower[*zIn]; + zIn++; + if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_NONE; + }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ + aff = SQLITE_AFF_INTEGER; + break; + } + } + + return aff; +} + /* ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. The pFirst token is the first @@ -777,19 +926,21 @@ void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){ Table *p; int i, j; int n; - char *z, **pz; + char *z; + const unsigned char *zIn; + Column *pCol; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; if( i<0 ) return; pCol = &p->aCol[i]; - pz = &pCol->zType; - n = pLast->n + (pLast->z - pFirst->z); + zIn = pFirst->z; + n = pLast->n + (pLast->z - zIn); assert( pCol->zType==0 ); - z = pCol->zType = sqlite3MPrintf("%.*s", n, pFirst->z); + z = pCol->zType = sqliteMallocRaw(n+1); if( z==0 ) return; - for(i=j=0; z[i]; i++){ - int c = z[i]; + for(i=j=0; ipNewTable)==0 ) return; - i = p->nCol-1; - if( i<0 ) return; - assert( p->aCol[i].zDflt==0 ); - z = p->aCol[i].zDflt = sqlite3MPrintf("%s%T", minusFlag ? "-" : "", pVal); - sqlite3Dequote(z); + pCol = &(p->aCol[p->nCol-1]); + if( !sqlite3ExprIsConstant(pExpr) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + pCol->zName); + }else{ + sqlite3ExprDelete(pCol->pDflt); + pCol->pDflt = sqlite3ExprDup(pExpr); + } + sqlite3ExprDelete(pExpr); } /* @@ -827,9 +983,7 @@ void sqlite3AddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){ ** error. ** ** If the PRIMARY KEY is on a single column whose datatype is INTEGER, -** then we will try to use that column as the row id. (Exception: -** For backwards compatibility with older databases, do not do this -** if the file format version number is less than 1.) Set the Table.iPKey +** then we will try to use that column as the rowid. Set the Table.iPKey ** field of the table under construction to be the index of the ** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is ** no INTEGER PRIMARY KEY. @@ -837,7 +991,12 @@ void sqlite3AddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){ ** If the key is not an INTEGER PRIMARY KEY, then create a unique ** index for the key. No index is created for INTEGER PRIMARY KEYs. */ -void sqlite3AddPrimaryKey(Parse *pParse, ExprList *pList, int onError){ +void sqlite3AddPrimaryKey( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List of field names to be indexed */ + int onError, /* What to do with a uniqueness conflict */ + int autoInc /* True if the AUTOINCREMENT keyword is present */ +){ Table *pTab = pParse->pNewTable; char *zType = 0; int iCol = -1, i; @@ -868,6 +1027,12 @@ void sqlite3AddPrimaryKey(Parse *pParse, ExprList *pList, int onError){ if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){ pTab->iPKey = iCol; pTab->keyConf = onError; + pTab->autoInc = autoInc; + }else if( autoInc ){ +#ifndef SQLITE_OMIT_AUTOINCREMENT + sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " + "INTEGER PRIMARY KEY"); +#endif }else{ sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0); pList = 0; @@ -980,6 +1145,7 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); sqliteFree(zExternal); } +#ifndef SQLITE_OMIT_UTF16 if( db->xCollNeeded16 ){ char const *zExternal; sqlite3_value *pTmp = sqlite3GetTransientValue(db); @@ -988,6 +1154,7 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ if( !zExternal ) return; db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); } +#endif } /* @@ -1105,44 +1272,6 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ } - -/* -** Scan the column type name zType (length nType) and return the -** associated affinity type. -*/ -char sqlite3AffinityType(const char *zType, int nType){ - int n, i; - static const struct { - const char *zSub; /* Keywords substring to search for */ - char nSub; /* length of zSub */ - char affinity; /* Affinity to return if it matches */ - } substrings[] = { - {"INT", 3, SQLITE_AFF_INTEGER}, - {"CHAR", 4, SQLITE_AFF_TEXT}, - {"CLOB", 4, SQLITE_AFF_TEXT}, - {"TEXT", 4, SQLITE_AFF_TEXT}, - {"BLOB", 4, SQLITE_AFF_NONE}, - }; - - if( nType==0 ){ - return SQLITE_AFF_NONE; - } - for(i=0; iinit.busy ){ int n; Vdbe *v; + char *zType; /* "view" or "table" */ + char *zType2; /* "VIEW" or "TABLE" */ + char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ v = sqlite3GetVdbe(pParse); if( v==0 ) return; + sqlite3VdbeAddOp(v, OP_Close, 0, 0); + + /* Create the rootpage for the new table and push it onto the stack. + ** A view has no rootpage, so just push a zero onto the stack for + ** views. Initialize zType at the same time. + */ if( p->pSelect==0 ){ /* A regular table */ - sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); + /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */ + zType = "table"; + zType2 = "TABLE"; +#ifndef SQLITE_OMIT_VIEW }else{ /* A view */ - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + /* sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */ + zType = "view"; + zType2 = "VIEW"; +#endif } - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT ** statement to populate the new table. The root-page number for the ** new table is on the top of the vdbe stack. @@ -1344,40 +1486,55 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ sqlite3DeleteTable(0, pSelTab); } } - - sqlite3OpenMasterTable(v, p->iDb); - - sqlite3VdbeOp3(v, OP_String8, 0, 0, p->pSelect==0?"table":"view",P3_STATIC); - sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0); - sqlite3VdbeAddOp(v, OP_Pull, 3, 0); + /* Compute the complete text of the CREATE statement */ if( pSelect ){ - char *z = createTableStmt(p); - n = z ? strlen(z) : 0; - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeChangeP3(v, -1, z, n); - sqliteFree(z); + zStmt = createTableStmt(p); }else{ - if( p->pSelect ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE VIEW ", P3_STATIC); - }else{ - sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE TABLE ", P3_STATIC); - } - assert( pEnd!=0 ); n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); - sqlite3VdbeAddOp(v, OP_Concat, 0, 0); + zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z); } - sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); - sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); + + /* A slot for the record has already been allocated in the + ** SQLITE_MASTER table. We just need to update that slot with all + ** the information we've collected. The rowid for the preallocated + ** slot is the 2nd item on the stack. The top of the stack is the + ** root page for the new table (or a 0 if this is a view). + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s " + "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q " + "WHERE rowid=#1", + db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb), + zType, + p->zName, + p->zName, + zStmt + ); + sqliteFree(zStmt); sqlite3ChangeCookie(db, v, p->iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Check to see if we need to create an sqlite_sequence table for + ** keeping track of autoincrement keys. + */ + if( p->autoInc ){ + Db *pDb = &db->aDb[p->iDb]; + if( pDb->pSeqTab==0 ){ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.sqlite_sequence(name,seq)", + pDb->zName + ); + } + } +#endif + + /* Reparse everything to update our internal data structures */ sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0, sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC); } + /* Add the table to the in-memory representation of the database. */ if( db->init.busy && pParse->nErr==0 ){ @@ -1389,17 +1546,20 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ return; } +#ifndef SQLITE_OMIT_FOREIGN_KEY for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ int nTo = strlen(pFKey->zTo) + 1; pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo); sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey); } +#endif pParse->pNewTable = 0; db->nTable++; db->flags |= SQLITE_InternChanges; } } +#ifndef SQLITE_OMIT_VIEW /* ** The parser calls this routine in order to create a new VIEW */ @@ -1461,17 +1621,19 @@ void sqlite3CreateView( sqlite3EndTable(pParse, &sEnd, 0); return; } +#endif /* SQLITE_OMIT_VIEW */ +#ifndef SQLITE_OMIT_VIEW /* ** The Table structure pTable is really a VIEW. Fill in the names of ** the columns of the view in the pTable structure. Return the number ** of errors. If an error is seen leave an error message in pParse->zErrMsg. */ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ - ExprList *pEList; - Select *pSel; - Table *pSelTab; - int nErr = 0; + Table *pSelTab; /* A fake table from which we get the result set */ + Select *pSel; /* Copy of the SELECT that implements the view */ + int nErr = 0; /* Number of errors encountered */ + int n; /* Temporarily holds the number of cursors assigned */ assert( pTable ); @@ -1496,23 +1658,19 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ } /* If we get this far, it means we need to compute the table names. + ** Note that the call to sqlite3ResultSetOfSelect() will expand any + ** "*" elements in the results set of the view and will assign cursors + ** to the elements of the FROM clause. But we do not want these changes + ** to be permanent. So the computation is done on a copy of the SELECT + ** statement that defines the view. */ - assert( pTable->pSelect ); /* If nCol==0, then pTable must be a VIEW */ - pSel = pTable->pSelect; - - /* Note that the call to sqlite3ResultSetOfSelect() will expand any - ** "*" elements in this list. But we will need to restore the list - ** back to its original configuration afterwards, so we save a copy of - ** the original in pEList. - */ - pEList = pSel->pEList; - pSel->pEList = sqlite3ExprListDup(pEList); - if( pSel->pEList==0 ){ - pSel->pEList = pEList; - return 1; /* Malloc failed */ - } + assert( pTable->pSelect ); + pSel = sqlite3SelectDup(pTable->pSelect); + n = pParse->nTab; + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); + pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; @@ -1525,12 +1683,12 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->nCol = 0; nErr++; } - sqlite3SelectUnbind(pSel); - sqlite3ExprListDelete(pSel->pEList); - pSel->pEList = pEList; + sqlite3SelectDelete(pSel); return nErr; } +#endif /* SQLITE_OMIT_VIEW */ +#ifndef SQLITE_OMIT_VIEW /* ** Clear the column names from every VIEW in database idx. */ @@ -1545,6 +1703,115 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ } DbClearProperty(db, idx, DB_UnresetViews); } +#else +# define sqliteViewResetAll(A,B) +#endif /* SQLITE_OMIT_VIEW */ + +/* +** This function is called by the VDBE to adjust the internal schema +** used by SQLite when the btree layer moves a table root page. The +** root-page of a table or index in database iDb has changed from iFrom +** to iTo. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){ + HashElem *pElem; + + for(pElem=sqliteHashFirst(&pDb->tblHash); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + if( pTab->tnum==iFrom ){ + pTab->tnum = iTo; + return; + } + } + for(pElem=sqliteHashFirst(&pDb->idxHash); pElem; pElem=sqliteHashNext(pElem)){ + Index *pIdx = sqliteHashData(pElem); + if( pIdx->tnum==iFrom ){ + pIdx->tnum = iTo; + return; + } + } + assert(0); +} +#endif + +/* +** Write code to erase the table with root-page iTable from database iDb. +** Also write code to modify the sqlite_master table and internal schema +** if a root-page of another table is moved by the btree-layer whilst +** erasing iTable (this can happen with an auto-vacuum database). +*/ +static void destroyRootPage(Parse *pParse, int iTable, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* OP_Destroy pushes an integer onto the stack. If this integer + ** is non-zero, then it is the root page number of a table moved to + ** location iTable. The following code modifies the sqlite_master table to + ** reflect this. + ** + ** The "#0" in the SQL is a special constant that means whatever value + ** is on the top of the stack. See sqlite3RegisterExpr(). + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0", + pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable); +#endif +} + +/* +** Write VDBE code to erase table pTab and all associated indices on disk. +** Code to update the sqlite_master tables and internal schema definitions +** in case a root-page belonging to another table is moved by the btree layer +** is also added (this can happen with an auto-vacuum database). +*/ +static void destroyTable(Parse *pParse, Table *pTab){ +#ifdef SQLITE_OMIT_AUTOVACUUM + Index *pIdx; + destroyRootPage(pParse, pTab->tnum, pTab->iDb); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + destroyRootPage(pParse, pIdx->tnum, pIdx->iDb); + } +#else + /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM + ** is not defined), then it is important to call OP_Destroy on the + ** table and index root-pages in order, starting with the numerically + ** largest root-page number. This guarantees that none of the root-pages + ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the + ** following were coded: + ** + ** OP_Destroy 4 0 + ** ... + ** OP_Destroy 5 0 + ** + ** and root page 5 happened to be the largest root-page number in the + ** database, then root page 5 would be moved to page 4 by the + ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit + ** a free-list page. + */ + int iTab = pTab->tnum; + int iDestroyed = 0; + + while( 1 ){ + Index *pIdx; + int iLargest = 0; + + if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ + int iIdx = pIdx->tnum; + assert( pIdx->iDb==pTab->iDb ); + if( (iDestroyed==0 || (iIdxiLargest ){ + iLargest = iIdx; + } + } + if( iLargest==0 ) return; + destroyRootPage(pParse, iLargest, pTab->iDb); + iDestroyed = iLargest; + } +#endif +} /* ** This routine is called to do the work of a DROP TABLE statement. @@ -1553,7 +1820,6 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ Table *pTab; Vdbe *v; - int base; sqlite3 *db = pParse->db; int iDb; @@ -1593,11 +1859,15 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ } } #endif - if( pTab->readOnly ){ + if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); - pParse->nErr++; goto exit_drop_table; } + +#ifndef SQLITE_OMIT_VIEW + /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used + ** on a table. + */ if( isView && pTab->pSelect==0 ){ sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); goto exit_drop_table; @@ -1606,30 +1876,17 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); goto exit_drop_table; } +#endif /* Generate code to remove the table from the master table ** on disk. */ v = sqlite3GetVdbe(pParse); if( v ){ - static const VdbeOpList dropTable[] = { - { OP_Rewind, 0, ADDR(13), 0}, - { OP_String8, 0, 0, 0}, /* 1 */ - { OP_MemStore, 1, 1, 0}, - { OP_MemLoad, 1, 0, 0}, /* 3 */ - { OP_Column, 0, 2, 0}, /* sqlite_master.tbl_name */ - { OP_Ne, 0, ADDR(12), 0}, - { OP_String8, 0, 0, "trigger"}, - { OP_Column, 0, 2, 0}, /* sqlite_master.type */ - { OP_Eq, 0, ADDR(12), 0}, - { OP_Delete, 0, 0, 0}, - { OP_Rewind, 0, ADDR(13), 0}, - { OP_Goto, 0, ADDR(3), 0}, - { OP_Next, 0, ADDR(3), 0}, /* 12 */ - }; - Index *pIdx; Trigger *pTrigger; - sqlite3BeginWriteOperation(pParse, 0, pTab->iDb); + int iDb = pTab->iDb; + Db *pDb = &db->aDb[iDb]; + sqlite3BeginWriteOperation(pParse, 0, iDb); /* Drop all triggers associated with the table being dropped. Code ** is generated to remove entries from sqlite_master and/or @@ -1637,11 +1894,25 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ */ pTrigger = pTab->pTrigger; while( pTrigger ){ - assert( pTrigger->iDb==pTab->iDb || pTrigger->iDb==1 ); + assert( pTrigger->iDb==iDb || pTrigger->iDb==1 ); sqlite3DropTriggerPtr(pParse, pTrigger, 1); pTrigger = pTrigger->pNext; } +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Remove any entries of the sqlite_sequence table associated with + ** the table being dropped. This is done before the table is dropped + ** at the btree level, in case the sqlite_sequence table needs to + ** move as a result of the drop (can happen in auto-vacuum mode). + */ + if( pTab->autoInc ){ + sqlite3NestedParse(pParse, + "DELETE FROM %s.sqlite_sequence WHERE name=%Q", + pDb->zName, pTab->zName + ); + } +#endif + /* Drop all SQLITE_MASTER table and index entries that refer to the ** table. The program name loops through the master table and deletes ** every row that refers to a table of the same name as the one being @@ -1649,18 +1920,18 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ ** created in the temp database that refers to a table in another ** database. */ - sqlite3OpenMasterTable(v, pTab->iDb); - base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable); - sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0); - sqlite3ChangeCookie(db, v, pTab->iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", + pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); if( !isView ){ - sqlite3VdbeAddOp(v, OP_Destroy, pTab->tnum, pTab->iDb); - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqlite3VdbeAddOp(v, OP_Destroy, pIdx->tnum, pIdx->iDb); - } + destroyTable(pParse, pTab); } - sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0); + + /* Remove the table entry from SQLite's internal schema and modify + ** the schema cookie. + */ + sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); + sqlite3ChangeCookie(db, v, iDb); } sqliteViewResetAll(db, iDb); @@ -1693,12 +1964,13 @@ void sqlite3CreateForeignKey( ExprList *pToCol, /* Columns in the other table */ int flags /* Conflict resolution algorithms. */ ){ +#ifndef SQLITE_OMIT_FOREIGN_KEY + FKey *pFKey = 0; Table *p = pParse->pNewTable; int nByte; int i; int nCol; char *z; - FKey *pFKey = 0; assert( pTo!=0 ); if( p==0 || pParse->nErr ) goto fk_end; @@ -1779,6 +2051,7 @@ void sqlite3CreateForeignKey( fk_end: sqliteFree(pFKey); +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ sqlite3ExprListDelete(pFromCol); sqlite3ExprListDelete(pToCol); } @@ -1791,15 +2064,80 @@ fk_end: ** accordingly. */ void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +#ifndef SQLITE_OMIT_FOREIGN_KEY Table *pTab; FKey *pFKey; if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; pFKey->isDeferred = isDeferred; +#endif +} + +/* +** Generate code that will erase and refill index *pIdx. This is +** used to initialize a newly created index or to recompute the +** content of an index in response to a REINDEX command. +** +** if memRootPage is not negative, it means that the index is newly +** created. The memory cell specified by memRootPage contains the +** root page number of the index. If memRootPage is negative, then +** the index already exists and must be cleared before being refilled and +** the root page number of the index is taken from pIndex->tnum. +*/ +static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ + Table *pTab = pIndex->pTable; /* The table that is indexed */ + int iTab = pParse->nTab; /* Btree cursor used for pTab */ + int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */ + int addr1; /* Address of top of loop */ + int tnum; /* Root page of index */ + Vdbe *v; /* Generate code into this virtual machine */ + int isUnique; /* True for a unique index */ + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, + pParse->db->aDb[pIndex->iDb].zName ) ){ + return; + } +#endif + + /* Ensure all the required collation sequences are available. This + ** routine will invoke the collation-needed callback if necessary (and + ** if one has been registered). + */ + if( sqlite3CheckIndexCollSeq(pParse, pIndex) ){ + return; + } + + v = sqlite3GetVdbe(pParse); + if( v==0 ) return; + if( memRootPage>=0 ){ + sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0); + tnum = 0; + }else{ + tnum = pIndex->tnum; + sqlite3VdbeAddOp(v, OP_Clear, tnum, pIndex->iDb); + } + sqlite3VdbeAddOp(v, OP_Integer, pIndex->iDb, 0); + sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, + (char*)&pIndex->keyInfo, P3_KEYINFO); + sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenRead, iTab, pTab->tnum); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pTab->nCol); + addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); + sqlite3GenerateIndexKey(v, pIndex, iTab); + isUnique = pIndex->onError!=OE_None; + sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique); + if( isUnique ){ + sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC); + } + sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1); + sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp(v, OP_Close, iTab, 0); + sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); } /* -** Create a new index for an SQL table. pIndex is the name of the index -** and pTable is the name of the table that is to be indexed. Both will +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is @@ -1810,16 +2148,16 @@ void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ ** to the table currently under construction. */ void sqlite3CreateIndex( - Parse *pParse, /* All information about this parse */ - Token *pName1, /* First part of index name. May be NULL */ - Token *pName2, /* Second part of index name. May be NULL */ - SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ + Parse *pParse, /* All information about this parse */ + Token *pName1, /* First part of index name. May be NULL */ + Token *pName2, /* Second part of index name. May be NULL */ + SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ ExprList *pList, /* A list of columns to be indexed */ - int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ - Token *pEnd /* The ")" that closes the CREATE INDEX statement */ + int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ + Token *pEnd /* The ")" that closes the CREATE INDEX statement */ ){ - Table *pTab = 0; /* Table to be indexed */ + Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ char *zName = 0; int i, j; @@ -1874,10 +2212,12 @@ void sqlite3CreateIndex( sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } +#ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ sqlite3ErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; } +#endif isTemp = pTab->iDb==1; /* @@ -1913,7 +2253,7 @@ void sqlite3CreateIndex( goto exit_create_index; } } - }else if( pName==0 ){ + }else{ char zBuf[30]; int n; Index *pLoop; @@ -2076,60 +2416,55 @@ void sqlite3CreateIndex( ** step can be skipped. */ else if( db->init.busy==0 ){ - int n; Vdbe *v; - int lbl1, lbl2; + char *zStmt; + int iMem = pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) goto exit_create_index; - if( pTblName!=0 ){ - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3OpenMasterTable(v, iDb); - } - sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, "index", P3_STATIC); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pIndex->zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); + + /* Create the rootpage for the index + */ + sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0); - if( pTblName ){ - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeOp3(v, OP_OpenWrite, 1, 0, - (char*)&pIndex->keyInfo, P3_KEYINFO); - } - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0); + + /* Gather the complete text of the CREATE INDEX statement into + ** the zStmt variable + */ if( pStart && pEnd ){ - if( onError==OE_None ){ - sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC); - }else{ - sqlite3VdbeChangeP3(v, -1, "CREATE UNIQUE INDEX ", P3_STATIC); - } - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - n = Addr(pEnd->z) - Addr(pName->z) + 1; - sqlite3VdbeChangeP3(v, -1, pName->z, n); - sqlite3VdbeAddOp(v, OP_Concat, 0, 0); + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", + Addr(pEnd->z) - Addr(pName->z) + 1, + pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; } - sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); - sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); + + /* Add an entry in sqlite_master for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pIndex->zName, + pTab->zName, + zStmt + ); + sqlite3VdbeAddOp(v, OP_Pop, 1, 0); + sqliteFree(zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ if( pTblName ){ - sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum); - /* VdbeComment((v, "%s", pTab->zName)); */ - sqlite3VdbeAddOp(v, OP_SetNumColumns, 2, pTab->nCol); - lbl2 = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2); - lbl1 = sqlite3VdbeCurrentAddr(v); - sqlite3GenerateIndexKey(v, pIndex, 2); - sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None, - "indexed columns are not unique", P3_STATIC); - sqlite3VdbeAddOp(v, OP_Next, 2, lbl1); - sqlite3VdbeResolveLabel(v, lbl2); - sqlite3VdbeAddOp(v, OP_Close, 2, 0); - sqlite3VdbeAddOp(v, OP_Close, 1, 0); + sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(db, v, iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC); + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); } } @@ -2207,27 +2542,15 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ /* Generate code to remove the index and from the master table */ v = sqlite3GetVdbe(pParse); if( v ){ - static const VdbeOpList dropIndex[] = { - { OP_Rewind, 0, ADDR(9), 0}, - { OP_String8, 0, 0, 0}, /* 1 */ - { OP_MemStore, 1, 1, 0}, - { OP_MemLoad, 1, 0, 0}, /* 3 */ - { OP_Column, 0, 1, 0}, - { OP_Eq, 0, ADDR(8), 0}, - { OP_Next, 0, ADDR(3), 0}, - { OP_Goto, 0, ADDR(9), 0}, - { OP_Delete, 0, 0, 0}, /* 8 */ - }; - int base; - - sqlite3BeginWriteOperation(pParse, 0, pIndex->iDb); - sqlite3OpenMasterTable(v, pIndex->iDb); - base = sqlite3VdbeAddOpList(v, ArraySize(dropIndex), dropIndex); - sqlite3VdbeChangeP3(v, base+1, pIndex->zName, 0); - sqlite3ChangeCookie(db, v, pIndex->iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - sqlite3VdbeAddOp(v, OP_Destroy, pIndex->tnum, pIndex->iDb); - sqlite3VdbeOp3(v, OP_DropIndex, pIndex->iDb, 0, pIndex->zName, 0); + int iDb = pIndex->iDb; + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE name=%Q", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pIndex->zName + ); + sqlite3ChangeCookie(db, v, iDb); + destroyRootPage(pParse, pIndex->tnum, iDb); + sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0); } exit_drop_index: @@ -2327,9 +2650,12 @@ SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){ */ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - for(i=0; inSrc; i++){ - if( pList->a[i].iCursor<0 ){ - pList->a[i].iCursor = pParse->nTab++; + struct SrcList_item *pItem; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pItem->iCursor>=0 ) break; + pItem->iCursor = pParse->nTab++; + if( pItem->pSelect ){ + sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); } } } @@ -2544,7 +2870,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ if( v==0 ) return; sqlite3CodeVerifySchema(pParse, iDb); pParse->writeMask |= 1<nested==0 ){ sqlite3VdbeAddOp(v, OP_Statement, iDb, 0); } if( iDb!=1 && pParse->db->aDb[1].pBt!=0 ){ @@ -2552,6 +2878,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ } } +#ifndef SQLITE_OMIT_UTF16 /* ** Return the transient sqlite3_value object used for encoding conversions ** during SQL compilation. @@ -2562,3 +2889,121 @@ sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){ } return db->pValue; } +#endif + +/* +** Check to see if pIndex uses the collating sequence pColl. Return +** true if it does and false if it does not. +*/ +#ifndef SQLITE_OMIT_REINDEX +static int collationMatch(CollSeq *pColl, Index *pIndex){ + int n = pIndex->keyInfo.nField; + CollSeq **pp = pIndex->keyInfo.aColl; + while( n-- ){ + if( *pp==pColl ) return 1; + pp++; + } + return 0; +} +#endif + +/* +** Recompute all indices of pTab that use the collating sequence pColl. +** If pColl==0 then recompute all indices of pTab. +*/ +#ifndef SQLITE_OMIT_REINDEX +void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){ + Index *pIndex; /* An index associated with pTab */ + + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( pColl==0 || collationMatch(pColl,pIndex) ){ + sqlite3BeginWriteOperation(pParse, 0, pTab->iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + } + } +} +#endif + +/* +** Recompute all indices of all tables in all databases where the +** indices use the collating sequence pColl. If pColl==0 then recompute +** all indices everywhere. +*/ +#ifndef SQLITE_OMIT_REINDEX +void reindexDatabases(Parse *pParse, CollSeq *pColl){ + Db *pDb; /* A single database */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + HashElem *k; /* For looping over tables in pDb */ + Table *pTab; /* A table in the database */ + + for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ + if( pDb==0 ) continue; + for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + reindexTable(pParse, pTab, pColl); + } + } +} +#endif + +/* +** Generate code for the REINDEX command. +** +** REINDEX -- 1 +** REINDEX -- 2 +** REINDEX ?.? -- 3 +** REINDEX ?.? -- 4 +** +** Form 1 causes all indices in all attached databases to be rebuilt. +** Form 2 rebuilds all indices in all databases that use the named +** collating function. Forms 3 and 4 rebuild the named index or all +** indices associated with the named table. +*/ +#ifndef SQLITE_OMIT_REINDEX +void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ + CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ + char *z; /* Name of a table or index */ + const char *zDb; /* Name of the database */ + Table *pTab; /* A table in the database */ + Index *pIndex; /* An index associated with pTab */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + Token *pObjName; /* Name of the table or index to be reindexed */ + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + if( pName1==0 || pName1->z==0 ){ + reindexDatabases(pParse, 0); + return; + }else if( pName2==0 || pName2->z==0 ){ + pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0); + if( pColl ){ + reindexDatabases(pParse, pColl); + return; + } + } + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + if( iDb<0 ) return; + z = sqlite3NameFromToken(pObjName); + zDb = db->aDb[iDb].zName; + pTab = sqlite3FindTable(db, z, zDb); + if( pTab ){ + reindexTable(pParse, pTab, 0); + sqliteFree(z); + return; + } + pIndex = sqlite3FindIndex(db, z, zDb); + sqliteFree(z); + if( pIndex ){ + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + return; + } + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); +} +#endif diff --git a/ext/pdo_sqlite/sqlite/src/date.c b/ext/pdo_sqlite/sqlite/src/date.c index 634e81d5ed..8780a51b6d 100644 --- a/ext/pdo_sqlite/sqlite/src/date.c +++ b/ext/pdo_sqlite/sqlite/src/date.c @@ -315,12 +315,10 @@ static int parseDateOrTime(const char *zDate, DateTime *p){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ double r; - if( sqlite3OsCurrentTime(&r)==0 ){ - p->rJD = r; - p->validJD = 1; - return 0; - } - return 1; + sqlite3OsCurrentTime(&r); + p->rJD = r; + p->validJD = 1; + return 0; }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){ p->rJD = sqlite3AtoF(zDate, 0); p->validJD = 1; @@ -862,9 +860,100 @@ static void strftimeFunc( } } +/* +** current_time() +** +** This function returns the same value as time('now'). +*/ +static void ctimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_value *pVal = sqlite3ValueNew(); + if( pVal ){ + sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); + timeFunc(context, 1, &pVal); + sqlite3ValueFree(pVal); + } +} +/* +** current_date() +** +** This function returns the same value as date('now'). +*/ +static void cdateFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_value *pVal = sqlite3ValueNew(); + if( pVal ){ + sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); + dateFunc(context, 1, &pVal); + sqlite3ValueFree(pVal); + } +} + +/* +** current_timestamp() +** +** This function returns the same value as datetime('now'). +*/ +static void ctimestampFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_value *pVal = sqlite3ValueNew(); + if( pVal ){ + sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); + datetimeFunc(context, 1, &pVal); + sqlite3ValueFree(pVal); + } +} #endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ +#ifdef SQLITE_OMIT_DATETIME_FUNCS +/* +** If the library is compiled to omit the full-scale date and time +** handling (to get a smaller binary), the following minimal version +** of the functions current_time(), current_date() and current_timestamp() +** are included instead. This is to support column declarations that +** include "DEFAULT CURRENT_TIME" etc. +** +** This function uses the C-library functions time(), gmtime() +** and strftime(). The format string to pass to strftime() is supplied +** as the user-data for the function. +*/ +static void currentTimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + time_t t; + char *zFormat = (char *)sqlite3_user_data(context); + char zBuf[20]; + + time(&t); +#ifdef SQLITE_TEST + { + extern int sqlite3_current_time; /* See os_XXX.c */ + if( sqlite3_current_time ){ + t = sqlite3_current_time; + } + } +#endif + + sqlite3OsEnterMutex(); + strftime(zBuf, 20, zFormat, gmtime(&t)); + sqlite3OsLeaveMutex(); + + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); +} +#endif + /* ** This function registered all of the above C functions as SQL ** functions. This should be the only routine in this file with @@ -882,6 +971,9 @@ void sqlite3RegisterDateTimeFunctions(sqlite3 *db){ { "time", -1, timeFunc }, { "datetime", -1, datetimeFunc }, { "strftime", -1, strftimeFunc }, + { "current_time", 0, ctimeFunc }, + { "current_timestamp", 0, ctimestampFunc }, + { "current_date", 0, cdateFunc }, }; int i; @@ -889,5 +981,20 @@ void sqlite3RegisterDateTimeFunctions(sqlite3 *db){ sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0); } +#else + static const struct { + char *zName; + char *zFormat; + } aFuncs[] = { + { "current_time", "%H:%M:%S" }, + { "current_date", "%Y-%m-%d" }, + { "current_timestamp", "%Y-%m-%d %H:%M:%S" } + }; + int i; + + for(i=0; ireadOnly ){ + if( pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0 + && pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } +#ifndef SQLITE_OMIT_VIEW if( !viewOk && pTab->pSelect ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); return 1; } +#endif return 0; } @@ -65,7 +68,11 @@ void sqlite3OpenTableForReading( /* -** Process a DELETE FROM statement. +** Generate code for a DELETE FROM statement. +** +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; +** \________/ \________________/ +** pTabList pWhere */ void sqlite3DeleteFrom( Parse *pParse, /* The parser context */ @@ -81,13 +88,14 @@ void sqlite3DeleteFrom( Index *pIdx; /* For looping over indices of the table */ int iCur; /* VDBE Cursor number for pTab */ sqlite3 *db; /* Main database structure */ - int isView; /* True if attempting to delete from a view */ AuthContext sContext; /* Authorization context */ + int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ + NameContext sNC; /* Name context to resolve expressions in */ - int row_triggers_exist = 0; /* True if any triggers exist */ - int before_triggers; /* True if there are BEFORE triggers */ - int after_triggers; /* True if there are AFTER triggers */ - int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to delete from a view */ + int triggers_exist = 0; /* True if any triggers exist */ +#endif sContext.pParse = 0; if( pParse->nErr || sqlite3_malloc_failed ){ @@ -104,13 +112,23 @@ void sqlite3DeleteFrom( */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto delete_from_cleanup; - before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, - TK_DELETE, TK_BEFORE, TK_ROW, 0); - after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, - TK_DELETE, TK_AFTER, TK_ROW, 0); - row_triggers_exist = before_triggers || after_triggers; + + /* Figure out if we have any triggers and if the table being + ** deleted from is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0); isView = pTab->pSelect!=0; - if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){ +#else +# define triggers_exist 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + + if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ goto delete_from_cleanup; } assert( pTab->iDbnDb ); @@ -127,15 +145,18 @@ void sqlite3DeleteFrom( /* Allocate a cursor used to store the old.* data for a trigger. */ - if( row_triggers_exist ){ + if( triggers_exist ){ oldIdx = pParse->nTab++; } - /* Resolve the column names in all the expressions. + /* Resolve the column names in the WHERE clause. */ assert( pTabList->nSrc==1 ); iCur = pTabList->a[0].iCursor = pParse->nTab++; - if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0, pWhere, 0, 0) ){ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + if( sqlite3ExprResolveNames(&sNC, pWhere) ){ goto delete_from_cleanup; } @@ -151,8 +172,8 @@ void sqlite3DeleteFrom( if( v==0 ){ goto delete_from_cleanup; } - sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, row_triggers_exist, pTab->iDb); + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, triggers_exist, pTab->iDb); /* If we are trying to delete from a view, construct that view into ** a temporary table. @@ -174,7 +195,7 @@ void sqlite3DeleteFrom( ** It is easier just to erase the whole table. Note, however, that ** this means that the row change count will be incorrect. */ - if( pWhere==0 && !row_triggers_exist ){ + if( pWhere==0 && !triggers_exist ){ if( db->flags & SQLITE_CountRows ){ /* If counting rows deleted, just count the total number of ** entries in the table. */ @@ -210,11 +231,12 @@ void sqlite3DeleteFrom( /* Begin the database scan */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0); if( pWInfo==0 ) goto delete_from_cleanup; - /* Remember the key of every item to be deleted. + /* Remember the rowid of every item to be deleted. */ + sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); @@ -226,7 +248,7 @@ void sqlite3DeleteFrom( /* Open the pseudo-table used to store OLD if there are triggers. */ - if( row_triggers_exist ){ + if( triggers_exist ){ sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol); } @@ -241,7 +263,7 @@ void sqlite3DeleteFrom( /* This is the beginning of the delete loop when there are ** row triggers. */ - if( row_triggers_exist ){ + if( triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); if( !isView ){ @@ -255,8 +277,8 @@ void sqlite3DeleteFrom( sqlite3VdbeAddOp(v, OP_Close, iCur, 0); } - sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1, - oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, + (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab, + -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, addr); } @@ -271,25 +293,25 @@ void sqlite3DeleteFrom( /* This is the beginning of the delete loop when there are no ** row triggers */ - if( !row_triggers_exist ){ + if( !triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); } /* Delete the row */ - sqlite3GenerateRowDelete(db, v, pTab, iCur, 1); + sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0); } /* If there are row triggers, close all cursors then invoke ** the AFTER triggers */ - if( row_triggers_exist ){ + if( triggers_exist ){ if( !isView ){ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum); } sqlite3VdbeAddOp(v, OP_Close, iCur, 0); } - sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1, + (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, addr); } @@ -300,7 +322,7 @@ void sqlite3DeleteFrom( sqlite3VdbeAddOp(v, OP_ListReset, 0, 0); /* Close the cursors after the loop if there are no row triggers */ - if( !row_triggers_exist ){ + if( !triggers_exist ){ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum); } @@ -309,9 +331,11 @@ void sqlite3DeleteFrom( } /* - ** Return the number of rows that were deleted. + ** Return the number of rows that were deleted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. */ - if( db->flags & SQLITE_CountRows ){ + if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC); diff --git a/ext/pdo_sqlite/sqlite/src/experimental.c b/ext/pdo_sqlite/sqlite/src/experimental.c new file mode 100644 index 0000000000..073f21835c --- /dev/null +++ b/ext/pdo_sqlite/sqlite/src/experimental.c @@ -0,0 +1,38 @@ + +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle SELECT statements in SQLite. +** +** $Id$ +*/ +#include "sqliteInt.h" + +/* +** Set all the parameters in the compiled SQL statement to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ + int i; + int rc = SQLITE_OK; + for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){ + rc = sqlite3_bind_null(pStmt, i); + } + return rc; +} + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +int sqlite3_sleep(int ms){ + return sqlite3OsSleep(ms); +} + diff --git a/ext/pdo_sqlite/sqlite/src/expr.c b/ext/pdo_sqlite/sqlite/src/expr.c index 2da3645b9b..c4943b1f83 100644 --- a/ext/pdo_sqlite/sqlite/src/expr.c +++ b/ext/pdo_sqlite/sqlite/src/expr.c @@ -62,8 +62,8 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ } /* -** pExpr is the left operand of a comparison operator. aff2 is the -** type affinity of the right operand. This routine returns the +** pExpr is an operand of a comparison operator. aff2 is the +** type affinity of the other operand. This routine returns the ** type affinity that should be used for the comparison operator. */ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ @@ -179,7 +179,7 @@ static int codeCompare( ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ -Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ +Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ @@ -189,6 +189,7 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ pNew->op = op; pNew->pLeft = pLeft; pNew->pRight = pRight; + pNew->iAgg = -1; if( pToken ){ assert( pToken->dyn==0 ); pNew->span = pNew->token = *pToken; @@ -198,6 +199,42 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ return pNew; } +/* +** When doing a nested parse, you can include terms in an expression +** that look like this: #0 #1 #2 ... These terms refer to elements +** on the stack. "#0" (or just "#") means the top of the stack. +** "#1" means the next down on the stack. And so forth. #-1 means +** memory location 0. #-2 means memory location 1. And so forth. +** +** This routine is called by the parser to deal with on of those terms. +** It immediately generates code to store the value in a memory location. +** The returns an expression that will code to extract the value from +** that memory location as needed. +*/ +Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){ + Vdbe *v = pParse->pVdbe; + Expr *p; + int depth; + if( v==0 ) return 0; + if( pParse->nested==0 ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken); + return 0; + } + p = sqlite3Expr(TK_REGISTER, 0, 0, pToken); + if( p==0 ){ + return 0; /* Malloc failed */ + } + depth = atoi(&pToken->z[1]); + if( depth>=0 ){ + p->iTable = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_Dup, depth, 0); + sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); + }else{ + p->iTable = -1-depth; + } + return p; +} + /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. @@ -356,7 +393,7 @@ Expr *sqlite3ExprDup(Expr *p){ 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 ); @@ -410,6 +447,15 @@ ExprList *sqlite3ExprListDup(ExprList *p){ } return pNew; } + +/* +** If cursors, triggers, views and subqueries are all omitted from +** the build, then none of the following routines, except for +** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes +** called with a NULL argument. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ + || !defined(SQLITE_OMIT_SUBQUERY) SrcList *sqlite3SrcListDup(SrcList *p){ SrcList *pNew; int i; @@ -427,10 +473,14 @@ SrcList *sqlite3SrcListDup(SrcList *p){ pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; - pNewItem->pTab = 0; + pNewItem->pTab = pOldItem->pTab; + if( pNewItem->pTab ){ + pNewItem->pTab->isTransient = 0; + } pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect); pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn); pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing); + pNewItem->colUsed = pOldItem->colUsed; } return pNew; } @@ -465,14 +515,22 @@ Select *sqlite3SelectDup(Select *p){ pNew->pOrderBy = sqlite3ExprListDup(p->pOrderBy); pNew->op = p->op; pNew->pPrior = sqlite3SelectDup(p->pPrior); - pNew->nLimit = p->nLimit; - pNew->nOffset = p->nOffset; - pNew->zSelect = 0; + pNew->pLimit = sqlite3ExprDup(p->pLimit); + pNew->pOffset = sqlite3ExprDup(p->pOffset); pNew->iLimit = -1; pNew->iOffset = -1; pNew->ppOpenTemp = 0; + pNew->pFetch = 0; + pNew->isResolved = p->isResolved; + pNew->isAgg = p->isAgg; return pNew; } +#else +Select *sqlite3SelectDup(Select *p){ + assert( p==0 ); + return 0; +} +#endif /* @@ -525,44 +583,104 @@ void sqlite3ExprListDelete(ExprList *pList){ } /* -** Walk an expression tree. Return 1 if the expression is constant -** and 0 if it involves variables. +** Walk an expression tree. Call xFunc for each node visited. ** -** For the purposes of this function, a double-quoted string (ex: "abc") -** is considered a variable but a single-quoted string (ex: 'abc') is -** a constant. +** The return value from xFunc determines whether the tree walk continues. +** 0 means continue walking the tree. 1 means do not walk children +** of the current node but continue with siblings. 2 means abandon +** the tree walk completely. +** +** The return value from this routine is 1 to abandon the tree walk +** and 0 to continue. */ -int sqlite3ExprIsConstant(Expr *p){ - switch( p->op ){ +static int walkExprList(ExprList *, int (*)(void *, Expr*), void *); +static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){ + int rc; + if( pExpr==0 ) return 0; + rc = (*xFunc)(pArg, pExpr); + if( rc==0 ){ + if( walkExprTree(pExpr->pLeft, xFunc, pArg) ) return 1; + if( walkExprTree(pExpr->pRight, xFunc, pArg) ) return 1; + if( walkExprList(pExpr->pList, xFunc, pArg) ) return 1; + } + return rc>1; +} + +/* +** Call walkExprTree() for every expression in list p. +*/ +static int walkExprList(ExprList *p, int (*xFunc)(void *, Expr*), void *pArg){ + int i; + struct ExprList_item *pItem; + if( !p ) return 0; + for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ + if( walkExprTree(pItem->pExpr, xFunc, pArg) ) return 1; + } + return 0; +} + +/* +** Call walkExprTree() for every expression in Select p, not including +** expressions that are part of sub-selects in any FROM clause or the LIMIT +** or OFFSET expressions.. +*/ +static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){ + walkExprList(p->pEList, xFunc, pArg); + walkExprTree(p->pWhere, xFunc, pArg); + walkExprList(p->pGroupBy, xFunc, pArg); + walkExprTree(p->pHaving, xFunc, pArg); + walkExprList(p->pOrderBy, xFunc, pArg); + return 0; +} + + +/* +** This routine is designed as an xFunc for walkExprTree(). +** +** pArg is really a pointer to an integer. If we can tell by looking +** at pExpr that the expression that contains pExpr is not a constant +** expression, then set *pArg to 0 and return 2 to abandon the tree walk. +** If pExpr does does not disqualify the expression from being a constant +** then do nothing. +** +** After walking the whole tree, if no nodes are found that disqualify +** the expression as constant, then we assume the whole expression +** is constant. See sqlite3ExprIsConstant() for additional information. +*/ +static int exprNodeIsConstant(void *pArg, Expr *pExpr){ + switch( pExpr->op ){ case TK_ID: case TK_COLUMN: case TK_DOT: + case TK_AGG_FUNCTION: case TK_FUNCTION: +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: + case TK_EXISTS: +#endif + *((int*)pArg) = 0; + return 2; + default: return 0; - case TK_NULL: - case TK_STRING: - case TK_BLOB: - case TK_INTEGER: - case TK_FLOAT: - case TK_VARIABLE: - return 1; - default: { - if( p->pLeft && !sqlite3ExprIsConstant(p->pLeft) ) return 0; - if( p->pRight && !sqlite3ExprIsConstant(p->pRight) ) return 0; - if( p->pList ){ - int i; - for(i=0; ipList->nExpr; i++){ - if( !sqlite3ExprIsConstant(p->pList->a[i].pExpr) ) return 0; - } - } - return p->pLeft!=0 || p->pRight!=0 || (p->pList && p->pList->nExpr>0); - } } - return 0; } /* -** If the given expression codes a constant integer that is small enough +** Walk an expression tree. Return 1 if the expression is constant +** and 0 if it involves variables. +** +** For the purposes of this function, a double-quoted string (ex: "abc") +** is considered a variable but a single-quoted string (ex: 'abc') is +** a constant. +*/ +int sqlite3ExprIsConstant(Expr *p){ + int isConst = 1; + walkExprTree(p, exprNodeIsConstant, &isConst); + return isConst; +} + +/* +** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. @@ -575,16 +693,6 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){ } break; } - case TK_STRING: { - const u8 *z = (u8*)p->token.z; - int n = p->token.n; - if( n>0 && z[0]=='-' ){ z++; n--; } - while( n>0 && *z && isdigit(*z) ){ z++; n--; } - if( n==0 && sqlite3GetInt32(p->token.z, pValue) ){ - return 1; - } - break; - } case TK_UPLUS: { return sqlite3ExprIsInteger(p->pLeft, pValue); } @@ -641,8 +749,7 @@ static int lookupName( Token *pDbToken, /* Name of the database containing table, or NULL */ Token *pTableToken, /* Name of table containing column, or NULL */ Token *pColumnToken, /* Name of the column. */ - SrcList *pSrcList, /* List of tables used to resolve column names */ - ExprList *pEList, /* List of expressions used to resolve "AS" */ + NameContext *pNC, /* The name context used to resolve the name */ Expr *pExpr /* Make this EXPR node point to the selected column */ ){ char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */ @@ -652,6 +759,9 @@ static int lookupName( int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ + struct SrcList_item *pItem; /* Use for looping over pSrcList items */ + struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); @@ -660,114 +770,132 @@ static int lookupName( if( sqlite3_malloc_failed ){ return 1; /* Leak memory (zDb and zTab) if malloc fails */ } - assert( zTab==0 || pEList==0 ); pExpr->iTable = -1; - for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrcList->a[i]; - Table *pTab = pItem->pTab; - Column *pCol; - - if( pTab==0 ) continue; - assert( pTab->nCol>0 ); - if( zTab ){ - if( pItem->zAlias ){ - char *zTabName = pItem->zAlias; - if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - }else{ - char *zTabName = pTab->zName; - if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ - continue; + while( pNC && cnt==0 ){ + SrcList *pSrcList = pNC->pSrcList; + ExprList *pEList = pNC->pEList; + + pNC->nRef++; + /* assert( zTab==0 || pEList==0 ); */ + if( pSrcList ){ + for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ + Table *pTab = pItem->pTab; + Column *pCol; + + if( pTab==0 ) continue; + assert( pTab->nCol>0 ); + if( zTab ){ + if( pItem->zAlias ){ + char *zTabName = pItem->zAlias; + if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; + }else{ + char *zTabName = pTab->zName; + if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; + if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ + continue; + } + } + } + if( 0==(cntTab++) ){ + pExpr->iTable = pItem->iCursor; + pExpr->iDb = pTab->iDb; + pMatch = pItem; + } + for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + cnt++; + pExpr->iTable = pItem->iCursor; + pMatch = pItem; + pExpr->iDb = pTab->iDb; + /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ + pExpr->iColumn = j==pTab->iPKey ? -1 : j; + pExpr->affinity = pTab->aCol[j].affinity; + pExpr->pColl = pTab->aCol[j].pColl; + break; + } } } } - if( 0==(cntTab++) ){ - pExpr->iTable = pItem->iCursor; - pExpr->iDb = pTab->iDb; - } - for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - cnt++; - pExpr->iTable = pItem->iCursor; - pExpr->iDb = pTab->iDb; - /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ - pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = pTab->aCol[j].pColl; - break; + +#ifndef SQLITE_OMIT_TRIGGER + /* If we have not already resolved the name, then maybe + ** it is a new.* or old.* trigger argument reference + */ + if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){ + TriggerStack *pTriggerStack = pParse->trigStack; + Table *pTab = 0; + if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){ + pExpr->iTable = pTriggerStack->newIdx; + assert( pTriggerStack->pTab ); + pTab = pTriggerStack->pTab; + }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){ + pExpr->iTable = pTriggerStack->oldIdx; + assert( pTriggerStack->pTab ); + pTab = pTriggerStack->pTab; } - } - } - /* If we have not already resolved the name, then maybe - ** it is a new.* or old.* trigger argument reference - */ - if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){ - TriggerStack *pTriggerStack = pParse->trigStack; - Table *pTab = 0; - if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){ - pExpr->iTable = pTriggerStack->newIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab) == 0 ){ - pExpr->iTable = pTriggerStack->oldIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - } - - if( pTab ){ - int j; - Column *pCol = pTab->aCol; - - pExpr->iDb = pTab->iDb; - cntTab++; - for(j=0; j < pTab->nCol; j++, pCol++) { - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - cnt++; - pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = pTab->aCol[j].pColl; - break; + if( pTab ){ + int j; + Column *pCol = pTab->aCol; + + pExpr->iDb = pTab->iDb; + cntTab++; + for(j=0; j < pTab->nCol; j++, pCol++) { + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + cnt++; + pExpr->iColumn = j==pTab->iPKey ? -1 : j; + pExpr->affinity = pTab->aCol[j].affinity; + pExpr->pColl = pTab->aCol[j].pColl; + break; + } } } } - } +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ - /* - ** Perhaps the name is a reference to the ROWID - */ - if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ - cnt = 1; - pExpr->iColumn = -1; - pExpr->affinity = SQLITE_AFF_INTEGER; - } + /* + ** Perhaps the name is a reference to the ROWID + */ + if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ + cnt = 1; + pExpr->iColumn = -1; + pExpr->affinity = SQLITE_AFF_INTEGER; + } - /* - ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z - ** might refer to an result-set alias. This happens, for example, when - ** we are resolving names in the WHERE clause of the following command: - ** - ** SELECT a+b AS x FROM table WHERE x<10; - ** - ** In cases like this, replace pExpr with a copy of the expression that - ** forms the result set entry ("a+b" in the example) and return immediately. - ** Note that the expression in the result set should have already been - ** resolved by the time the WHERE clause is resolved. - */ - if( cnt==0 && pEList!=0 ){ - for(j=0; jnExpr; j++){ - char *zAs = pEList->a[j].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - pExpr->op = TK_AS; - pExpr->iColumn = j; - pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr); - sqliteFree(zCol); - assert( zTab==0 && zDb==0 ); - return 0; - } - } + /* + ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z + ** might refer to an result-set alias. This happens, for example, when + ** we are resolving names in the WHERE clause of the following command: + ** + ** SELECT a+b AS x FROM table WHERE x<10; + ** + ** In cases like this, replace pExpr with a copy of the expression that + ** forms the result set entry ("a+b" in the example) and return immediately. + ** Note that the expression in the result set should have already been + ** resolved by the time the WHERE clause is resolved. + */ + if( cnt==0 && pEList!=0 && zTab==0 ){ + for(j=0; jnExpr; j++){ + char *zAs = pEList->a[j].zName; + if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + pExpr->op = TK_AS; + pExpr->iColumn = j; + pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr); + sqliteFree(zCol); + assert( zTab==0 && zDb==0 ); + return 0; + } + } + } + + /* Advance to the next name context. The loop will exit when either + ** we have a match (cnt>0) or when we run out of name contexts. + */ + if( cnt==0 ){ + pNC = pNC->pNext; + } } /* @@ -799,6 +927,22 @@ static int lookupName( } sqlite3ErrorMsg(pParse, zErr, z); sqliteFree(z); + pTopNC->nErr++; + } + + /* If a column from a table in pSrcList is referenced, then record + ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes + ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the + ** column number is greater than the number of bits in the bitmask + ** then set the high-order bit of the bitmask. + */ + if( pExpr->iColumn>=0 && pMatch!=0 ){ + int n = pExpr->iColumn; + if( n>=sizeof(Bitmask)*8 ){ + n = sizeof(Bitmask)*8-1; + } + assert( pMatch->iCursor==pExpr->iTable ); + pMatch->colUsed |= 1<pRight); pExpr->pRight = 0; pExpr->op = TK_COLUMN; - sqlite3AuthRead(pParse, pExpr, pSrcList); + if( cnt==1 ){ + assert( pNC!=0 ); + sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); + } return cnt!=1; } /* -** This routine walks an expression tree and resolves references to -** table columns. Nodes of the form ID.ID or ID resolve into an -** index to the table in the table list and a column offset. The -** Expr.opcode for such nodes is changed to TK_COLUMN. The Expr.iTable -** value is changed to the index of the referenced table in pTabList -** plus the "base" value. The base value will ultimately become the -** VDBE cursor number for a cursor that is pointing into the referenced -** table. The Expr.iColumn value is changed to the index of the column -** of the referenced table. The Expr.iColumn value for the special -** ROWID column is -1. Any INTEGER PRIMARY KEY column is tried as an -** alias for ROWID. -** -** We also check for instances of the IN operator. IN comes in two -** forms: -** -** expr IN (exprlist) -** and -** expr IN (SELECT ...) +** pExpr is a node that defines a function of some kind. It might +** be a syntactic function like "count(x)" or it might be a function +** that implements an operator, like "a LIKE b". ** -** The first form is handled by creating a set holding the list -** of allowed values. The second form causes the SELECT to generate -** a temporary table. +** This routine makes *pzName point to the name of the function and +** *pnName hold the number of characters in the function name. +*/ +static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){ + switch( pExpr->op ){ + case TK_FUNCTION: { + *pzName = pExpr->token.z; + *pnName = pExpr->token.n; + break; + } + case TK_LIKE: { + *pzName = "like"; + *pnName = 4; + break; + } + case TK_GLOB: { + *pzName = "glob"; + *pnName = 4; + break; + } + case TK_CTIME: { + *pzName = "current_time"; + *pnName = 12; + break; + } + case TK_CDATE: { + *pzName = "current_date"; + *pnName = 12; + break; + } + case TK_CTIMESTAMP: { + *pzName = "current_timestamp"; + *pnName = 17; + break; + } + } +} + +/* +** This routine is designed as an xFunc for walkExprTree(). ** -** This routine also looks for scalar SELECTs that are part of an expression. -** If it finds any, it generates code to write the value of that select -** into a memory cell. +** Resolve symbolic names into TK_COLUMN operators for the current +** node in the expression tree. Return 0 to continue the search down +** the tree or 2 to abort the tree walk. ** -** Unknown columns or tables provoke an error. The function returns -** the number of errors seen and leaves an error message on pParse->zErrMsg. +** This routine also does error checking and name resolution for +** function names. The operator for aggregate functions is changed +** to TK_AGG_FUNCTION. */ -int sqlite3ExprResolveIds( - Parse *pParse, /* The parser context */ - SrcList *pSrcList, /* List of tables used to resolve column names */ - ExprList *pEList, /* List of expressions used to resolve "AS" */ - Expr *pExpr /* The expression to be analyzed. */ -){ - int i; - - if( pExpr==0 || pSrcList==0 ) return 0; - for(i=0; inSrc; i++){ - assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab ); +static int nameResolverStep(void *pArg, Expr *pExpr){ + NameContext *pNC = (NameContext*)pArg; + SrcList *pSrcList; + Parse *pParse; + + if( pExpr==0 ) return 1; + assert( pNC!=0 ); + pSrcList = pNC->pSrcList; + pParse = pNC->pParse; + + if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1; + ExprSetProperty(pExpr, EP_Resolved); +#ifndef NDEBUG + if( pSrcList ){ + int i; + for(i=0; inSrc; i++){ + assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); + } } +#endif switch( pExpr->op ){ /* Double-quoted strings (ex: "abc") are used as identifiers if ** possible. Otherwise they remain as strings. Single-quoted @@ -867,13 +1045,11 @@ int sqlite3ExprResolveIds( if( pExpr->token.z[0]=='\'' ) break; /* Fall thru into the TK_ID case if this is a double-quoted string */ } - /* A lone identifier is the name of a columnd. + /* A lone identifier is the name of a column. */ case TK_ID: { - if( lookupName(pParse, 0, 0, &pExpr->token, pSrcList, pEList, pExpr) ){ - return 1; - } - break; + lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr); + return 1; } /* A table name and column name: ID.ID @@ -885,6 +1061,7 @@ int sqlite3ExprResolveIds( Token *pDb; Expr *pRight; + /* if( pSrcList==0 ) break; */ pRight = pExpr->pRight; if( pRight->op==TK_ID ){ pDb = 0; @@ -896,22 +1073,171 @@ int sqlite3ExprResolveIds( pTable = &pRight->pLeft->token; pColumn = &pRight->pRight->token; } - if( lookupName(pParse, pDb, pTable, pColumn, pSrcList, 0, pExpr) ){ - return 1; + lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr); + return 1; + } + + /* Resolve function names + */ + case TK_CTIME: + case TK_CTIMESTAMP: + case TK_CDATE: + case TK_GLOB: + case TK_LIKE: + case TK_FUNCTION: { + ExprList *pList = pExpr->pList; /* The argument list */ + int n = pList ? pList->nExpr : 0; /* Number of arguments */ + int no_such_func = 0; /* True if no such function exists */ + int wrong_num_args = 0; /* True if wrong number of arguments */ + int is_agg = 0; /* True if is an aggregate function */ + int i; + int nId; /* Number of characters in function name */ + const char *zId; /* The function name. */ + FuncDef *pDef; /* Information about the function */ + int enc = pParse->db->enc; /* The database encoding */ + + getFunctionName(pExpr, &zId, &nId); + pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); + if( pDef==0 ){ + pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); + if( pDef==0 ){ + no_such_func = 1; + }else{ + wrong_num_args = 1; + } + }else{ + is_agg = pDef->xFunc==0; + } + if( is_agg && !pNC->allowAgg ){ + sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); + pNC->nErr++; + is_agg = 0; + }else if( no_such_func ){ + sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + pNC->nErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", + nId, zId); + pNC->nErr++; + } + if( is_agg ){ + pExpr->op = TK_AGG_FUNCTION; + pNC->hasAgg = 1; + } + if( is_agg ) pNC->allowAgg = 0; + for(i=0; pNC->nErr==0 && ia[i].pExpr, nameResolverStep, pNC); + } + if( is_agg ) pNC->allowAgg = 1; + /* FIX ME: Compute pExpr->affinity based on the expected return + ** type of the function + */ + return is_agg; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: + case TK_EXISTS: +#endif + case TK_IN: { + if( pExpr->pSelect ){ + int nRef = pNC->nRef; + sqlite3SelectResolve(pParse, pExpr->pSelect, pNC); + assert( pNC->nRef>=nRef ); + if( nRef!=pNC->nRef ){ + ExprSetProperty(pExpr, EP_VarSelect); + } } - break; } + } + return 0; +} +/* +** This routine walks an expression tree and resolves references to +** table columns. Nodes of the form ID.ID or ID resolve into an +** index to the table in the table list and a column offset. The +** Expr.opcode for such nodes is changed to TK_COLUMN. The Expr.iTable +** value is changed to the index of the referenced table in pTabList +** plus the "base" value. The base value will ultimately become the +** VDBE cursor number for a cursor that is pointing into the referenced +** table. The Expr.iColumn value is changed to the index of the column +** of the referenced table. The Expr.iColumn value for the special +** ROWID column is -1. Any INTEGER PRIMARY KEY column is tried as an +** alias for ROWID. +** +** Also resolve function names and check the functions for proper +** usage. Make sure all function names are recognized and all functions +** have the correct number of arguments. Leave an error message +** in pParse->zErrMsg if anything is amiss. Return the number of errors. +** +** If the expression contains aggregate functions then set the EP_Agg +** property on the expression. +*/ +int sqlite3ExprResolveNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + Expr *pExpr /* The expression to be analyzed. */ +){ + if( pExpr==0 ) return 0; + walkExprTree(pExpr, nameResolverStep, pNC); + if( pNC->nErr>0 ){ + ExprSetProperty(pExpr, EP_Error); + } + return ExprHasProperty(pExpr, EP_Error); +} + +/* +** A pointer instance of this structure is used to pass information +** through walkExprTree into codeSubqueryStep(). +*/ +typedef struct QueryCoder QueryCoder; +struct QueryCoder { + Parse *pParse; /* The parsing context */ + NameContext *pNC; /* Namespace of first enclosing query */ +}; + + +/* +** Generate code for subqueries and IN operators. +** +** IN operators comes in two forms: +** +** expr IN (exprlist) +** and +** expr IN (SELECT ...) +** +** The first form is handled by creating a set holding the list +** of allowed values. The second form causes the SELECT to generate +** a temporary table. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ + int label = 0; /* Address after sub-select code */ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v==0 ) return; + + /* If this is not a variable (correlated) select, then execute + ** it only once. Unless this is part of a trigger program. In + ** that case re-execute every time (this could be optimized). + */ + if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ + int mem = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); + label = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp(v, OP_If, 0, label); + sqlite3VdbeAddOp(v, OP_Integer, 1, 0); + sqlite3VdbeAddOp(v, OP_MemStore, mem, 1); + } + + if( pExpr->pSelect ){ + sqlite3VdbeAddOp(v, OP_AggContextPush, 0, 0); + } + + switch( pExpr->op ){ case TK_IN: { char affinity; - Vdbe *v = sqlite3GetVdbe(pParse); KeyInfo keyInfo; int addr; /* Address of OP_OpenTemp instruction */ - if( v==0 ) return 1; - if( sqlite3ExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){ - return 1; - } affinity = sqlite3ExprAffinity(pExpr->pLeft); /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' @@ -970,10 +1296,7 @@ int sqlite3ExprResolveIds( if( !sqlite3ExprIsConstant(pE2) ){ sqlite3ErrorMsg(pParse, "right-hand side of IN operator must be constant"); - return 1; - } - if( sqlite3ExprCheck(pParse, pE2, 0, 0) ){ - return 1; + return; } /* Evaluate the expression and insert it into the temp table */ @@ -984,183 +1307,43 @@ int sqlite3ExprResolveIds( } } sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO); - break; } + case TK_EXISTS: case TK_SELECT: { /* This has to be a scalar SELECT. Generate code to put the ** value of this select in a memory cell and record the number ** of the memory cell in iColumn. */ - pExpr->iColumn = pParse->nMem++; - if(sqlite3Select(pParse, pExpr->pSelect, SRT_Mem,pExpr->iColumn,0,0,0,0)){ - return 1; - } - break; - } - - /* For all else, just recursively walk the tree */ - default: { - if( pExpr->pLeft - && sqlite3ExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){ - return 1; - } - if( pExpr->pRight - && sqlite3ExprResolveIds(pParse, pSrcList, pEList, pExpr->pRight) ){ - return 1; - } - if( pExpr->pList ){ - int i; - ExprList *pList = pExpr->pList; - for(i=0; inExpr; i++){ - Expr *pArg = pList->a[i].pExpr; - if( sqlite3ExprResolveIds(pParse, pSrcList, pEList, pArg) ){ - return 1; - } - } - } - } - } - return 0; -} - -/* -** pExpr is a node that defines a function of some kind. It might -** be a syntactic function like "count(x)" or it might be a function -** that implements an operator, like "a LIKE b". -** -** This routine makes *pzName point to the name of the function and -** *pnName hold the number of characters in the function name. -*/ -static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){ - switch( pExpr->op ){ - case TK_FUNCTION: { - *pzName = pExpr->token.z; - *pnName = pExpr->token.n; - break; - } - case TK_LIKE: { - *pzName = "like"; - *pnName = 4; - break; - } - case TK_GLOB: { - *pzName = "glob"; - *pnName = 4; - break; - } - default: { - *pzName = "can't happen"; - *pnName = 12; - break; - } - } -} - -/* -** Error check the functions in an expression. Make sure all -** function names are recognized and all functions have the correct -** number of arguments. Leave an error message in pParse->zErrMsg -** if anything is amiss. Return the number of errors. -** -** if pIsAgg is not null and this expression is an aggregate function -** (like count(*) or max(value)) then write a 1 into *pIsAgg. -*/ -int sqlite3ExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){ - int nErr = 0; - if( pExpr==0 ) return 0; - switch( pExpr->op ){ - case TK_GLOB: - case TK_LIKE: - case TK_FUNCTION: { - int n = pExpr->pList ? pExpr->pList->nExpr : 0; /* Number of arguments */ - int no_such_func = 0; /* True if no such function exists */ - int wrong_num_args = 0; /* True if wrong number of arguments */ - int is_agg = 0; /* True if is an aggregate function */ - int i; - int nId; /* Number of characters in function name */ - const char *zId; /* The function name. */ - FuncDef *pDef; - int enc = pParse->db->enc; + int sop; + Select *pSel; - getFunctionName(pExpr, &zId, &nId); - pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); - if( pDef==0 ){ - pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); - if( pDef==0 ){ - no_such_func = 1; - }else{ - wrong_num_args = 1; - } + pExpr->iColumn = pParse->nMem++; + pSel = pExpr->pSelect; + if( pExpr->op==TK_SELECT ){ + sop = SRT_Mem; }else{ - is_agg = pDef->xFunc==0; - } - if( is_agg && !allowAgg ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId, zId); - nErr++; - is_agg = 0; - }else if( no_such_func ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - nErr++; - }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); - nErr++; - } - if( is_agg ){ - pExpr->op = TK_AGG_FUNCTION; - if( pIsAgg ) *pIsAgg = 1; - } - for(i=0; nErr==0 && ipList->a[i].pExpr, - allowAgg && !is_agg, pIsAgg); - } - /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function - */ - } - default: { - if( pExpr->pLeft ){ - nErr = sqlite3ExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg); - } - if( nErr==0 && pExpr->pRight ){ - nErr = sqlite3ExprCheck(pParse, pExpr->pRight, allowAgg, pIsAgg); - } - if( nErr==0 && pExpr->pList ){ - int n = pExpr->pList->nExpr; - int i; - for(i=0; nErr==0 && ipList->a[i].pExpr; - nErr = sqlite3ExprCheck(pParse, pE2, allowAgg, pIsAgg); - } + static const Token one = { "1", 0, 1 }; + sop = SRT_Exists; + sqlite3ExprListDelete(pSel->pEList); + pSel->pEList = sqlite3ExprListAppend(0, + sqlite3Expr(TK_INTEGER, 0, 0, &one), 0); } + sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0); break; } } - return nErr; -} -/* -** Call sqlite3ExprResolveIds() followed by sqlite3ExprCheck(). -** -** This routine is provided as a convenience since it is very common -** to call ResolveIds() and Check() back to back. -*/ -int sqlite3ExprResolveAndCheck( - Parse *pParse, /* The parser context */ - SrcList *pSrcList, /* List of tables used to resolve column names */ - ExprList *pEList, /* List of expressions used to resolve "AS" */ - Expr *pExpr, /* The expression to be analyzed. */ - int allowAgg, /* True to allow aggregate expressions */ - int *pIsAgg /* Set to TRUE if aggregates are found */ -){ - if( pExpr==0 ) return 0; - if( sqlite3ExprResolveIds(pParse,pSrcList,pEList,pExpr) ){ - return 1; + if( pExpr->pSelect ){ + sqlite3VdbeAddOp(v, OP_AggContextPop, 0, 0); + } + if( label<0 ){ + sqlite3VdbeResolveLabel(v, label); } - return sqlite3ExprCheck(pParse, pExpr, allowAgg, pIsAgg); + return; } +#endif /* SQLITE_OMIT_SUBQUERY */ /* ** Generate an instruction that will put the integer describe by @@ -1190,12 +1373,16 @@ static void codeInteger(Vdbe *v, const char *z, int n){ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ Vdbe *v = pParse->pVdbe; int op; - if( v==0 || pExpr==0 ) return; + if( v==0 ) return; + if( pExpr==0 ){ + sqlite3VdbeAddOp(v, OP_String8, 0, 0); /* Empty expression evals to NULL */ + return; + } op = pExpr->op; switch( op ){ case TK_COLUMN: { - if( pParse->useAgg ){ - sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); + if( !pParse->fillAgg && pExpr->iAgg>=0 ){ + sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg); }else if( pExpr->iColumn>=0 ){ sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); #ifndef NDEBUG @@ -1220,12 +1407,14 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeDequoteP3(v, -1); break; } +#ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { assert( TK_BLOB==OP_HexBlob ); sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1); sqlite3VdbeDequoteP3(v, -1); break; } +#endif case TK_NULL: { sqlite3VdbeAddOp(v, OP_String8, 0, 0); break; @@ -1237,6 +1426,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } break; } + case TK_REGISTER: { + sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0); + break; + } case TK_LT: case TK_LE: case TK_GT: @@ -1323,6 +1516,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); break; } + case TK_CDATE: + case TK_CTIME: + case TK_CTIMESTAMP: case TK_GLOB: case TK_LIKE: case TK_FUNCTION: { @@ -1354,7 +1550,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF); break; } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: case TK_SELECT: { + sqlite3CodeSubselect(pParse, pExpr); sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); VdbeComment((v, "# load subquery result")); break; @@ -1362,6 +1561,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_IN: { int addr; char affinity; + sqlite3CodeSubselect(pParse, pExpr); /* Figure out the affinity to use to create a key from the results ** of the expression. affinityStr stores a static string suitable for @@ -1386,6 +1586,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ break; } +#endif case TK_BETWEEN: { Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->pList->a; @@ -1452,6 +1653,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeResolveLabel(v, expr_end_label); break; } +#ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { if( !pParse->trigStack ){ sqlite3ErrorMsg(pParse, @@ -1472,10 +1674,38 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ VdbeComment((v, "# raise(IGNORE)")); } } +#endif break; } } +#ifndef SQLITE_OMIT_TRIGGER +/* +** Generate code that evalutes the given expression and leaves the result +** on the stack. See also sqlite3ExprCode(). +** +** This routine might also cache the result and modify the pExpr tree +** so that it will make use of the cached result on subsequent evaluations +** rather than evaluate the whole expression again. Trivial expressions are +** not cached. If the expression is cached, its result is stored in a +** memory location. +*/ +void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ + Vdbe *v = pParse->pVdbe; + int iMem; + int addr1, addr2; + if( v==0 ) return; + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3ExprCode(pParse, pExpr); + addr2 = sqlite3VdbeCurrentAddr(v); + if( addr2>addr1+1 || sqlite3VdbeGetOp(v, addr1)->opcode==OP_Function ){ + iMem = pExpr->iTable = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0); + pExpr->op = TK_REGISTER; + } +} +#endif + /* ** Generate code that pushes the value of every element of the given ** expression list onto the stack. @@ -1737,6 +1967,8 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ /* ** Add a new element to the pParse->aAgg[] array and return its index. +** The new element is initialized to zero. The calling function is +** expected to fill it in. */ static int appendAggInfo(Parse *pParse){ if( (pParse->nAgg & 0x7)==0 ){ @@ -1752,80 +1984,91 @@ static int appendAggInfo(Parse *pParse){ } /* -** Analyze the given expression looking for aggregate functions and -** for variables that need to be added to the pParse->aAgg[] array. -** Make additional entries to the pParse->aAgg[] array as necessary. +** This is an xFunc for walkExprTree() used to implement +** sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates +** for additional information. ** -** This routine should only be called after the expression has been -** analyzed by sqlite3ExprResolveIds() and sqlite3ExprCheck(). -** -** If errors are seen, leave an error message in zErrMsg and return -** the number of errors. +** This routine analyzes the aggregate function at pExpr. */ -int sqlite3ExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){ +static int analyzeAggregate(void *pArg, Expr *pExpr){ int i; AggExpr *aAgg; - int nErr = 0; + NameContext *pNC = (NameContext *)pArg; + Parse *pParse = pNC->pParse; + SrcList *pSrcList = pNC->pSrcList; - if( pExpr==0 ) return 0; switch( pExpr->op ){ case TK_COLUMN: { - aAgg = pParse->aAgg; - for(i=0; inAgg; i++){ - if( aAgg[i].isAgg ) continue; - if( aAgg[i].pExpr->iTable==pExpr->iTable - && aAgg[i].pExpr->iColumn==pExpr->iColumn ){ - break; + for(i=0; pSrcList && inSrc; i++){ + if( pExpr->iTable==pSrcList->a[i].iCursor ){ + aAgg = pParse->aAgg; + for(i=0; inAgg; i++){ + if( aAgg[i].isAgg ) continue; + if( aAgg[i].pExpr->iTable==pExpr->iTable + && aAgg[i].pExpr->iColumn==pExpr->iColumn ){ + break; + } + } + if( i>=pParse->nAgg ){ + i = appendAggInfo(pParse); + if( i<0 ) return 1; + pParse->aAgg[i].isAgg = 0; + pParse->aAgg[i].pExpr = pExpr; + } + pExpr->iAgg = i; + pExpr->iAggCtx = pNC->nDepth; + return 1; } } - if( i>=pParse->nAgg ){ - i = appendAggInfo(pParse); - if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 0; - pParse->aAgg[i].pExpr = pExpr; - } - pExpr->iAgg = i; - break; + return 1; } case TK_AGG_FUNCTION: { - aAgg = pParse->aAgg; - for(i=0; inAgg; i++){ - if( !aAgg[i].isAgg ) continue; - if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){ - break; + if( pNC->nDepth==0 ){ + aAgg = pParse->aAgg; + for(i=0; inAgg; i++){ + if( !aAgg[i].isAgg ) continue; + if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){ + break; + } } - } - if( i>=pParse->nAgg ){ - u8 enc = pParse->db->enc; - i = appendAggInfo(pParse); - if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 1; - pParse->aAgg[i].pExpr = pExpr; - pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db, - pExpr->token.z, pExpr->token.n, - pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); - } - pExpr->iAgg = i; - break; - } - default: { - if( pExpr->pLeft ){ - nErr = sqlite3ExprAnalyzeAggregates(pParse, pExpr->pLeft); - } - if( nErr==0 && pExpr->pRight ){ - nErr = sqlite3ExprAnalyzeAggregates(pParse, pExpr->pRight); - } - if( nErr==0 && pExpr->pList ){ - int n = pExpr->pList->nExpr; - int i; - for(i=0; nErr==0 && ipList->a[i].pExpr); + if( i>=pParse->nAgg ){ + u8 enc = pParse->db->enc; + i = appendAggInfo(pParse); + if( i<0 ) return 1; + pParse->aAgg[i].isAgg = 1; + pParse->aAgg[i].pExpr = pExpr; + pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db, + pExpr->token.z, pExpr->token.n, + pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); } + pExpr->iAgg = i; + return 1; } - break; } } - return nErr; + if( pExpr->pSelect ){ + pNC->nDepth++; + walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC); + pNC->nDepth--; + } + return 0; +} + +/* +** Analyze the given expression looking for aggregate functions and +** for variables that need to be added to the pParse->aAgg[] array. +** Make additional entries to the pParse->aAgg[] array as necessary. +** +** This routine should only be called after the expression has been +** analyzed by sqlite3ExprResolveNames(). +** +** If errors are seen, leave an error message in zErrMsg and return +** the number of errors. +*/ +int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ + int nErr = pNC->pParse->nErr; + walkExprTree(pExpr, analyzeAggregate, pNC); + return pNC->pParse->nErr - nErr; } /* @@ -1917,7 +2160,10 @@ FuncDef *sqlite3FindFunction( pBest->iPrefEnc = enc; memcpy(pBest->zName, zName, nName); pBest->zName[nName] = 0; - sqlite3HashInsert(&db->aFunc, pBest->zName, nName, (void*)pBest); + if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){ + sqliteFree(pBest); + return 0; + } } if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ diff --git a/ext/pdo_sqlite/sqlite/src/func.c b/ext/pdo_sqlite/sqlite/src/func.c index f61bdae3fd..49ceed39ea 100644 --- a/ext/pdo_sqlite/sqlite/src/func.c +++ b/ext/pdo_sqlite/sqlite/src/func.c @@ -18,11 +18,11 @@ ** ** $Id$ */ +#include "sqliteInt.h" #include #include #include #include -#include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" @@ -347,10 +347,11 @@ static const struct compareInfo likeInfo = { '%', '_', 0, 1 }; ** ** abc[*]xyz Matches "abc*xyz" only */ -int patternCompare( +static int patternCompare( const u8 *zPattern, /* The glob pattern */ const u8 *zString, /* The string to compare against the glob */ - const struct compareInfo *pInfo /* Information about how to do the compare */ + const struct compareInfo *pInfo, /* Information about how to do the compare */ + const int esc /* The escape character */ ){ register int c; int invert; @@ -360,9 +361,10 @@ int patternCompare( u8 matchAll = pInfo->matchAll; u8 matchSet = pInfo->matchSet; u8 noCase = pInfo->noCase; + int prevEscape = 0; /* True if the previous character was 'escape' */ while( (c = *zPattern)!=0 ){ - if( c==matchAll ){ + if( !prevEscape && c==matchAll ){ while( (c=zPattern[1]) == matchAll || c == matchOne ){ if( c==matchOne ){ if( *zString==0 ) return 0; @@ -370,9 +372,15 @@ int patternCompare( } zPattern++; } + if( c && esc && sqlite3ReadUtf8(&zPattern[1])==esc ){ + u8 const *zTemp = &zPattern[1]; + sqliteNextChar(zTemp); + c = *zTemp; + } if( c==0 ) return 1; if( c==matchSet ){ - while( *zString && patternCompare(&zPattern[1],zString,pInfo)==0 ){ + assert( esc==0 ); /* This is GLOB, not LIKE */ + while( *zString && patternCompare(&zPattern[1],zString,pInfo,esc)==0 ){ sqliteNextChar(zString); } return *zString!=0; @@ -386,17 +394,18 @@ int patternCompare( while( c2 != 0 && c2 != c ){ c2 = *++zString; } } if( c2==0 ) return 0; - if( patternCompare(&zPattern[1],zString,pInfo) ) return 1; + if( patternCompare(&zPattern[1],zString,pInfo,esc) ) return 1; sqliteNextChar(zString); } return 0; } - }else if( c==matchOne ){ + }else if( !prevEscape && c==matchOne ){ if( *zString==0 ) return 0; sqliteNextChar(zString); zPattern++; }else if( c==matchSet ){ int prior_c = 0; + assert( esc==0 ); /* This only occurs for GLOB, not LIKE */ seen = 0; invert = 0; c = sqliteCharVal(zString); @@ -424,6 +433,9 @@ int patternCompare( if( c2==0 || (seen ^ invert)==0 ) return 0; sqliteNextChar(zString); zPattern++; + }else if( esc && !prevEscape && sqlite3ReadUtf8(zPattern)==esc){ + prevEscape = 1; + sqliteNextChar(zPattern); }else{ if( noCase ){ if( sqlite3UpperToLower[c] != sqlite3UpperToLower[*zString] ) return 0; @@ -432,6 +444,7 @@ int patternCompare( } zPattern++; zString++; + prevEscape = 0; } } return *zString==0; @@ -457,8 +470,21 @@ static void likeFunc( ){ const unsigned char *zA = sqlite3_value_text(argv[0]); const unsigned char *zB = sqlite3_value_text(argv[1]); + int escape = 0; + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + const unsigned char *zEsc = sqlite3_value_text(argv[2]); + if( sqlite3utf8CharLen(zEsc, -1)!=1 ){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + escape = sqlite3ReadUtf8(zEsc); + } if( zA && zB ){ - sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo)); + sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo, escape)); } } @@ -469,13 +495,13 @@ static void likeFunc( ** ** A GLOB B ** -** is implemented as glob(A,B). +** is implemented as glob(B,A). */ static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){ const unsigned char *zA = sqlite3_value_text(argv[0]); const unsigned char *zB = sqlite3_value_text(argv[1]); if( zA && zB ){ - sqlite3_result_int(context, patternCompare(zA, zB, &globInfo)); + sqlite3_result_int(context, patternCompare(zA, zB, &globInfo, 0)); } } @@ -507,6 +533,7 @@ static void versionFunc( sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC); } + /* ** EXPERIMENTAL - This is not an official function. The interface may ** change. This function may disappear. Do not write code that depends @@ -704,10 +731,12 @@ static void test_destructor( memcpy(zVal, sqlite3ValueText(argv[0], db->enc), len); if( db->enc==SQLITE_UTF8 ){ sqlite3_result_text(pCtx, zVal, -1, destructor); +#ifndef SQLITE_OMIT_UTF16 }else if( db->enc==SQLITE_UTF16LE ){ sqlite3_result_text16le(pCtx, zVal, -1, destructor); }else{ sqlite3_result_text16be(pCtx, zVal, -1, destructor); +#endif /* SQLITE_OMIT_UTF16 */ } } static void test_destructor_count( @@ -762,6 +791,20 @@ static void test_auxdata( } #endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST +/* +** A function to test error reporting from user functions. This function +** returns a copy of it's first argument as an error. +*/ +static void test_error( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **argv +){ + sqlite3_result_error(pCtx, sqlite3_value_text(argv[0]), 0); +} +#endif /* SQLITE_TEST */ + /* ** An instance of the following structure holds the context of a ** sum() or avg() aggregate computation. @@ -808,33 +851,6 @@ struct StdDevCtx { int cnt; /* Number of terms counted */ }; -#if 0 /* Omit because math library is required */ -/* -** Routines used to compute the standard deviation as an aggregate. -*/ -static void stdDevStep(sqlite3_context *context, int argc, const char **argv){ - StdDevCtx *p; - double x; - if( argc<1 ) return; - p = sqlite3_aggregate_context(context, sizeof(*p)); - if( p && argv[0] ){ - x = sqlite3AtoF(argv[0], 0); - p->sum += x; - p->sum2 += x*x; - p->cnt++; - } -} -static void stdDevFinalize(sqlite3_context *context){ - double rN = sqlite3_aggregate_count(context); - StdDevCtx *p = sqlite3_aggregate_context(context, sizeof(*p)); - if( p && p->cnt>1 ){ - double rCnt = cnt; - sqlite3_set_result_double(context, - sqrt((p->sum2 - p->sum*p->sum/rCnt)/(rCnt-1.0))); - } -} -#endif - /* ** The following structure keeps track of state information for the ** count() aggregate function. @@ -933,7 +949,9 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc }, { "length", 1, 0, SQLITE_UTF8, 0, lengthFunc }, { "substr", 3, 0, SQLITE_UTF8, 0, substrFunc }, +#ifndef SQLITE_OMIT_UTF16 { "substr", 3, 0, SQLITE_UTF16LE, 0, sqlite3utf16Substr }, +#endif { "abs", 1, 0, SQLITE_UTF8, 0, absFunc }, { "round", 1, 0, SQLITE_UTF8, 0, roundFunc }, { "round", 2, 0, SQLITE_UTF8, 0, roundFunc }, @@ -945,6 +963,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc }, { "random", -1, 0, SQLITE_UTF8, 0, randomFunc }, { "like", 2, 0, SQLITE_UTF8, 0, likeFunc }, + { "like", 3, 0, SQLITE_UTF8, 0, likeFunc }, { "glob", 2, 0, SQLITE_UTF8, 0, globFunc }, { "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc }, { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc}, @@ -960,6 +979,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "test_destructor", 1, 1, SQLITE_UTF8, 0, test_destructor}, { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count}, { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata}, + { "test_error", 1, 0, SQLITE_UTF8, 0, test_error}, #endif }; static const struct { @@ -976,9 +996,6 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "avg", 1, 0, 0, sumStep, avgFinalize }, { "count", 0, 0, 0, countStep, countFinalize }, { "count", 1, 0, 0, countStep, countFinalize }, -#if 0 - { "stddev", 1, 0, stdDevStep, stdDevFinalize }, -#endif }; int i; @@ -998,6 +1015,9 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ } } } +#ifndef SQLITE_OMIT_ALTERTABLE + sqlite3AlterFunctions(db); +#endif for(i=0; i 0 ){ + h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; + nKey--; + } + return h & 0x7fffffff; } static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){ if( n1!=n2 ) return 1; diff --git a/ext/pdo_sqlite/sqlite/src/insert.c b/ext/pdo_sqlite/sqlite/src/insert.c index 65cbdc8ff1..c9485fe247 100644 --- a/ext/pdo_sqlite/sqlite/src/insert.c +++ b/ext/pdo_sqlite/sqlite/src/insert.c @@ -94,6 +94,27 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0); } +/* +** Return non-zero if SELECT statement p opens the table with rootpage +** iTab in database iDb. This is used to see if a statement of the form +** "INSERT INTO SELECT ..." can run without using temporary +** table for the results of the SELECT. +** +** No checking is done for sub-selects that are part of expressions. +*/ +static int selectReadsTable(Select *p, int iDb, int iTab){ + int i; + struct SrcList_item *pItem; + if( p->pSrc==0 ) return 0; + for(i=0, pItem=p->pSrc->a; ipSrc->nSrc; i++, pItem++){ + if( pItem->pSelect ){ + if( selectReadsTable(p, iDb, iTab) ) return 1; + }else{ + if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1; + } + } + return 0; +} /* ** This routine is call to handle SQL of the following forms: @@ -182,18 +203,24 @@ void sqlite3Insert( sqlite3 *db; /* The main database structure */ int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ int endOfLoop; /* Label for the end of the insertion loop */ - int useTempTable; /* Store SELECT results in intermediate table */ + int useTempTable = 0; /* Store SELECT results in intermediate table */ int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ int iSelectLoop = 0; /* Address of code that implements the SELECT */ int iCleanup = 0; /* Address of the cleanup code */ int iInsertBlock = 0; /* Address of the subroutine used to insert data */ int iCntMem = 0; /* Memory cell used for the row counter */ - int isView; /* True if attempting to insert into a view */ + int newIdx = -1; /* Cursor for the NEW table */ + Db *pDb; /* The database containing table being inserted into */ + int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */ - int row_triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ - int before_triggers; /* True if there are BEFORE triggers */ - int after_triggers; /* True if there are AFTER triggers */ - int newIdx = -1; /* Cursor for the NEW table */ +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to insert into a view */ + int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ +#endif + +#ifndef SQLITE_OMIT_AUTOINCREMENT + int counterRowid; /* Memory cell holding rowid of autoinc counter */ +#endif if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup; db = pParse->db; @@ -208,22 +235,32 @@ void sqlite3Insert( goto insert_cleanup; } assert( pTab->iDbnDb ); - zDb = db->aDb[pTab->iDb].zName; + pDb = &db->aDb[pTab->iDb]; + zDb = pDb->zName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ goto insert_cleanup; } + /* Figure out if we have any triggers and if the table being + ** inserted into is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0); + isView = pTab->pSelect!=0; +#else +# define triggers_exist 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + /* Ensure that: * (a) the table is not read-only, * (b) that if it is a view then ON INSERT triggers exist */ - before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT, - TK_BEFORE, TK_ROW, 0); - after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT, - TK_AFTER, TK_ROW, 0); - row_triggers_exist = before_triggers || after_triggers; - isView = pTab->pSelect!=0; - if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){ + if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ goto insert_cleanup; } if( pTab==0 ) goto insert_cleanup; @@ -245,14 +282,42 @@ void sqlite3Insert( */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; - sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb); + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, pTab->iDb); /* if there are row triggers, allocate a temp table for new.* references. */ - if( row_triggers_exist ){ + if( triggers_exist ){ newIdx = pParse->nTab++; } +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If this is an AUTOINCREMENT table, look up the sequence number in the + ** sqlite_sequence table and store it in memory cell counterMem. Also + ** remember the rowid of the sqlite_sequence table entry in memory cell + ** counterRowid. + */ + if( pTab->autoInc ){ + int iCur = pParse->nTab; + int base = sqlite3VdbeCurrentAddr(v); + counterRowid = pParse->nMem++; + counterMem = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2); + sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13); + sqlite3VdbeAddOp(v, OP_Column, iCur, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); + sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12); + sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1); + sqlite3VdbeAddOp(v, OP_Column, iCur, 1); + sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1); + sqlite3VdbeAddOp(v, OP_Goto, 0, base+13); + sqlite3VdbeAddOp(v, OP_Next, iCur, base+4); + sqlite3VdbeAddOp(v, OP_Close, iCur, 0); + } +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + /* Figure out how many columns of data are supplied. If the data ** is coming from a SELECT statement, then this step also generates ** all the code to implement the SELECT statement and invoke a subroutine @@ -268,8 +333,11 @@ void sqlite3Insert( iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); iSelectLoop = sqlite3VdbeCurrentAddr(v); iInsertBlock = sqlite3VdbeMakeLabel(v); - rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock, 0,0,0,0); + + /* Resolve the expressions in the SELECT statement and execute it. */ + rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0); if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup; + iCleanup = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup); assert( pSelect->pEList ); @@ -283,20 +351,8 @@ void sqlite3Insert( ** of the tables being read by the SELECT statement. Also use a ** temp table in the case of row triggers. */ - if( row_triggers_exist ){ + if( triggers_exist || selectReadsTable(pSelect, pTab->iDb, pTab->tnum) ){ useTempTable = 1; - }else{ - int addr = 0; - useTempTable = 0; - while( useTempTable==0 ){ - VdbeOp *pOp; - addr = sqlite3VdbeFindOp(v, addr, OP_OpenRead, pTab->tnum); - if( addr==0 ) break; - pOp = sqlite3VdbeGetOp(v, addr-2); - if( pOp->opcode==OP_Integer && pOp->p1==pTab->iDb ){ - useTempTable = 1; - } - } } if( useTempTable ){ @@ -328,15 +384,16 @@ void sqlite3Insert( /* This is the case if the data for the INSERT is coming from a VALUES ** clause */ - SrcList dummy; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; assert( pList!=0 ); srcTab = -1; useTempTable = 0; assert( pList ); nColumn = pList->nExpr; - dummy.nSrc = 0; for(i=0; ia[i].pExpr,0,0) ){ + if( sqlite3ExprResolveNames(&sNC, pList->a[i].pExpr) ){ goto insert_cleanup; } } @@ -404,7 +461,7 @@ void sqlite3Insert( /* Open the temp table for FOR EACH ROW triggers */ - if( row_triggers_exist ){ + if( triggers_exist ){ sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol); } @@ -418,7 +475,7 @@ void sqlite3Insert( } /* Open tables and indices if there are no row triggers */ - if( !row_triggers_exist ){ + if( !triggers_exist ){ base = pParse->nTab; sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); } @@ -440,7 +497,7 @@ void sqlite3Insert( /* Run the BEFORE and INSTEAD OF triggers, if there are any */ endOfLoop = sqlite3VdbeMakeLabel(v); - if( before_triggers ){ + if( triggers_exist & TRIGGER_BEFORE ){ /* build the NEW.* reference row. Note that if there is an INTEGER ** PRIMARY KEY into which a NULL is being inserted, that NULL will be @@ -452,9 +509,8 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_Integer, -1, 0); }else if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1); }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); @@ -473,13 +529,12 @@ void sqlite3Insert( } } if( pColumn && j>=pColumn->nId ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); }else if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, j); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Dup, nColumn-j-1, 1); }else{ - sqlite3ExprCode(pParse, pList->a[j].pExpr); + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr); } } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); @@ -495,7 +550,7 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); /* Fire BEFORE or INSTEAD OF triggers */ - if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab, + if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, newIdx, -1, onError, endOfLoop) ){ goto insert_cleanup; } @@ -504,7 +559,7 @@ void sqlite3Insert( /* If any triggers exists, the opening of tables and indices is deferred ** until now. */ - if( row_triggers_exist && !isView ){ + if( triggers_exist && !isView ){ base = pParse->nTab; sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); } @@ -528,11 +583,16 @@ void sqlite3Insert( */ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_NewRecno, base, 0); + sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); }else{ - sqlite3VdbeAddOp(v, OP_NewRecno, base, 0); + sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); + } +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( pTab->autoInc ){ + sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0); } +#endif /* SQLITE_OMIT_AUTOINCREMENT */ /* Push onto the stack, data for all columns of the new entry, beginning ** with the first column. @@ -554,7 +614,7 @@ void sqlite3Insert( } } if( pColumn && j>=pColumn->nId ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); }else if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, j); }else if( pSelect ){ @@ -570,7 +630,7 @@ void sqlite3Insert( sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0, 0, onError, endOfLoop); sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0, - after_triggers ? newIdx : -1); + (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1); } /* Update the count of rows that are inserted @@ -579,7 +639,7 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0); } - if( row_triggers_exist ){ + if( triggers_exist ){ /* Close all tables opened */ if( !isView ){ sqlite3VdbeAddOp(v, OP_Close, base, 0); @@ -589,8 +649,8 @@ void sqlite3Insert( } /* Code AFTER triggers */ - if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1, - onError, endOfLoop) ){ + if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab, + newIdx, -1, onError, endOfLoop) ){ goto insert_cleanup; } } @@ -608,7 +668,7 @@ void sqlite3Insert( sqlite3VdbeResolveLabel(v, iCleanup); } - if( !row_triggers_exist ){ + if( !triggers_exist ){ /* Close all tables opened */ sqlite3VdbeAddOp(v, OP_Close, base, 0); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ @@ -616,10 +676,35 @@ void sqlite3Insert( } } +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Update the sqlite_sequence table by storing the content of the + ** counter value in memory counterMem back into the sqlite_sequence + ** table. + */ + if( pTab->autoInc ){ + int iCur = pParse->nTab; + int base = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2); + sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0); + sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7); + sqlite3VdbeAddOp(v, OP_Pop, 1, 0); + sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); + sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0); + sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0); + sqlite3VdbeAddOp(v, OP_Close, iCur, 0); + } +#endif + /* - ** Return the number of rows inserted. + ** Return the number of rows inserted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. */ - if( db->flags & SQLITE_CountRows ){ + if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); @@ -753,11 +838,13 @@ void sqlite3GenerateConstraintChecks( }else if( onError==OE_Default ){ onError = OE_Abort; } - if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){ + if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ onError = OE_Abort; } sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1); addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0); + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Rollback: case OE_Abort: @@ -775,11 +862,10 @@ void sqlite3GenerateConstraintChecks( break; } case OE_Replace: { - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0); break; } - default: assert(0); } sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v)); } @@ -885,6 +971,8 @@ void sqlite3GenerateConstraintChecks( jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0); /* Generate code that executes if the new index entry is not unique */ + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Rollback: case OE_Abort: @@ -929,7 +1017,6 @@ void sqlite3GenerateConstraintChecks( seenReplace = 1; break; } - default: assert(0); } contAddr = sqlite3VdbeCurrentAddr(v); assert( contAddr<(1<<24) ); @@ -975,12 +1062,18 @@ void sqlite3CompleteInsertion( } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); sqlite3TableAffinityStr(v, pTab); +#ifndef SQLITE_OMIT_TRIGGER if( newIdx>=0 ){ sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); } - pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID)); +#endif + if( pParse->nested ){ + pik_flags = 0; + }else{ + pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID)); + } sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags); if( isUpdate && recnoChng ){ diff --git a/ext/pdo_sqlite/sqlite/src/main.c b/ext/pdo_sqlite/sqlite/src/main.c index 0ae7e1b263..1d6dec3a3c 100644 --- a/ext/pdo_sqlite/sqlite/src/main.c +++ b/ext/pdo_sqlite/sqlite/src/main.c @@ -202,7 +202,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** meta[2] Size of the page cache. ** meta[3] Use freelist if 0. Autovacuum if greater than zero. ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE - ** meta[5] + ** meta[5] The user cookie. Used by the application. ** meta[6] ** meta[7] ** meta[8] @@ -257,12 +257,23 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ /* This happens if the database was initially empty */ db->file_format = 1; } + + if( db->file_format==2 ){ + /* File format 2 is treated exactly as file format 1. New + ** databases are created with file format 1. + */ + db->file_format = 1; + } } /* - ** file_format==1 Version 3.0.0. + ** file_format==1 Version 3.0.0. + ** file_format==2 Version 3.1.3. + ** + ** Version 3.0 can only use files with file_format==1. Version 3.1.3 + ** can read and write files with file_format==1 or file_format==2. */ - if( meta[1]>1 ){ + if( meta[1]>2 ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; @@ -279,7 +290,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ }else{ char *zSql; zSql = sqlite3MPrintf( - "SELECT name, rootpage, sql, %s FROM '%q'.%s", + "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", zDbNum, db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); @@ -373,12 +384,13 @@ int sqlite3ReadSchema(Parse *pParse){ const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $"; const char sqlite3_version[] = SQLITE_VERSION; const char *sqlite3_libversion(void){ return sqlite3_version; } +int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } /* ** This is the default collating function named "BINARY" which is always ** available. */ -static int binaryCollatingFunc( +static int binCollFunc( void *NotUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2 @@ -553,7 +565,7 @@ const char *sqlite3ErrStr(int rc){ case SQLITE_NOLFS: z = "kernel lacks large file support"; break; case SQLITE_AUTH: z = "authorization denied"; break; case SQLITE_FORMAT: z = "auxiliary database format error"; break; - case SQLITE_RANGE: z = "bind index out of range"; break; + case SQLITE_RANGE: z = "bind or column index out of range"; break; case SQLITE_NOTADB: z = "file is encrypted or is not a database";break; default: z = "unknown error"; break; } @@ -706,6 +718,7 @@ int sqlite3_create_function( return SQLITE_ERROR; } +#ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. @@ -725,6 +738,25 @@ int sqlite3_create_function( if( rc!=SQLITE_OK ) return rc; enc = SQLITE_UTF16BE; } +#else + enc = SQLITE_UTF8; +#endif + + /* Check if an existing function is being overridden or deleted. If so, + ** and there are active VMs, then return SQLITE_BUSY. If a function + ** is being overridden/deleted but there are no active VMs, allow the + ** operation to continue but invalidate all precompiled statements. + */ + p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0); + if( p && p->iPrefEnc==enc && p->nArg==nArg ){ + if( db->activeVdbeCnt ){ + sqlite3Error(db, SQLITE_BUSY, + "Unable to delete/modify user-function due to active statements"); + return SQLITE_BUSY; + }else{ + sqlite3ExpirePreparedStatements(db); + } + } p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); if( p==0 ) return SQLITE_NOMEM; @@ -734,6 +766,7 @@ int sqlite3_create_function( p->pUserData = pUserData; return SQLITE_OK; } +#ifndef SQLITE_OMIT_UTF16 int sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, @@ -762,6 +795,7 @@ int sqlite3_create_function16( pUserData, xFunc, xStep, xFinal); return rc; } +#endif /* ** Register a trace function. The pArg from the previously registered trace @@ -835,13 +869,14 @@ int sqlite3BtreeFactory( if( omitJournal ){ btree_flags |= BTREE_OMIT_JOURNAL; } + if( db->flags & SQLITE_NoReadlock ){ + btree_flags |= BTREE_NO_READLOCK; + } if( zFilename==0 ){ -#ifndef TEMP_STORE -# define TEMP_STORE 1 -#endif #if TEMP_STORE==0 /* Do nothing */ #endif +#ifndef SQLITE_OMIT_MEMORYDB #if TEMP_STORE==1 if( db->temp_store==2 ) zFilename = ":memory:"; #endif @@ -851,6 +886,7 @@ int sqlite3BtreeFactory( #if TEMP_STORE==3 zFilename = ":memory:"; #endif +#endif /* SQLITE_OMIT_MEMORYDB */ } rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags); @@ -880,6 +916,7 @@ const char *sqlite3_errmsg(sqlite3 *db){ return z; } +#ifndef SQLITE_OMIT_UTF16 /* ** Return UTF-16 encoded English language explanation of the most recent ** error. @@ -919,6 +956,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){ } return z; } +#endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. @@ -1005,6 +1043,7 @@ int sqlite3_prepare( if( pzTail ) *pzTail = sParse.zTail; rc = sParse.rc; +#ifndef SQLITE_OMIT_EXPLAIN if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 5); sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); @@ -1013,6 +1052,7 @@ int sqlite3_prepare( sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC); } +#endif prepare_out: if( sqlite3SafetyOff(db) ){ @@ -1033,6 +1073,7 @@ prepare_out: return rc; } +#ifndef SQLITE_OMIT_UTF16 /* ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ @@ -1076,6 +1117,7 @@ int sqlite3_prepare16( return rc; } +#endif /* SQLITE_OMIT_UTF16 */ /* ** This routine does the work of opening a database on behalf of @@ -1091,7 +1133,6 @@ static int openDatabase( ){ sqlite3 *db; int rc, i; - char *zErrMsg = 0; /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite3) ); @@ -1102,7 +1143,7 @@ static int openDatabase( db->aDb = db->aDbStatic; db->enc = SQLITE_UTF8; db->autoCommit = 1; - /* db->flags |= SQLITE_ShortColNames; */ + db->flags |= SQLITE_ShortColNames; sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0); for(i=0; inDb; i++){ @@ -1116,11 +1157,9 @@ static int openDatabase( ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ - sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binaryCollatingFunc); - sqlite3_create_collation(db, "BINARY", SQLITE_UTF16LE, 0,binaryCollatingFunc); - sqlite3_create_collation(db, "BINARY", SQLITE_UTF16BE, 0,binaryCollatingFunc); - db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0); - if( !db->pDfltColl ){ + if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) || + sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) || + !(db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0)) ){ rc = db->errCode; assert( rc!=SQLITE_OK ); db->magic = SQLITE_MAGIC_CLOSED; @@ -1150,14 +1189,8 @@ static int openDatabase( ** is accessed. */ sqlite3RegisterBuiltinFunctions(db); - if( rc==SQLITE_OK ){ - sqlite3Error(db, SQLITE_OK, 0); - db->magic = SQLITE_MAGIC_OPEN; - }else{ - sqlite3Error(db, rc, "%s", zErrMsg, 0); - if( zErrMsg ) sqliteFree(zErrMsg); - db->magic = SQLITE_MAGIC_CLOSED; - } + sqlite3Error(db, SQLITE_OK, 0); + db->magic = SQLITE_MAGIC_OPEN; opendb_out: if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){ @@ -1177,6 +1210,7 @@ int sqlite3_open( return openDatabase(zFilename, ppDb); } +#ifndef SQLITE_OMIT_UTF16 /* ** Open a new database handle. */ @@ -1205,6 +1239,7 @@ int sqlite3_open16( return rc; } +#endif /* SQLITE_OMIT_UTF16 */ /* ** The following routine destroys a virtual machine that is created by @@ -1239,7 +1274,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){ rc = SQLITE_OK; }else{ rc = sqlite3VdbeReset((Vdbe*)pStmt); - sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0); + sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0, 0); } return rc; } @@ -1276,6 +1311,21 @@ int sqlite3_create_collation( ); return SQLITE_ERROR; } + + /* Check if this call is removing or replacing an existing collation + ** sequence. If so, and there are active VMs, return busy. If there + ** are no active VMs, invalidate any pre-compiled statements. + */ + pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0); + if( pColl && pColl->xCmp ){ + if( db->activeVdbeCnt ){ + sqlite3Error(db, SQLITE_BUSY, + "Unable to delete/modify collation sequence due to active statements"); + return SQLITE_BUSY; + } + sqlite3ExpirePreparedStatements(db); + } + pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1); if( 0==pColl ){ rc = SQLITE_NOMEM; @@ -1288,6 +1338,7 @@ int sqlite3_create_collation( return rc; } +#ifndef SQLITE_OMIT_UTF16 /* ** Register a new collation sequence with the database handle db. */ @@ -1308,6 +1359,7 @@ int sqlite3_create_collation16( zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8); return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare); } +#endif /* SQLITE_OMIT_UTF16 */ /* ** Register a collation sequence factory callback with the database handle @@ -1327,6 +1379,7 @@ int sqlite3_collation_needed( return SQLITE_OK; } +#ifndef SQLITE_OMIT_UTF16 /* ** Register a collation sequence factory callback with the database handle ** db. Replace any previously installed collation sequence factory. @@ -1344,3 +1397,4 @@ int sqlite3_collation_needed16( db->pCollNeededArg = pCollNeededArg; return SQLITE_OK; } +#endif /* SQLITE_OMIT_UTF16 */ diff --git a/ext/pdo_sqlite/sqlite/src/opcodes.c b/ext/pdo_sqlite/sqlite/src/opcodes.c index b6f012198d..734d1a5409 100644 --- a/ext/pdo_sqlite/sqlite/src/opcodes.c +++ b/ext/pdo_sqlite/sqlite/src/opcodes.c @@ -1,128 +1,137 @@ /* Automatically generated. Do not edit */ -/* See the mkopcodec.h script for details. */ +/* See the mkopcodec.awk script for details. */ +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) const char *const sqlite3OpcodeNames[] = { "?", - "ContextPop", - "IntegrityCk", - "DropTrigger", - "DropIndex", - "Recno", - "KeyAsData", - "Delete", - "MoveGt", - "VerifyCookie", - "Push", - "Dup", - "Blob", - "IdxGT", - "IdxRecno", - "RowKey", - "PutStrKey", - "IsUnique", - "SetNumColumns", - "IdxIsNull", - "NullRow", - "OpenPseudo", - "OpenWrite", - "OpenRead", - "Transaction", - "AutoCommit", - "Pop", - "Halt", - "Vacuum", - "ListRead", - "RowData", - "NotExists", - "MoveLe", - "SetCookie", - "Variable", - "AggNext", - "AggReset", - "Sort", - "IdxDelete", - "ResetCount", - "OpenTemp", - "IdxColumn", - "Integer", - "AggSet", - "CreateIndex", - "IdxPut", - "MoveLt", - "Return", - "MemLoad", - "SortNext", - "IdxLT", - "Rewind", - "AddImm", - "AggFunc", - "AggInit", - "MemIncr", - "ListReset", - "Clear", - "Or", - "And", - "Not", - "PutIntKey", - "If", - "Callback", - "IsNull", - "NotNull", - "Ne", - "Eq", - "Gt", - "Le", - "Lt", - "Ge", - "BitAnd", - "BitOr", - "ShiftLeft", - "ShiftRight", - "Add", - "Subtract", - "Multiply", - "Divide", - "Remainder", - "Concat", - "Negative", - "SortReset", - "BitNot", - "String8", - "SortPut", - "Last", - "NotFound", - "MakeRecord", - "String", - "Goto", - "AggFocus", - "DropTable", - "Column", - "Noop", - "AggGet", - "CreateTable", - "NewRecno", - "Found", - "Distinct", - "Close", - "Statement", - "IfNot", - "Pull", - "MemStore", - "Next", - "Prev", - "MoveGe", - "MustBeInt", - "ForceInt", - "CollSeq", - "Gosub", - "ContextPush", - "ListRewind", - "ListWrite", - "ParseSchema", - "Destroy", - "IdxGE", - "FullKey", - "ReadCookie", - "AbsValue", - "Real", - "HexBlob", - "Function", + /* 1 */ "MemLoad", + /* 2 */ "Column", + /* 3 */ "SetCookie", + /* 4 */ "IfMemPos", + /* 5 */ "MoveGt", + /* 6 */ "AggFocus", + /* 7 */ "RowKey", + /* 8 */ "IdxRecno", + /* 9 */ "AggNext", + /* 10 */ "OpenWrite", + /* 11 */ "If", + /* 12 */ "PutStrKey", + /* 13 */ "Pop", + /* 14 */ "SortPut", + /* 15 */ "AggContextPush", + /* 16 */ "CollSeq", + /* 17 */ "OpenRead", + /* 18 */ "Expire", + /* 19 */ "SortReset", + /* 20 */ "AutoCommit", + /* 21 */ "Sort", + /* 22 */ "ListRewind", + /* 23 */ "IntegrityCk", + /* 24 */ "Function", + /* 25 */ "Noop", + /* 26 */ "Return", + /* 27 */ "Variable", + /* 28 */ "String", + /* 29 */ "ParseSchema", + /* 30 */ "PutIntKey", + /* 31 */ "AggFunc", + /* 32 */ "Close", + /* 33 */ "ListWrite", + /* 34 */ "CreateIndex", + /* 35 */ "IsUnique", + /* 36 */ "IdxIsNull", + /* 37 */ "NotFound", + /* 38 */ "MustBeInt", + /* 39 */ "Halt", + /* 40 */ "IdxLT", + /* 41 */ "AddImm", + /* 42 */ "Statement", + /* 43 */ "RowData", + /* 44 */ "MemMax", + /* 45 */ "Push", + /* 46 */ "KeyAsData", + /* 47 */ "NotExists", + /* 48 */ "OpenTemp", + /* 49 */ "MemIncr", + /* 50 */ "Gosub", + /* 51 */ "AggSet", + /* 52 */ "Integer", + /* 53 */ "SortNext", + /* 54 */ "Prev", + /* 55 */ "CreateTable", + /* 56 */ "Last", + /* 57 */ "ResetCount", + /* 58 */ "Callback", + /* 59 */ "ContextPush", + /* 60 */ "DropTrigger", + /* 61 */ "DropIndex", + /* 62 */ "FullKey", + /* 63 */ "IdxGE", + /* 64 */ "Or", + /* 65 */ "And", + /* 66 */ "Not", + /* 67 */ "IdxDelete", + /* 68 */ "Vacuum", + /* 69 */ "MoveLe", + /* 70 */ "IsNull", + /* 71 */ "NotNull", + /* 72 */ "Ne", + /* 73 */ "Eq", + /* 74 */ "Gt", + /* 75 */ "Le", + /* 76 */ "Lt", + /* 77 */ "Ge", + /* 78 */ "IfNot", + /* 79 */ "BitAnd", + /* 80 */ "BitOr", + /* 81 */ "ShiftLeft", + /* 82 */ "ShiftRight", + /* 83 */ "Add", + /* 84 */ "Subtract", + /* 85 */ "Multiply", + /* 86 */ "Divide", + /* 87 */ "Remainder", + /* 88 */ "Concat", + /* 89 */ "Negative", + /* 90 */ "DropTable", + /* 91 */ "BitNot", + /* 92 */ "String8", + /* 93 */ "MakeRecord", + /* 94 */ "Delete", + /* 95 */ "AggContextPop", + /* 96 */ "ListRead", + /* 97 */ "ListReset", + /* 98 */ "Dup", + /* 99 */ "Goto", + /* 100 */ "Clear", + /* 101 */ "IdxGT", + /* 102 */ "MoveLt", + /* 103 */ "VerifyCookie", + /* 104 */ "Pull", + /* 105 */ "SetNumColumns", + /* 106 */ "AbsValue", + /* 107 */ "Transaction", + /* 108 */ "AggGet", + /* 109 */ "ContextPop", + /* 110 */ "Next", + /* 111 */ "AggInit", + /* 112 */ "Distinct", + /* 113 */ "NewRecno", + /* 114 */ "AggReset", + /* 115 */ "Destroy", + /* 116 */ "ReadCookie", + /* 117 */ "ForceInt", + /* 118 */ "Recno", + /* 119 */ "OpenPseudo", + /* 120 */ "Blob", + /* 121 */ "MemStore", + /* 122 */ "Rewind", + /* 123 */ "MoveGe", + /* 124 */ "IdxPut", + /* 125 */ "Found", + /* 126 */ "NullRow", + /* 127 */ "NotUsed_127", + /* 128 */ "NotUsed_128", + /* 129 */ "NotUsed_129", + /* 130 */ "Real", + /* 131 */ "HexBlob", }; +#endif diff --git a/ext/pdo_sqlite/sqlite/src/opcodes.h b/ext/pdo_sqlite/sqlite/src/opcodes.h index 7b792c5a11..8be3dc7ea1 100644 --- a/ext/pdo_sqlite/sqlite/src/opcodes.h +++ b/ext/pdo_sqlite/sqlite/src/opcodes.h @@ -1,126 +1,135 @@ /* Automatically generated. Do not edit */ /* See the mkopcodeh.awk script for details */ -#define OP_ContextPop 1 -#define OP_IntegrityCk 2 -#define OP_DropTrigger 3 -#define OP_DropIndex 4 -#define OP_Recno 5 -#define OP_KeyAsData 6 -#define OP_Delete 7 -#define OP_MoveGt 8 -#define OP_VerifyCookie 9 -#define OP_Push 10 -#define OP_Dup 11 -#define OP_Blob 12 -#define OP_IdxGT 13 -#define OP_IdxRecno 14 -#define OP_RowKey 15 -#define OP_PutStrKey 16 -#define OP_IsUnique 17 -#define OP_SetNumColumns 18 -#define OP_Eq 67 -#define OP_IdxIsNull 19 -#define OP_NullRow 20 -#define OP_OpenPseudo 21 -#define OP_OpenWrite 22 -#define OP_OpenRead 23 -#define OP_Transaction 24 -#define OP_AutoCommit 25 -#define OP_Negative 82 -#define OP_Pop 26 -#define OP_Halt 27 -#define OP_Vacuum 28 -#define OP_ListRead 29 -#define OP_RowData 30 -#define OP_NotExists 31 -#define OP_MoveLe 32 -#define OP_SetCookie 33 -#define OP_Variable 34 -#define OP_AggNext 35 -#define OP_AggReset 36 -#define OP_Sort 37 -#define OP_IdxDelete 38 -#define OP_ResetCount 39 -#define OP_OpenTemp 40 -#define OP_IdxColumn 41 -#define OP_NotNull 65 -#define OP_Ge 71 -#define OP_Remainder 80 -#define OP_Divide 79 -#define OP_Integer 42 -#define OP_AggSet 43 -#define OP_CreateIndex 44 -#define OP_IdxPut 45 -#define OP_MoveLt 46 -#define OP_And 59 -#define OP_ShiftLeft 74 -#define OP_Real 122 -#define OP_Return 47 -#define OP_MemLoad 48 -#define OP_SortNext 49 -#define OP_IdxLT 50 -#define OP_Rewind 51 -#define OP_Gt 68 -#define OP_AddImm 52 -#define OP_Subtract 77 -#define OP_AggFunc 53 -#define OP_AggInit 54 -#define OP_MemIncr 55 -#define OP_ListReset 56 -#define OP_Clear 57 -#define OP_PutIntKey 61 -#define OP_IsNull 64 -#define OP_If 62 -#define OP_Callback 63 -#define OP_SortReset 83 -#define OP_SortPut 86 -#define OP_Last 87 -#define OP_NotFound 88 -#define OP_MakeRecord 89 -#define OP_BitAnd 72 -#define OP_Add 76 -#define OP_HexBlob 123 -#define OP_String 90 -#define OP_Goto 91 -#define OP_AggFocus 92 -#define OP_DropTable 93 -#define OP_Column 94 -#define OP_Noop 95 -#define OP_Not 60 -#define OP_Le 69 -#define OP_BitOr 73 -#define OP_Multiply 78 -#define OP_String8 85 -#define OP_AggGet 96 -#define OP_CreateTable 97 -#define OP_NewRecno 98 -#define OP_Found 99 -#define OP_Distinct 100 -#define OP_Close 101 -#define OP_Statement 102 -#define OP_IfNot 103 -#define OP_Pull 104 -#define OP_MemStore 105 -#define OP_Next 106 -#define OP_Prev 107 -#define OP_MoveGe 108 -#define OP_Lt 70 -#define OP_Ne 66 -#define OP_MustBeInt 109 -#define OP_ForceInt 110 -#define OP_ShiftRight 75 -#define OP_CollSeq 111 -#define OP_Gosub 112 -#define OP_ContextPush 113 -#define OP_ListRewind 114 -#define OP_ListWrite 115 -#define OP_ParseSchema 116 -#define OP_Destroy 117 -#define OP_IdxGE 118 -#define OP_FullKey 119 -#define OP_ReadCookie 120 -#define OP_BitNot 84 -#define OP_AbsValue 121 -#define OP_Or 58 -#define OP_Function 124 -#define OP_Concat 81 +#define OP_MemLoad 1 +#define OP_HexBlob 131 /* same as TK_BLOB */ +#define OP_Column 2 +#define OP_SetCookie 3 +#define OP_IfMemPos 4 +#define OP_Real 130 /* same as TK_FLOAT */ +#define OP_MoveGt 5 +#define OP_Ge 77 /* same as TK_GE */ +#define OP_AggFocus 6 +#define OP_RowKey 7 +#define OP_IdxRecno 8 +#define OP_AggNext 9 +#define OP_Eq 73 /* same as TK_EQ */ +#define OP_OpenWrite 10 +#define OP_NotNull 71 /* same as TK_NOTNULL */ +#define OP_If 11 +#define OP_PutStrKey 12 +#define OP_String8 92 /* same as TK_STRING */ +#define OP_Pop 13 +#define OP_SortPut 14 +#define OP_AggContextPush 15 +#define OP_CollSeq 16 +#define OP_OpenRead 17 +#define OP_Expire 18 +#define OP_SortReset 19 +#define OP_AutoCommit 20 +#define OP_Gt 74 /* same as TK_GT */ +#define OP_Sort 21 +#define OP_ListRewind 22 +#define OP_IntegrityCk 23 +#define OP_Function 24 +#define OP_Subtract 84 /* same as TK_MINUS */ +#define OP_And 65 /* same as TK_AND */ +#define OP_Noop 25 +#define OP_Return 26 +#define OP_Remainder 87 /* same as TK_REM */ +#define OP_Multiply 85 /* same as TK_STAR */ +#define OP_Variable 27 +#define OP_String 28 +#define OP_ParseSchema 29 +#define OP_PutIntKey 30 +#define OP_AggFunc 31 +#define OP_Close 32 +#define OP_ListWrite 33 +#define OP_CreateIndex 34 +#define OP_IsUnique 35 +#define OP_IdxIsNull 36 +#define OP_NotFound 37 +#define OP_MustBeInt 38 +#define OP_Halt 39 +#define OP_IdxLT 40 +#define OP_AddImm 41 +#define OP_Statement 42 +#define OP_RowData 43 +#define OP_MemMax 44 +#define OP_Push 45 +#define OP_Or 64 /* same as TK_OR */ +#define OP_KeyAsData 46 +#define OP_NotExists 47 +#define OP_OpenTemp 48 +#define OP_MemIncr 49 +#define OP_Gosub 50 +#define OP_Divide 86 /* same as TK_SLASH */ +#define OP_AggSet 51 +#define OP_Integer 52 +#define OP_SortNext 53 +#define OP_Prev 54 +#define OP_Concat 88 /* same as TK_CONCAT */ +#define OP_BitAnd 79 /* same as TK_BITAND */ +#define OP_CreateTable 55 +#define OP_Last 56 +#define OP_IsNull 70 /* same as TK_ISNULL */ +#define OP_ShiftRight 82 /* same as TK_RSHIFT */ +#define OP_ResetCount 57 +#define OP_Callback 58 +#define OP_ContextPush 59 +#define OP_DropTrigger 60 +#define OP_DropIndex 61 +#define OP_FullKey 62 +#define OP_IdxGE 63 +#define OP_IdxDelete 67 +#define OP_Vacuum 68 +#define OP_MoveLe 69 +#define OP_IfNot 78 +#define OP_DropTable 90 +#define OP_MakeRecord 93 +#define OP_Delete 94 +#define OP_AggContextPop 95 +#define OP_ListRead 96 +#define OP_ListReset 97 +#define OP_ShiftLeft 81 /* same as TK_LSHIFT */ +#define OP_Dup 98 +#define OP_Goto 99 +#define OP_Clear 100 +#define OP_IdxGT 101 +#define OP_MoveLt 102 +#define OP_Le 75 /* same as TK_LE */ +#define OP_VerifyCookie 103 +#define OP_Pull 104 +#define OP_Not 66 /* same as TK_NOT */ +#define OP_SetNumColumns 105 +#define OP_AbsValue 106 +#define OP_Transaction 107 +#define OP_Negative 89 /* same as TK_UMINUS */ +#define OP_Ne 72 /* same as TK_NE */ +#define OP_AggGet 108 +#define OP_ContextPop 109 +#define OP_BitOr 80 /* same as TK_BITOR */ +#define OP_Next 110 +#define OP_AggInit 111 +#define OP_Distinct 112 +#define OP_NewRecno 113 +#define OP_Lt 76 /* same as TK_LT */ +#define OP_AggReset 114 +#define OP_Destroy 115 +#define OP_ReadCookie 116 +#define OP_ForceInt 117 +#define OP_Recno 118 +#define OP_OpenPseudo 119 +#define OP_Blob 120 +#define OP_Add 83 /* same as TK_PLUS */ +#define OP_MemStore 121 +#define OP_Rewind 122 +#define OP_MoveGe 123 +#define OP_IdxPut 124 +#define OP_BitNot 91 /* same as TK_BITNOT */ +#define OP_Found 125 +#define OP_NullRow 126 + +/* The following opcode values are never used */ +#define OP_NotUsed_127 127 +#define OP_NotUsed_128 128 +#define OP_NotUsed_129 129 diff --git a/ext/pdo_sqlite/sqlite/src/os.h b/ext/pdo_sqlite/sqlite/src/os.h index fc478baa93..d39d62d809 100644 --- a/ext/pdo_sqlite/sqlite/src/os.h +++ b/ext/pdo_sqlite/sqlite/src/os.h @@ -25,30 +25,17 @@ */ #if !defined(OS_UNIX) && !defined(OS_TEST) # ifndef OS_WIN -# ifndef OS_MAC -# if defined(__MACOS__) -# define OS_MAC 1 -# define OS_WIN 0 -# define OS_UNIX 0 -# elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) -# define OS_MAC 0 -# define OS_WIN 1 -# define OS_UNIX 0 -# else -# define OS_MAC 0 -# define OS_WIN 0 -# define OS_UNIX 1 -# endif -# else -# define OS_WIN 0 -# define OS_UNIX 0 +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) +# define OS_WIN 1 +# define OS_UNIX 0 +# else +# define OS_WIN 0 +# define OS_UNIX 1 # endif # else -# define OS_MAC 0 # define OS_UNIX 0 # endif #else -# define OS_MAC 0 # ifndef OS_WIN # define OS_WIN 0 # endif @@ -66,9 +53,6 @@ #if OS_WIN # include "os_win.h" #endif -#if OS_MAC -# include "os_mac.h" -#endif /* ** Temporary files are named starting with this prefix followed by 16 random @@ -162,7 +146,7 @@ ** */ #define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */ -/* #define PENDING_BYTE 0x5400 // Page 20 - for testing */ +/* #define PENDING_BYTE 0x5400 // Page 22 - for testing */ #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 @@ -176,6 +160,7 @@ int sqlite3OsOpenReadOnly(const char*, OsFile*); int sqlite3OsOpenDirectory(const char*, OsFile*); int sqlite3OsSyncDirectory(const char*); int sqlite3OsTempFileName(char*); +int sqlite3OsIsDirWritable(char*); int sqlite3OsClose(OsFile*); int sqlite3OsRead(OsFile*, void*, int amt); int sqlite3OsWrite(OsFile*, const void*, int amt); diff --git a/ext/pdo_sqlite/sqlite/src/os_test.c b/ext/pdo_sqlite/sqlite/src/os_test.c index 0e292bc428..8199f5b183 100644 --- a/ext/pdo_sqlite/sqlite/src/os_test.c +++ b/ext/pdo_sqlite/sqlite/src/os_test.c @@ -239,10 +239,12 @@ printf("Writing block %d of %s\n", i, pFile->zName); if( BLOCK_OFFSET(i+1)>nMax ){ len = nMax-BLOCK_OFFSET(i); } - if( trash ){ - sqlite3Randomness(len, p); + if( len>0 ){ + if( trash ){ + sqlite3Randomness(len, p); + } + rc = sqlite3RealWrite(&pFile->fd, p, len); } - rc = sqlite3RealWrite(&pFile->fd, p, len); } sqliteFree(p); } diff --git a/ext/pdo_sqlite/sqlite/src/os_unix.c b/ext/pdo_sqlite/sqlite/src/os_unix.c index 94fca70199..0e270c0bb6 100644 --- a/ext/pdo_sqlite/sqlite/src/os_unix.c +++ b/ext/pdo_sqlite/sqlite/src/os_unix.c @@ -574,7 +574,7 @@ int sqlite3OsOpenDirectory( ** name of a directory, then that directory will be used to store ** temporary files. */ -const char *sqlite3_temp_directory = 0; +char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to @@ -616,6 +616,22 @@ int sqlite3OsTempFileName(char *zBuf){ return SQLITE_OK; } +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Check that a given pathname is a directory and is writable +** +*/ +int sqlite3OsIsDirWritable(char *zBuf){ + struct stat buf; + if( zBuf==0 ) return 0; + if( zBuf[0]==0 ) return 0; + if( stat(zBuf, &buf) ) return 0; + if( !S_ISDIR(buf.st_mode) ) return 0; + if( access(zBuf, 07) ) return 0; + return 1; +} +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes @@ -645,6 +661,7 @@ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ int wrote = 0; assert( id->isOpen ); + assert( amt>0 ); SimulateIOError(SQLITE_IOERR); SimulateDiskfullError; TIMER_START; @@ -675,8 +692,17 @@ int sqlite3OsSeek(OsFile *id, i64 offset){ ** The fsync() system call does not work as advertised on many ** unix systems. The following procedure is an attempt to make ** it work better. +** +** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful +** for testing when we want to run through the test suite quickly. +** You are strongly advised *not* to deploy with SQLITE_NO_SYNC +** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash +** or power failure will likely corrupt the database file. */ static int full_fsync(int fd){ +#ifdef SQLITE_NO_SYNC + return SQLITE_OK; +#else int rc; #ifdef F_FULLFSYNC rc = fcntl(fd, F_FULLFSYNC, 0); @@ -685,6 +711,7 @@ static int full_fsync(int fd){ rc = fsync(fd); #endif return rc; +#endif } /* @@ -1157,10 +1184,16 @@ int sqlite3OsRandomSeed(char *zBuf){ memset(zBuf, 0, 256); #if !defined(SQLITE_TEST) { - int pid; - time((time_t*)zBuf); - pid = getpid(); - memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid)); + int pid, fd; + fd = open("/dev/urandom", O_RDONLY); + if( fd<0 ){ + time((time_t*)zBuf); + pid = getpid(); + memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid)); + }else{ + read(fd, zBuf, 256); + close(fd); + } } #endif return SQLITE_OK; diff --git a/ext/pdo_sqlite/sqlite/src/os_win.c b/ext/pdo_sqlite/sqlite/src/os_win.c index f6e3e3ea83..2614ed08a6 100644 --- a/ext/pdo_sqlite/sqlite/src/os_win.c +++ b/ext/pdo_sqlite/sqlite/src/os_win.c @@ -202,7 +202,7 @@ int sqlite3OsOpenDirectory( ** name of a directory, then that directory will be used to store ** temporary files. */ -const char *sqlite3_temp_directory = 0; +char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to @@ -275,12 +275,13 @@ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ ** or some other error code on failure. */ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ - int rc; + int rc = 0; DWORD wrote; assert( id->isOpen ); SimulateIOError(SQLITE_IOERR); SimulateDiskfullError; TRACE3("WRITE %d lock=%d\n", id->h, id->locktype); + assert( amt>0 ); while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){ amt -= wrote; pBuf = &((char*)pBuf)[wrote]; @@ -409,6 +410,24 @@ static int unlockReadLock(OsFile *id){ return res; } +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Check that a given pathname is a directory and is writable +** +*/ +int sqlite3OsIsDirWritable(char *zBuf){ + int fileAttr; + if(! zBuf ) return 0; + if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0; + fileAttr = GetFileAttributesA(zBuf); + if( fileAttr == 0xffffffff ) return 0; + if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){ + return 0; + } + return 1; +} +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: diff --git a/ext/pdo_sqlite/sqlite/src/pager.c b/ext/pdo_sqlite/sqlite/src/pager.c index a374562bc7..47d895240c 100644 --- a/ext/pdo_sqlite/sqlite/src/pager.c +++ b/ext/pdo_sqlite/sqlite/src/pager.c @@ -34,13 +34,32 @@ #define TRACE2(X,Y) sqlite3DebugPrintf(X,Y) #define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z) #define TRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W) +#define TRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V) #else #define TRACE1(X) #define TRACE2(X,Y) #define TRACE3(X,Y,Z) #define TRACE4(X,Y,Z,W) +#define TRACE5(X,Y,Z,W,V) #endif +/* +** The following two macros are used within the TRACEX() macros above +** to print out file-descriptors. They are required so that tracing +** can be turned on when using both the regular os_unix.c and os_test.c +** backends. +** +** PAGERID() takes a pointer to a Pager struct as it's argument. The +** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile +** struct as it's argument. +*/ +#ifdef OS_TEST +#define PAGERID(p) (p->fd->fd.h) +#define FILEHANDLEID(fd) (fd->fd.h) +#else +#define PAGERID(p) (p->fd.h) +#define FILEHANDLEID(fd) (fd.h) +#endif /* ** The page cache as a whole is always in one of the following @@ -110,6 +129,12 @@ # define SQLITE_BUSY_RESERVED_LOCK 0 #endif +/* +** This macro rounds values up so that if the value is an address it +** is guaranteed to be an address that is aligned to an 8-byte boundary. +*/ +#define FORCE_ALIGNMENT(X) (((X)+7)&~7) + /* ** Each in-memory image of a page begins with the following header. ** This header is only visible to this pager module. The client @@ -143,7 +168,10 @@ struct PgHdr { u8 alwaysRollback; /* Disable dont_rollback() for this page */ short int nRef; /* Number of users of this page */ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ - /* pPager->pageSize bytes of page data follow this header */ +#ifdef SQLITE_CHECK_PAGES + u32 pageHash; +#endif + /* pPager->psAligned bytes of page data follow this header */ /* Pager.nExtra bytes of local data follow the page data */ }; @@ -179,9 +207,9 @@ struct PgHistory { */ #define PGHDR_TO_DATA(P) ((void*)(&(P)[1])) #define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1]) -#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize]) +#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->psAligned]) #define PGHDR_TO_HIST(P,PGR) \ - ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra]) + ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->psAligned+(PGR)->nExtra]) /* ** How big to make the hash table used for locating in-memory pages @@ -214,15 +242,18 @@ struct Pager { void (*xDestructor)(void*,int); /* Call this routine when freeing pages */ void (*xReiniter)(void*,int); /* Call this routine when reloading pages */ int pageSize; /* Number of bytes in a page */ + int psAligned; /* pageSize rounded up to a multiple of 8 */ int nPage; /* Total number of in-memory pages */ int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ int mxPage; /* Maximum number of pages to hold in cache */ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ + int nRead,nWrite; /* Database pages read/written */ void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void *pCodecArg; /* First argument to xCodec() */ u8 journalOpen; /* True if journal file descriptors is valid */ u8 journalStarted; /* True if header of journal is synced */ u8 useJournal; /* Use a rollback journal on this file */ + u8 noReadlock; /* Do not bother to obtain readlocks */ u8 stmtOpen; /* True if the statement subjournal is open */ u8 stmtInUse; /* True we are in a statement subtransaction */ u8 stmtAutoopen; /* Open stmt journal when main journal is opened*/ @@ -301,6 +332,21 @@ static const unsigned char aJournalMagic[] = { */ #define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) +/* +** The macro MEMDB is true if we are dealing with an in-memory database. +** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, +** the value of MEMDB will be a constant and the compiler will optimize +** out code that would never execute. +*/ +#ifdef SQLITE_OMIT_MEMORYDB +# define MEMDB 0 +#else +# define MEMDB pPager->memDb +#endif + +/* +** The default size of a disk sector +*/ #define PAGER_SECTOR_SIZE 512 /* @@ -310,12 +356,18 @@ static const unsigned char aJournalMagic[] = { ** is devoted to storing a master journal name - there are no more pages to ** roll back. See comments for function writeMasterJournal() for details. */ -#define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) +/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */ +#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1) + +/* +** The maximum legal page number is (2^31 - 1). +*/ +#define PAGER_MAX_PGNO 2147483647 /* ** Enable reference count tracking (for debugging) here: */ -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG int pager3_refinfo_enable = 0; static void pager_refinfo(PgHdr *p){ static int cnt = 0; @@ -402,6 +454,36 @@ static int pager_errcode(Pager *pPager){ return rc; } +#ifdef SQLITE_CHECK_PAGES +/* +** Return a 32-bit hash of the page data for pPage. +*/ +static u32 pager_pagehash(PgHdr *pPage){ + u32 hash = 0; + int i; + unsigned char *pData = (unsigned char *)PGHDR_TO_DATA(pPage); + for(i=0; ipPager->pageSize; i++){ + hash = (hash+i)^pData[i]; + } + return hash; +} + +/* +** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES +** is defined, and NDEBUG is not defined, an assert() statement checks +** that the page is either dirty or still matches the calculated page-hash. +*/ +#define CHECK_PAGE(x) checkPage(x) +static void checkPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty || + pPg->pageHash==pager_pagehash(pPg) ); +} + +#else +#define CHECK_PAGE(x) +#endif + /* ** When this is called the journal file for pager pPager must be open. ** The master journal file name is read from the end of the file and @@ -463,8 +545,9 @@ static int readMasterJournal(OsFile *pJrnl, char **pzMaster){ */ sqliteFree(*pzMaster); *pzMaster = 0; + }else{ + (*pzMaster)[len] = '\0'; } - (*pzMaster)[len] = '\0'; return SQLITE_OK; } @@ -772,7 +855,7 @@ static void pager_reset(Pager *pPager){ static int pager_unwritelock(Pager *pPager){ PgHdr *pPg; int rc; - assert( !pPager->memDb ); + assert( !MEMDB ); if( pPager->stateinJournal = 0; pPg->dirty = 0; pPg->needSync = 0; +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif } pPager->dirtyCache = 0; pPager->nRec = 0; @@ -886,18 +972,20 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ */ pPg = pager_lookup(pPager, pgno); assert( pPager->state>=PAGER_EXCLUSIVE || pPg ); - TRACE3("PLAYBACK %d page %d\n", pPager->fd.h, pgno); + TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno); if( pPager->state>=PAGER_EXCLUSIVE ){ sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize); } if( pPg ){ - /* No page should ever be rolled back that is in use, except for page - ** 1 which is held in use in order to keep the lock on the database - ** active. + /* No page should ever be explicitly rolled back that is in use, except + ** for page 1 which is held in use in order to keep the lock on the + ** database active. However such a page may be rolled back as a result + ** of an internal error resulting in an automatic call to + ** sqlite3pager_rollback(). */ void *pData; - assert( pPg->nRef==0 || pPg->pgno==1 ); + /* assert( pPg->nRef==0 || pPg->pgno==1 ); */ pData = PGHDR_TO_DATA(pPg); memcpy(pData, aData, pPager->pageSize); if( pPager->xDestructor ){ /*** FIX ME: Should this be xReinit? ***/ @@ -906,6 +994,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ if( pPager->state>=PAGER_EXCLUSIVE ){ pPg->dirty = 0; pPg->needSync = 0; +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif } CODEC(pPager, pData, pPg->pgno, 3); } @@ -963,6 +1054,7 @@ static int pager_delmaster(const char *zMaster){ ** so, return without deleting the master journal file. */ OsFile journal; + int c; memset(&journal, 0, sizeof(journal)); rc = sqlite3OsOpenReadOnly(zJournal, &journal); @@ -976,7 +1068,9 @@ static int pager_delmaster(const char *zMaster){ goto delmaster_out; } - if( zMasterPtr && !strcmp(zMasterPtr, zMaster) ){ + c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0; + sqliteFree(zMasterPtr); + if( c ){ /* We have a match. Do not delete the master journal file. */ goto delmaster_out; } @@ -1015,7 +1109,7 @@ static int pager_reload_cache(Pager *pPager){ if( (int)pPg->pgno <= pPager->origDbSize ){ sqlite3OsSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1)); rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize); - TRACE3("REFETCH %d page %d\n", pPager->fd.h, pPg->pgno); + TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno); if( rc ) break; CODEC(pPager, zBuf, pPg->pgno, 2); }else{ @@ -1031,6 +1125,9 @@ static int pager_reload_cache(Pager *pPager){ } pPg->needSync = 0; pPg->dirty = 0; +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif } return rc; } @@ -1040,6 +1137,7 @@ static int pager_reload_cache(Pager *pPager){ ** indicated. */ static int pager_truncate(Pager *pPager, int nPage){ + assert( pPager->state>=PAGER_EXCLUSIVE ); return sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(i64)nPage); } @@ -1159,7 +1257,8 @@ static int pager_playback(Pager *pPager){ /* If this is the first header read from the journal, truncate the ** database file back to it's original size. */ - if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ + if( pPager->state>=PAGER_EXCLUSIVE && + pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg ); rc = pager_truncate(pPager, mxPg); if( rc!=SQLITE_OK ){ @@ -1200,11 +1299,10 @@ end_playback: } if( zMaster ){ /* If there was a master journal and this routine will return true, - ** see if it is possible to delete the master journal. If errors - ** occur during this process, ignore them. + ** see if it is possible to delete the master journal. */ if( rc==SQLITE_OK ){ - pager_delmaster(zMaster); + rc = pager_delmaster(zMaster); } sqliteFree(zMaster); } @@ -1258,10 +1356,11 @@ static int pager_stmt_playback(Pager *pPager){ hdrOff = szJ; } - /* Truncate the database back to its original size. */ - rc = pager_truncate(pPager, pPager->stmtSize); + if( pPager->state>=PAGER_EXCLUSIVE ){ + rc = pager_truncate(pPager, pPager->stmtSize); + } pPager->dbSize = pPager->stmtSize; /* Figure out how many records are in the statement journal. @@ -1384,11 +1483,13 @@ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){ ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS void sqlite3pager_set_safety_level(Pager *pPager, int level){ pPager->noSync = level==1 || pPager->tempFile; pPager->fullSync = level==3 && !pPager->tempFile; if( pPager->noSync ) pPager->needSync = 0; } +#endif /* ** Open a temporary file. Write the name of the file into zName @@ -1428,7 +1529,7 @@ int sqlite3pager_open( Pager **ppPager, /* Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ - int useJournal /* TRUE to use a rollback journal on this file */ + int flags /* flags controlling this file */ ){ Pager *pPager; char *zFullPathname = 0; @@ -1439,6 +1540,8 @@ int sqlite3pager_open( int tempFile = 0; int memDb = 0; int readOnly = 0; + int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; + int noReadlock = (flags & PAGER_NO_READLOCK)!=0; char zTemp[SQLITE_TEMPNAME_SIZE]; *ppPager = 0; @@ -1447,11 +1550,14 @@ int sqlite3pager_open( return SQLITE_NOMEM; } if( zFilename && zFilename[0] ){ +#ifndef SQLITE_OMIT_MEMORYDB if( strcmp(zFilename,":memory:")==0 ){ memDb = 1; zFullPathname = sqliteStrDup(""); rc = SQLITE_OK; - }else{ + }else +#endif + { zFullPathname = sqlite3OsFullPathname(zFilename); if( zFullPathname ){ rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly); @@ -1481,7 +1587,7 @@ int sqlite3pager_open( sqliteFree(zFullPathname); return SQLITE_NOMEM; } - TRACE3("OPEN %d %s\n", fd.h, zFullPathname); + TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname); pPager->zFilename = (char*)&pPager[1]; pPager->zDirectory = &pPager->zFilename[nameLen+1]; pPager->zJournal = &pPager->zDirectory[nameLen+1]; @@ -1498,11 +1604,13 @@ int sqlite3pager_open( #endif pPager->journalOpen = 0; pPager->useJournal = useJournal && !memDb; + pPager->noReadlock = noReadlock && readOnly; pPager->stmtOpen = 0; pPager->stmtInUse = 0; pPager->nRef = 0; pPager->dbSize = memDb-1; pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE; + pPager->psAligned = FORCE_ALIGNMENT(pPager->pageSize); pPager->stmtSize = 0; pPager->stmtJSize = 0; pPager->nPage = 0; @@ -1518,7 +1626,7 @@ int sqlite3pager_open( pPager->pFirst = 0; pPager->pFirstSynced = 0; pPager->pLast = 0; - pPager->nExtra = nExtra; + pPager->nExtra = FORCE_ALIGNMENT(nExtra); pPager->sectorSize = PAGER_SECTOR_SIZE; pPager->pBusyHandler = 0; memset(pPager->aHash, 0, sizeof(pPager->aHash)); @@ -1564,6 +1672,7 @@ void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){ void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); pPager->pageSize = pageSize; + pPager->psAligned = FORCE_ALIGNMENT(pageSize); } /* @@ -1572,7 +1681,7 @@ void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ */ void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ memset(pDest, 0, N); - if( pPager->memDb==0 ){ + if( MEMDB==0 ){ sqlite3OsSeek(&pPager->fd, 0); sqlite3OsRead(&pPager->fd, pDest, N); } @@ -1593,7 +1702,7 @@ int sqlite3pager_pagecount(Pager *pPager){ return 0; } n /= pPager->pageSize; - if( !pPager->memDb && n==PENDING_BYTE/pPager->pageSize ){ + if( !MEMDB && n==PENDING_BYTE/pPager->pageSize ){ n++; } if( pPager->state!=PAGER_UNLOCK ){ @@ -1608,6 +1717,33 @@ int sqlite3pager_pagecount(Pager *pPager){ static int syncJournal(Pager*); +/* +** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate +** that the page is not part of any hash chain. This is required because the +** sqlite3pager_movepage() routine can leave a page in the +** pNextFree/pPrevFree list that is not a part of any hash-chain. +*/ +static void unlinkHashChain(Pager *pPager, PgHdr *pPg){ + if( pPg->pgno==0 ){ + /* If the page number is zero, then this page is not in any hash chain. */ + return; + } + if( pPg->pNextHash ){ + pPg->pNextHash->pPrevHash = pPg->pPrevHash; + } + if( pPg->pPrevHash ){ + assert( pPager->aHash[pager_hash(pPg->pgno)]!=pPg ); + pPg->pPrevHash->pNextHash = pPg->pNextHash; + }else{ + int h = pager_hash(pPg->pgno); + assert( pPager->aHash[h]==pPg ); + pPager->aHash[h] = pPg->pNextHash; + } + + pPg->pgno = 0; + pPg->pNextHash = pPg->pPrevHash = 0; +} + /* ** Unlink a page from the free list (the list of all pages where nRef==0) ** and from its hash collision chain. @@ -1638,19 +1774,10 @@ static void unlinkPage(PgHdr *pPg){ pPg->pNextFree = pPg->pPrevFree = 0; /* Unlink from the pgno hash table */ - if( pPg->pNextHash ){ - pPg->pNextHash->pPrevHash = pPg->pPrevHash; - } - if( pPg->pPrevHash ){ - pPg->pPrevHash->pNextHash = pPg->pNextHash; - }else{ - int h = pager_hash(pPg->pgno); - assert( pPager->aHash[h]==pPg ); - pPager->aHash[h] = pPg->pNextHash; - } - pPg->pNextHash = pPg->pPrevHash = 0; + unlinkHashChain(pPager, pPg); } +#ifndef SQLITE_OMIT_MEMORYDB /* ** This routine is used to truncate an in-memory database. Delete ** all pages whose pgno is larger than pPager->dbSize and is unreferenced. @@ -1676,6 +1803,40 @@ static void memoryTruncate(Pager *pPager){ } } } +#else +#define memoryTruncate(p) +#endif + +/* +** Try to obtain a lock on a file. Invoke the busy callback if the lock +** is currently not available. Repeate until the busy callback returns +** false or until the lock succeeds. +** +** Return SQLITE_OK on success and an error code if we cannot obtain +** the lock. +*/ +static int pager_wait_on_lock(Pager *pPager, int locktype){ + int rc; + assert( PAGER_SHARED==SHARED_LOCK ); + assert( PAGER_RESERVED==RESERVED_LOCK ); + assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK ); + if( pPager->state>=locktype ){ + rc = SQLITE_OK; + }else{ + int busy = 1; + do { + rc = sqlite3OsLock(&pPager->fd, locktype); + }while( rc==SQLITE_BUSY && + pPager->pBusyHandler && + pPager->pBusyHandler->xFunc && + pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++) + ); + if( rc==SQLITE_OK ){ + pPager->state = locktype; + } + } + return rc; +} /* ** Truncate the file to the number of pages specified. @@ -1690,7 +1851,7 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ if( nPage>=(unsigned)pPager->dbSize ){ return SQLITE_OK; } - if( pPager->memDb ){ + if( MEMDB ){ pPager->dbSize = nPage; memoryTruncate(pPager); return SQLITE_OK; @@ -1699,6 +1860,13 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ if( rc!=SQLITE_OK ){ return rc; } + + /* Get an exclusive lock on the database before truncating. */ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = pager_truncate(pPager, nPage); if( rc==SQLITE_OK ){ pPager->dbSize = nPage; @@ -1721,15 +1889,27 @@ int sqlite3pager_close(Pager *pPager){ case PAGER_RESERVED: case PAGER_SYNCED: case PAGER_EXCLUSIVE: { + /* We ignore any IO errors that occur during the rollback + ** operation. So disable IO error simulation so that testing + ** works more easily. + */ +#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN)) + extern int sqlite3_io_error_pending; + int ioerr_cnt = sqlite3_io_error_pending; + sqlite3_io_error_pending = -1; +#endif sqlite3pager_rollback(pPager); - if( !pPager->memDb ){ +#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN)) + sqlite3_io_error_pending = ioerr_cnt; +#endif + if( !MEMDB ){ sqlite3OsUnlock(&pPager->fd, NO_LOCK); } assert( pPager->journalOpen==0 ); break; } case PAGER_SHARED: { - if( !pPager->memDb ){ + if( !MEMDB ){ sqlite3OsUnlock(&pPager->fd, NO_LOCK); } break; @@ -1741,7 +1921,7 @@ int sqlite3pager_close(Pager *pPager){ } for(pPg=pPager->pAll; pPg; pPg=pNext){ #ifndef NDEBUG - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( !pPg->alwaysRollback ); assert( !pHist->pOrig ); @@ -1751,7 +1931,7 @@ int sqlite3pager_close(Pager *pPager){ pNext = pPg->pNextAll; sqliteFree(pPg); } - TRACE2("CLOSE %d\n", pPager->fd.h); + TRACE2("CLOSE %d\n", PAGERID(pPager)); sqlite3OsClose(&pPager->fd); assert( pPager->journalOpen==0 ); /* Temp files are automatically deleted by the OS @@ -1759,12 +1939,7 @@ int sqlite3pager_close(Pager *pPager){ ** sqlite3OsDelete(pPager->zFilename); ** } */ - if( pPager->zFilename!=(char*)&pPager[1] ){ - assert( 0 ); /* Cannot happen */ - sqliteFree(pPager->zFilename); - sqliteFree(pPager->zJournal); - sqliteFree(pPager->zDirectory); - } + sqliteFree(pPager); return SQLITE_OK; } @@ -1809,7 +1984,7 @@ static void _page_ref(PgHdr *pPg){ pPg->nRef++; REFINFO(pPg); } -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG static void page_ref(PgHdr *pPg){ if( pPg->nRef==0 ){ _page_ref(pPg); @@ -1882,7 +2057,7 @@ static int syncJournal(Pager *pPager){ ** it as a candidate for rollback. */ if( pPager->fullSync ){ - TRACE2("SYNC journal of %d\n", pPager->fd.h); + TRACE2("SYNC journal of %d\n", PAGERID(pPager)); rc = sqlite3OsSync(&pPager->jfd); if( rc!=0 ) return rc; } @@ -1892,7 +2067,7 @@ static int syncJournal(Pager *pPager){ sqlite3OsSeek(&pPager->jfd, pPager->journalOff); } - TRACE2("SYNC journal of %d\n", pPager->fd.h); + TRACE2("SYNC journal of %d\n", PAGERID(pPager)); rc = sqlite3OsSync(&pPager->jfd); if( rc!=0 ) return rc; pPager->journalStarted = 1; @@ -1923,37 +2098,6 @@ static int syncJournal(Pager *pPager){ return rc; } -/* -** Try to obtain a lock on a file. Invoke the busy callback if the lock -** is currently not available. Repeate until the busy callback returns -** false or until the lock succeeds. -** -** Return SQLITE_OK on success and an error code if we cannot obtain -** the lock. -*/ -static int pager_wait_on_lock(Pager *pPager, int locktype){ - int rc; - assert( PAGER_SHARED==SHARED_LOCK ); - assert( PAGER_RESERVED==RESERVED_LOCK ); - assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK ); - if( pPager->state>=locktype ){ - rc = SQLITE_OK; - }else{ - int busy = 1; - do { - rc = sqlite3OsLock(&pPager->fd, locktype); - }while( rc==SQLITE_BUSY && - pPager->pBusyHandler && - pPager->pBusyHandler->xFunc && - pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++) - ); - if( rc==SQLITE_OK ){ - pPager->state = locktype; - } - } - return rc; -} - /* ** Given a list of pages (connected by the PgHdr.pDirty pointer) write ** every one of those pages out to the database file and mark them all @@ -1990,12 +2134,28 @@ static int pager_write_pagelist(PgHdr *pList){ while( pList ){ assert( pList->dirty ); sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize); - CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); - TRACE3("STORE %d page %d\n", pPager->fd.h, pList->pgno); - rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize); - CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0); + /* If there are dirty pages in the page cache with page numbers greater + ** than Pager.dbSize, this means sqlite3pager_truncate() was called to + ** make the file smaller (presumably by auto-vacuum code). Do not write + ** any such pages to the file. + */ + if( pList->pgno<=pPager->dbSize ){ + CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); + TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno); + rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize); + CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0); + pPager->nWrite++; + } +#ifndef NDEBUG + else{ + TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno); + } +#endif if( rc ) return rc; pList->dirty = 0; +#ifdef SQLITE_CHECK_PAGES + pList->pageHash = pager_pagehash(pList); +#endif pList = pList->pDirty; } return SQLITE_OK; @@ -2043,12 +2203,18 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ */ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ PgHdr *pPg; - int rc; + int rc, n; + + /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page + ** number greater than this, or zero, is requested. + */ + if( pgno>PAGER_MAX_PGNO || pgno==0 ){ + return SQLITE_CORRUPT; + } /* Make sure we have not hit any critical errors. */ assert( pPager!=0 ); - assert( pgno!=0 ); *ppPage = 0; if( pPager->errMask & ~(PAGER_ERR_FULL) ){ return pager_errcode(pPager); @@ -2057,10 +2223,12 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ /* If this is the first page accessed, then get a SHARED lock ** on the database file. */ - if( pPager->nRef==0 && !pPager->memDb ){ - rc = pager_wait_on_lock(pPager, SHARED_LOCK); - if( rc!=SQLITE_OK ){ - return rc; + if( pPager->nRef==0 && !MEMDB ){ + if( !pPager->noReadlock ){ + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } } /* If a journal file exists, and there is no RESERVED lock on the @@ -2123,7 +2291,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ }else{ /* Search for page in cache */ pPg = pager_lookup(pPager, pgno); - if( pPager->memDb && pPager->state==PAGER_UNLOCK ){ + if( MEMDB && pPager->state==PAGER_UNLOCK ){ pPager->state = PAGER_SHARED; } } @@ -2131,20 +2299,20 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ /* The requested page is not in the page cache. */ int h; pPager->nMiss++; - if( pPager->nPagemxPage || pPager->pFirst==0 || pPager->memDb ){ + if( pPager->nPagemxPage || pPager->pFirst==0 || MEMDB ){ /* Create a new page */ - pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize + pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned + sizeof(u32) + pPager->nExtra - + pPager->memDb*sizeof(PgHistory) ); + + MEMDB*sizeof(PgHistory) ); if( pPg==0 ){ - if( !pPager->memDb ){ + if( !MEMDB ){ pager_unwritelock(pPager); } pPager->errMask |= PAGER_ERR_MEM; return SQLITE_NOMEM; } memset(pPg, 0, sizeof(*pPg)); - if( pPager->memDb ){ + if( MEMDB ){ memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory)); } pPg->pPager = pPager; @@ -2247,20 +2415,20 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } - sqlite3pager_pagecount(pPager); + n = sqlite3pager_pagecount(pPager); if( pPager->errMask!=0 ){ sqlite3pager_unref(PGHDR_TO_DATA(pPg)); rc = pager_errcode(pPager); return rc; } - if( pPager->dbSize<(int)pgno ){ + if( n<(int)pgno ){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ int rc; - assert( pPager->memDb==0 ); + assert( MEMDB==0 ); sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize); - TRACE3("FETCH %d page %d\n", pPager->fd.h, pPg->pgno); + TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); if( rc!=SQLITE_OK ){ i64 fileSize; @@ -2271,8 +2439,13 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ }else{ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); } + }else{ + pPager->nRead++; } } +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif }else{ /* The requested page is in the page cache. */ pPager->nHit++; @@ -2325,6 +2498,8 @@ int sqlite3pager_unref(void *pData){ pPg->nRef--; REFINFO(pPg); + CHECK_PAGE(pPg); + /* When the number of references to a page reach 0, call the ** destructor and add the page to the freelist. */ @@ -2351,7 +2526,7 @@ int sqlite3pager_unref(void *pData){ */ pPager->nRef--; assert( pPager->nRef>=0 ); - if( pPager->nRef==0 && !pPager->memDb ){ + if( pPager->nRef==0 && !MEMDB ){ pager_reset(pPager); } } @@ -2367,7 +2542,7 @@ int sqlite3pager_unref(void *pData){ */ static int pager_open_journal(Pager *pPager){ int rc; - assert( !pPager->memDb ); + assert( !MEMDB ); assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); @@ -2452,7 +2627,7 @@ int sqlite3pager_begin(void *pData, int exFlag){ assert( pPager->state!=PAGER_UNLOCK ); if( pPager->state==PAGER_SHARED ){ assert( pPager->aInJournal==0 ); - if( pPager->memDb ){ + if( MEMDB ){ pPager->state = PAGER_EXCLUSIVE; pPager->origDbSize = pPager->dbSize; }else{ @@ -2471,7 +2646,7 @@ int sqlite3pager_begin(void *pData, int exFlag){ return rc; } pPager->dirtyCache = 0; - TRACE2("TRANSACTION %d\n", pPager->fd.h); + TRACE2("TRANSACTION %d\n", PAGERID(pPager)); if( pPager->useJournal && !pPager->tempFile ){ rc = pager_open_journal(pPager); } @@ -2513,128 +2688,130 @@ int sqlite3pager_write(void *pData){ assert( !pPager->setMaster ); + CHECK_PAGE(pPg); + /* Mark the page as dirty. If the page has already been written ** to the journal then we can return right away. */ pPg->dirty = 1; if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){ pPager->dirtyCache = 1; - return SQLITE_OK; - } - - /* If we get this far, it means that the page needs to be - ** written to the transaction journal or the ckeckpoint journal - ** or both. - ** - ** First check to see that the transaction journal exists and - ** create it if it does not. - */ - assert( pPager->state!=PAGER_UNLOCK ); - rc = sqlite3pager_begin(pData, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pPager->state>=PAGER_RESERVED ); - if( !pPager->journalOpen && pPager->useJournal ){ - rc = pager_open_journal(pPager); - if( rc!=SQLITE_OK ) return rc; - } - assert( pPager->journalOpen || !pPager->useJournal ); - pPager->dirtyCache = 1; + }else{ - /* The transaction journal now exists and we have a RESERVED or an - ** EXCLUSIVE lock on the main database file. Write the current page to - ** the transaction journal if it is not there already. - */ - if( !pPg->inJournal && (pPager->useJournal || pPager->memDb) ){ - if( (int)pPg->pgno <= pPager->origDbSize ){ - int szPg; - u32 saved; - if( pPager->memDb ){ + /* If we get this far, it means that the page needs to be + ** written to the transaction journal or the ckeckpoint journal + ** or both. + ** + ** First check to see that the transaction journal exists and + ** create it if it does not. + */ + assert( pPager->state!=PAGER_UNLOCK ); + rc = sqlite3pager_begin(pData, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pPager->state>=PAGER_RESERVED ); + if( !pPager->journalOpen && pPager->useJournal ){ + rc = pager_open_journal(pPager); + if( rc!=SQLITE_OK ) return rc; + } + assert( pPager->journalOpen || !pPager->useJournal ); + pPager->dirtyCache = 1; + + /* The transaction journal now exists and we have a RESERVED or an + ** EXCLUSIVE lock on the main database file. Write the current page to + ** the transaction journal if it is not there already. + */ + if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){ + if( (int)pPg->pgno <= pPager->origDbSize ){ + int szPg; + u32 saved; + if( MEMDB ){ + PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); + TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); + assert( pHist->pOrig==0 ); + pHist->pOrig = sqliteMallocRaw( pPager->pageSize ); + if( pHist->pOrig ){ + memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); + } + }else{ + u32 cksum; + CODEC(pPager, pData, pPg->pgno, 7); + cksum = pager_cksum(pPager, pPg->pgno, pData); + saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager); + store32bits(cksum, pPg, pPager->pageSize); + szPg = pPager->pageSize+8; + store32bits(pPg->pgno, pPg, -4); + rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg); + pPager->journalOff += szPg; + TRACE4("JOURNAL %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, pPg->needSync); + CODEC(pPager, pData, pPg->pgno, 0); + *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved; + if( rc!=SQLITE_OK ){ + sqlite3pager_rollback(pPager); + pPager->errMask |= PAGER_ERR_FULL; + return rc; + } + pPager->nRec++; + assert( pPager->aInJournal!=0 ); + pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); + pPg->needSync = !pPager->noSync; + if( pPager->stmtInUse ){ + pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); + page_add_to_stmt_list(pPg); + } + } + }else{ + pPg->needSync = !pPager->journalStarted && !pPager->noSync; + TRACE4("APPEND %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, pPg->needSync); + } + if( pPg->needSync ){ + pPager->needSync = 1; + } + pPg->inJournal = 1; + } + + /* If the statement journal is open and the page is not in it, + ** then write the current page to the statement journal. Note that + ** the statement journal format differs from the standard journal format + ** in that it omits the checksums and the header. + */ + if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ + assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - TRACE3("JOURNAL %d page %d\n", pPager->fd.h, pPg->pgno); - assert( pHist->pOrig==0 ); - pHist->pOrig = sqliteMallocRaw( pPager->pageSize ); - if( pHist->pOrig ){ - memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); + assert( pHist->pStmt==0 ); + pHist->pStmt = sqliteMallocRaw( pPager->pageSize ); + if( pHist->pStmt ){ + memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); } + TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); }else{ - u32 cksum; - CODEC(pPager, pData, pPg->pgno, 7); - cksum = pager_cksum(pPager, pPg->pgno, pData); - saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager); - store32bits(cksum, pPg, pPager->pageSize); - szPg = pPager->pageSize+8; store32bits(pPg->pgno, pPg, -4); - rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg); - pPager->journalOff += szPg; - TRACE4("JOURNAL %d page %d needSync=%d\n", - pPager->fd.h, pPg->pgno, pPg->needSync); + CODEC(pPager, pData, pPg->pgno, 7); + rc = sqlite3OsWrite(&pPager->stfd,((char*)pData)-4, pPager->pageSize+4); + TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC(pPager, pData, pPg->pgno, 0); - *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved; if( rc!=SQLITE_OK ){ sqlite3pager_rollback(pPager); pPager->errMask |= PAGER_ERR_FULL; return rc; } - pPager->nRec++; - assert( pPager->aInJournal!=0 ); - pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); - pPg->needSync = !pPager->noSync; - if( pPager->stmtInUse ){ - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); - page_add_to_stmt_list(pPg); - } + pPager->stmtNRec++; + assert( pPager->aInStmt!=0 ); + pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); } - }else{ - pPg->needSync = !pPager->journalStarted && !pPager->noSync; - TRACE4("APPEND %d page %d needSync=%d\n", - pPager->fd.h, pPg->pgno, pPg->needSync); - } - if( pPg->needSync ){ - pPager->needSync = 1; - } - pPg->inJournal = 1; - } - - /* If the statement journal is open and the page is not in it, - ** then write the current page to the statement journal. Note that - ** the statement journal format differs from the standard journal format - ** in that it omits the checksums and the header. - */ - if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ - assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); - if( pPager->memDb ){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - assert( pHist->pStmt==0 ); - pHist->pStmt = sqliteMallocRaw( pPager->pageSize ); - if( pHist->pStmt ){ - memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); - } - TRACE3("STMT-JOURNAL %d page %d\n", pPager->fd.h, pPg->pgno); - }else{ - store32bits(pPg->pgno, pPg, -4); - CODEC(pPager, pData, pPg->pgno, 7); - rc = sqlite3OsWrite(&pPager->stfd, ((char*)pData)-4, pPager->pageSize+4); - TRACE3("STMT-JOURNAL %d page %d\n", pPager->fd.h, pPg->pgno); - CODEC(pPager, pData, pPg->pgno, 0); - if( rc!=SQLITE_OK ){ - sqlite3pager_rollback(pPager); - pPager->errMask |= PAGER_ERR_FULL; - return rc; - } - pPager->stmtNRec++; - assert( pPager->aInStmt!=0 ); - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); + page_add_to_stmt_list(pPg); } - page_add_to_stmt_list(pPg); } /* Update the database size and return. */ if( pPager->dbSize<(int)pPg->pgno ){ pPager->dbSize = pPg->pgno; - if( !pPager->memDb && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ + if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ pPager->dbSize++; } } @@ -2651,6 +2828,7 @@ int sqlite3pager_iswriteable(void *pData){ return pPg->dirty; } +#ifndef SQLITE_OMIT_VACUUM /* ** Replace the content of a single page with the information in the third ** argument. @@ -2669,6 +2847,7 @@ int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){ } return rc; } +#endif /* ** A call to this routine tells the pager that it is not necessary to @@ -2697,7 +2876,7 @@ int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){ PgHdr *pPg; - if( pPager->memDb ) return; + if( MEMDB ) return; pPg = pager_lookup(pPager, pgno); pPg->alwaysRollback = 1; @@ -2712,8 +2891,11 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){ ** corruption during the next transaction. */ }else{ - TRACE3("DONT_WRITE page %d of %d\n", pgno, pPager->fd.h); + TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager)); pPg->dirty = 0; +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif } } } @@ -2729,7 +2911,7 @@ void sqlite3pager_dont_rollback(void *pData){ Pager *pPager = pPg->pPager; if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return; - if( pPg->alwaysRollback || pPager->alwaysRollback || pPager->memDb ) return; + if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return; if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){ assert( pPager->aInJournal!=0 ); pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); @@ -2738,7 +2920,7 @@ void sqlite3pager_dont_rollback(void *pData){ pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); page_add_to_stmt_list(pPg); } - TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, pPager->fd.h); + TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager)); } if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); @@ -2749,6 +2931,7 @@ void sqlite3pager_dont_rollback(void *pData){ } +#ifndef SQLITE_OMIT_MEMORYDB /* ** Clear a PgHistory block */ @@ -2758,6 +2941,9 @@ static void clearHistory(PgHistory *pHist){ pHist->pOrig = 0; pHist->pStmt = 0; } +#else +#define clearHistory(x) +#endif /* ** Commit all changes to the database and release the write lock. @@ -2784,8 +2970,8 @@ int sqlite3pager_commit(Pager *pPager){ if( pPager->statefd.h); - if( pPager->memDb ){ + TRACE2("COMMIT %d\n", PAGERID(pPager)); + if( MEMDB ){ pPg = pager_get_all_dirty_pages(pPager); while( pPg ){ clearHistory(PGHDR_TO_HIST(pPg, pPager)); @@ -2816,7 +3002,7 @@ int sqlite3pager_commit(Pager *pPager){ return rc; } assert( pPager->journalOpen ); - rc = sqlite3pager_sync(pPager, 0); + rc = sqlite3pager_sync(pPager, 0, 0); if( rc!=SQLITE_OK ){ goto commit_abort; } @@ -2845,8 +3031,8 @@ commit_abort: */ int sqlite3pager_rollback(Pager *pPager){ int rc; - TRACE2("ROLLBACK %d\n", pPager->fd.h); - if( pPager->memDb ){ + TRACE2("ROLLBACK %d\n", PAGERID(pPager)); + if( MEMDB ){ PgHdr *p; for(p=pPager->pAll; p; p=p->pNextAll){ PgHistory *pHist; @@ -2860,9 +3046,9 @@ int sqlite3pager_rollback(Pager *pPager){ pHist = PGHDR_TO_HIST(p, pPager); if( pHist->pOrig ){ memcpy(PGHDR_TO_DATA(p), pHist->pOrig, pPager->pageSize); - TRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, pPager->fd.h); + TRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager)); }else{ - TRACE3("PAGE %d is clean on %d\n", p->pgno, pPager->fd.h); + TRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager)); } clearHistory(pHist); p->dirty = 0; @@ -2896,13 +3082,11 @@ int sqlite3pager_rollback(Pager *pPager){ return pager_errcode(pPager); } if( pPager->state==PAGER_RESERVED ){ - int rc2, rc3; + int rc2; rc = pager_reload_cache(pPager); - rc2 = pager_truncate(pPager, pPager->origDbSize); - rc3 = pager_unwritelock(pPager); + rc2 = pager_unwritelock(pPager); if( rc==SQLITE_OK ){ rc = rc2; - if( rc3 ) rc = rc3; } }else{ rc = pager_playback(pPager); @@ -2927,7 +3111,7 @@ int sqlite3pager_isreadonly(Pager *pPager){ ** This routine is used for testing and analysis only. */ int *sqlite3pager_stats(Pager *pPager){ - static int a[9]; + static int a[11]; a[0] = pPager->nRef; a[1] = pPager->nPage; a[2] = pPager->mxPage; @@ -2937,6 +3121,8 @@ int *sqlite3pager_stats(Pager *pPager){ a[6] = pPager->nHit; a[7] = pPager->nMiss; a[8] = pPager->nOvfl; + a[9] = pPager->nRead; + a[10] = pPager->nWrite; return a; } @@ -2952,8 +3138,8 @@ int sqlite3pager_stmt_begin(Pager *pPager){ char zTemp[SQLITE_TEMPNAME_SIZE]; assert( !pPager->stmtInUse ); assert( pPager->dbSize>=0 ); - TRACE2("STMT-BEGIN %d\n", pPager->fd.h); - if( pPager->memDb ){ + TRACE2("STMT-BEGIN %d\n", PAGERID(pPager)); + if( MEMDB ){ pPager->stmtInUse = 1; pPager->stmtSize = pPager->dbSize; return SQLITE_OK; @@ -3000,8 +3186,8 @@ stmt_begin_failed: int sqlite3pager_stmt_commit(Pager *pPager){ if( pPager->stmtInUse ){ PgHdr *pPg, *pNext; - TRACE2("STMT-COMMIT %d\n", pPager->fd.h); - if( !pPager->memDb ){ + TRACE2("STMT-COMMIT %d\n", PAGERID(pPager)); + if( !MEMDB ){ sqlite3OsSeek(&pPager->stfd, 0); /* sqlite3OsTruncate(&pPager->stfd, 0); */ sqliteFree( pPager->aInStmt ); @@ -3012,7 +3198,7 @@ int sqlite3pager_stmt_commit(Pager *pPager){ assert( pPg->inStmt ); pPg->inStmt = 0; pPg->pPrevStmt = pPg->pNextStmt = 0; - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); sqliteFree(pHist->pStmt); pHist->pStmt = 0; @@ -3032,8 +3218,8 @@ int sqlite3pager_stmt_commit(Pager *pPager){ int sqlite3pager_stmt_rollback(Pager *pPager){ int rc; if( pPager->stmtInUse ){ - TRACE2("STMT-ROLLBACK %d\n", pPager->fd.h); - if( pPager->memDb ){ + TRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager)); + if( MEMDB ){ PgHdr *pPg; for(pPg=pPager->pStmt; pPg; pPg=pPg->pNextStmt){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); @@ -3132,14 +3318,20 @@ static int pager_incr_changecounter(Pager *pPager){ ** ** Note that if zMaster==NULL, this does not overwrite a previous value ** passed to an sqlite3pager_sync() call. +** +** If parameter nTrunc is non-zero, then the pager file is truncated to +** nTrunc pages (this is used by auto-vacuum databases). */ -int sqlite3pager_sync(Pager *pPager, const char *zMaster){ +int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){ int rc = SQLITE_OK; + TRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", + pPager->zFilename, zMaster, nTrunc); + /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is a no-op. */ - if( pPager->state!=PAGER_SYNCED && !pPager->memDb && pPager->dirtyCache ){ + if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){ PgHdr *pPg; assert( pPager->journalOpen ); @@ -3152,12 +3344,38 @@ int sqlite3pager_sync(Pager *pPager, const char *zMaster){ if( !pPager->setMaster ){ rc = pager_incr_changecounter(pPager); if( rc!=SQLITE_OK ) goto sync_exit; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( nTrunc!=0 ){ + /* If this transaction has made the database smaller, then all pages + ** being discarded by the truncation must be written to the journal + ** file. + */ + Pgno i; + void *pPage; + for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){ + if( !(pPager->aInJournal[i/8] & (1<<(i&7))) ){ + rc = sqlite3pager_get(pPager, i, &pPage); + if( rc!=SQLITE_OK ) goto sync_exit; + rc = sqlite3pager_write(pPage); + sqlite3pager_unref(pPage); + if( rc!=SQLITE_OK ) goto sync_exit; + } + } + } +#endif rc = writeMasterJournal(pPager, zMaster); if( rc!=SQLITE_OK ) goto sync_exit; rc = syncJournal(pPager); if( rc!=SQLITE_OK ) goto sync_exit; } +#ifndef SQLITE_OMIT_AUTOVACUUM + if( nTrunc!=0 ){ + rc = sqlite3pager_truncate(pPager, nTrunc); + if( rc!=SQLITE_OK ) goto sync_exit; + } +#endif + /* Write all dirty pages to the database file */ pPg = pager_get_all_dirty_pages(pPager); rc = pager_write_pagelist(pPg); @@ -3175,6 +3393,102 @@ sync_exit: return rc; } +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Move the page identified by pData to location pgno in the file. +** +** There must be no references to the current page pgno. If current page +** pgno is not already in the rollback journal, it is not written there by +** by this routine. The same applies to the page pData refers to on entry to +** this routine. +** +** References to the page refered to by pData remain valid. Updating any +** meta-data associated with page pData (i.e. data stored in the nExtra bytes +** allocated along with the page) is the responsibility of the caller. +** +** A transaction must be active when this routine is called, however it is +** illegal to call this routine if a statment transaction is active. +*/ +int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ + PgHdr *pPg = DATA_TO_PGHDR(pData); + PgHdr *pPgOld; + int h; + Pgno needSyncPgno = 0; + + assert( !pPager->stmtInUse ); + assert( pPg->nRef>0 ); + + TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERID(pPager), pPg->pgno, pPg->needSync, pgno); + + if( pPg->needSync ){ + needSyncPgno = pPg->pgno; + assert( pPg->inJournal ); + assert( pPg->dirty ); + assert( pPager->needSync ); + } + + /* Unlink pPg from it's hash-chain */ + unlinkHashChain(pPager, pPg); + + /* If the cache contains a page with page-number pgno, remove it + ** from it's hash chain. Also, if the PgHdr.needSync was set for + ** page pgno before the 'move' operation, it needs to be retained + ** for the page moved there. + */ + pPgOld = pager_lookup(pPager, pgno); + if( pPgOld ){ + assert( pPgOld->nRef==0 ); + unlinkHashChain(pPager, pPgOld); + pPgOld->dirty = 0; + if( pPgOld->needSync ){ + assert( pPgOld->inJournal ); + pPg->inJournal = 1; + pPg->needSync = 1; + assert( pPager->needSync ); + } + } + + /* Change the page number for pPg and insert it into the new hash-chain. */ + pPg->pgno = pgno; + h = pager_hash(pgno); + if( pPager->aHash[h] ){ + assert( pPager->aHash[h]->pPrevHash==0 ); + pPager->aHash[h]->pPrevHash = pPg; + } + pPg->pNextHash = pPager->aHash[h]; + pPager->aHash[h] = pPg; + pPg->pPrevHash = 0; + + pPg->dirty = 1; + pPager->dirtyCache = 1; + + if( needSyncPgno ){ + /* If needSyncPgno is non-zero, then the journal file needs to be + ** sync()ed before any data is written to database file page needSyncPgno. + ** Currently, no such page exists in the page-cache and the + ** Pager.aInJournal bit has been set. This needs to be remedied by loading + ** the page into the pager-cache and setting the PgHdr.needSync flag. + ** + ** The sqlite3pager_get() call may cause the journal to sync. So make + ** sure the Pager.needSync flag is set too. + */ + int rc; + void *pNeedSync; + assert( pPager->needSync ); + rc = sqlite3pager_get(pPager, needSyncPgno, &pNeedSync); + if( rc!=SQLITE_OK ) return rc; + pPager->needSync = 1; + DATA_TO_PGHDR(pNeedSync)->needSync = 1; + DATA_TO_PGHDR(pNeedSync)->inJournal = 1; + DATA_TO_PGHDR(pNeedSync)->dirty = 1; + sqlite3pager_unref(pNeedSync); + } + + return SQLITE_OK; +} +#endif + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Return the current state of the file lock for the given pager. @@ -3190,7 +3504,7 @@ int sqlite3pager_lockstate(Pager *pPager){ } #endif -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG /* ** Print a listing of all referenced pages and their ref count. */ diff --git a/ext/pdo_sqlite/sqlite/src/pager.h b/ext/pdo_sqlite/sqlite/src/pager.h index 0231e27a93..a592b1944b 100644 --- a/ext/pdo_sqlite/sqlite/src/pager.h +++ b/ext/pdo_sqlite/sqlite/src/pager.h @@ -50,13 +50,21 @@ typedef unsigned int Pgno; */ typedef struct Pager Pager; +/* +** Allowed values for the flags parameter to sqlite3pager_open(). +** +** NOTE: This values must match the corresponding BTREE_ values in btree.h. +*/ +#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ +#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ + /* ** See source code comments for a detailed description of the following ** routines: */ int sqlite3pager_open(Pager **ppPager, const char *zFilename, - int nExtra, int useJournal); + int nExtra, int flags); void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler); void sqlite3pager_set_destructor(Pager*, void(*)(void*,int)); void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int)); @@ -76,7 +84,7 @@ int sqlite3pager_pagecount(Pager*); int sqlite3pager_truncate(Pager*,Pgno); int sqlite3pager_begin(void*, int exFlag); int sqlite3pager_commit(Pager*); -int sqlite3pager_sync(Pager*,const char *zMaster); +int sqlite3pager_sync(Pager*,const char *zMaster, Pgno); int sqlite3pager_rollback(Pager*); int sqlite3pager_isreadonly(Pager*); int sqlite3pager_stmt_begin(Pager*); @@ -91,6 +99,7 @@ const char *sqlite3pager_dirname(Pager*); const char *sqlite3pager_journalname(Pager*); int sqlite3pager_rename(Pager*, const char *zNewName); void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*); +int sqlite3pager_movepage(Pager*,void*,Pgno); #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) int sqlite3pager_lockstate(Pager*); diff --git a/ext/pdo_sqlite/sqlite/src/parse.c b/ext/pdo_sqlite/sqlite/src/parse.c index 1856c3ea97..bec7a0a433 100644 --- a/ext/pdo_sqlite/sqlite/src/parse.c +++ b/ext/pdo_sqlite/sqlite/src/parse.c @@ -1,10 +1,10 @@ -/* Driver template for the LEMON parser generator. +/* Driver template for the LEMON parser generator. ** The author disclaims copyright to this source code. */ /* First off, code is include which follows the "include" declaration ** in the input file. */ #include -#line 33 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 33 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" #include "sqliteInt.h" #include "parse.h" @@ -14,8 +14,8 @@ ** LIMIT clause of a SELECT statement. */ struct LimitVal { - int limit; /* The LIMIT value. -1 if there is no limit */ - int offset; /* The OFFSET. 0 if there is none */ + Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ + Expr *pOffset; /* The OFFSET expression. NULL if there is none */ }; /* @@ -43,7 +43,7 @@ struct TrigEvent { int a; IdList * b; }; */ struct AttachKey { int type; Token key; }; -#line 48 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 48 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/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. */ @@ -93,35 +93,35 @@ struct AttachKey { int type; Token key; }; ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 225 +#define YYNOCODE 239 #define YYACTIONTYPE unsigned short int #define sqlite3ParserTOKENTYPE Token typedef union { sqlite3ParserTOKENTYPE yy0; - struct {int value; int mask;} yy47; - TriggerStep* yy91; - Token yy98; - Select* yy107; - struct TrigEvent yy146; - ExprList* yy210; - Expr* yy258; - SrcList* yy259; + struct AttachKey yy40; + int yy60; + struct TrigEvent yy62; + struct {int value; int mask;} yy243; + struct LikeOp yy258; + ExprList* yy266; IdList* yy272; - int yy284; - struct AttachKey yy292; - struct LikeOp yy342; - struct LimitVal yy404; - int yy449; + Select* yy331; + struct LimitVal yy348; + Token yy406; + SrcList* yy427; + Expr* yy454; + TriggerStep* yy455; + int yy477; } YYMINORTYPE; #define YYSTACKDEPTH 100 #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 537 -#define YYNRULE 292 -#define YYERRORSYMBOL 130 -#define YYERRSYMDT yy449 +#define YYNSTATE 564 +#define YYNRULE 305 +#define YYERRORSYMBOL 141 +#define YYERRSYMDT yy477 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -175,430 +175,481 @@ typedef union { ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 257, 325, 255, 138, 140, 142, 144, 146, 148, 150, - /* 10 */ 152, 154, 156, 89, 87, 88, 159, 12, 4, 6, - /* 20 */ 158, 537, 38, 24, 830, 1, 536, 3, 329, 488, - /* 30 */ 534, 535, 319, 50, 124, 112, 160, 169, 174, 179, - /* 40 */ 168, 173, 134, 136, 128, 130, 126, 132, 138, 140, - /* 50 */ 142, 144, 146, 148, 150, 152, 154, 156, 26, 73, - /* 60 */ 384, 256, 39, 58, 64, 66, 299, 330, 612, 611, - /* 70 */ 351, 30, 92, 332, 326, 159, 13, 14, 353, 158, - /* 80 */ 5, 355, 361, 366, 499, 146, 148, 150, 152, 154, - /* 90 */ 156, 12, 369, 124, 112, 160, 169, 174, 179, 168, - /* 100 */ 173, 134, 136, 128, 130, 126, 132, 138, 140, 142, - /* 110 */ 144, 146, 148, 150, 152, 154, 156, 128, 130, 126, - /* 120 */ 132, 138, 140, 142, 144, 146, 148, 150, 152, 154, - /* 130 */ 156, 659, 353, 244, 62, 355, 361, 366, 79, 12, - /* 140 */ 63, 98, 96, 289, 159, 280, 369, 349, 158, 181, - /* 150 */ 13, 14, 27, 12, 546, 383, 32, 10, 368, 273, - /* 160 */ 515, 765, 124, 112, 160, 169, 174, 179, 168, 173, - /* 170 */ 134, 136, 128, 130, 126, 132, 138, 140, 142, 144, - /* 180 */ 146, 148, 150, 152, 154, 156, 810, 349, 47, 73, - /* 190 */ 222, 763, 223, 114, 246, 31, 32, 48, 13, 14, - /* 200 */ 74, 274, 252, 166, 175, 180, 275, 304, 49, 8, - /* 210 */ 255, 45, 13, 14, 159, 290, 350, 382, 158, 245, - /* 220 */ 441, 46, 378, 183, 247, 185, 186, 15, 16, 17, - /* 230 */ 73, 205, 124, 112, 160, 169, 174, 179, 168, 173, - /* 240 */ 134, 136, 128, 130, 126, 132, 138, 140, 142, 144, - /* 250 */ 146, 148, 150, 152, 154, 156, 542, 306, 438, 159, - /* 260 */ 98, 96, 332, 158, 272, 475, 447, 437, 12, 256, - /* 270 */ 288, 12, 304, 339, 287, 50, 77, 124, 112, 160, - /* 280 */ 169, 174, 179, 168, 173, 134, 136, 128, 130, 126, - /* 290 */ 132, 138, 140, 142, 144, 146, 148, 150, 152, 154, - /* 300 */ 156, 547, 36, 335, 39, 58, 64, 66, 299, 330, - /* 310 */ 35, 334, 291, 545, 114, 332, 114, 329, 12, 625, - /* 320 */ 353, 187, 306, 355, 361, 366, 422, 13, 14, 159, - /* 330 */ 13, 14, 184, 158, 369, 636, 188, 259, 188, 764, - /* 340 */ 91, 87, 88, 100, 87, 88, 219, 124, 112, 160, - /* 350 */ 169, 174, 179, 168, 173, 134, 136, 128, 130, 126, - /* 360 */ 132, 138, 140, 142, 144, 146, 148, 150, 152, 154, - /* 370 */ 156, 297, 282, 114, 292, 51, 237, 13, 14, 150, - /* 380 */ 152, 154, 156, 114, 12, 225, 53, 225, 159, 166, - /* 390 */ 175, 180, 158, 380, 303, 111, 433, 658, 69, 92, - /* 400 */ 379, 183, 92, 185, 186, 111, 124, 112, 160, 169, - /* 410 */ 174, 179, 168, 173, 134, 136, 128, 130, 126, 132, - /* 420 */ 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, - /* 430 */ 103, 230, 561, 159, 773, 12, 286, 158, 631, 534, - /* 440 */ 535, 105, 815, 13, 14, 166, 175, 180, 203, 808, - /* 450 */ 215, 124, 112, 160, 169, 174, 179, 168, 173, 134, - /* 460 */ 136, 128, 130, 126, 132, 138, 140, 142, 144, 146, - /* 470 */ 148, 150, 152, 154, 156, 2, 3, 183, 159, 185, - /* 480 */ 186, 813, 158, 43, 44, 569, 33, 633, 41, 348, - /* 490 */ 340, 413, 415, 414, 13, 14, 124, 112, 160, 169, - /* 500 */ 174, 179, 168, 173, 134, 136, 128, 130, 126, 132, - /* 510 */ 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, - /* 520 */ 249, 336, 697, 159, 337, 338, 183, 158, 185, 186, - /* 530 */ 56, 57, 183, 11, 185, 186, 183, 416, 185, 186, - /* 540 */ 402, 124, 112, 160, 169, 174, 179, 168, 173, 134, - /* 550 */ 136, 128, 130, 126, 132, 138, 140, 142, 144, 146, - /* 560 */ 148, 150, 152, 154, 156, 342, 87, 88, 159, 345, - /* 570 */ 87, 88, 158, 98, 96, 183, 404, 185, 186, 240, - /* 580 */ 9, 183, 92, 185, 186, 802, 124, 177, 160, 169, - /* 590 */ 174, 179, 168, 173, 134, 136, 128, 130, 126, 132, - /* 600 */ 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, - /* 610 */ 787, 341, 257, 159, 255, 255, 183, 158, 185, 186, - /* 620 */ 94, 95, 480, 518, 92, 307, 314, 316, 92, 548, - /* 630 */ 325, 171, 112, 160, 169, 174, 179, 168, 173, 134, - /* 640 */ 136, 128, 130, 126, 132, 138, 140, 142, 144, 146, - /* 650 */ 148, 150, 152, 154, 156, 255, 25, 486, 159, 482, - /* 660 */ 170, 358, 158, 19, 241, 242, 252, 266, 513, 267, - /* 670 */ 259, 553, 72, 256, 256, 402, 68, 244, 160, 169, - /* 680 */ 174, 179, 168, 173, 134, 136, 128, 130, 126, 132, - /* 690 */ 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, - /* 700 */ 207, 255, 72, 326, 780, 260, 68, 267, 514, 47, - /* 710 */ 189, 428, 388, 385, 256, 325, 259, 21, 48, 162, - /* 720 */ 395, 12, 114, 161, 516, 517, 195, 193, 294, 49, - /* 730 */ 207, 484, 209, 312, 191, 70, 71, 387, 246, 113, - /* 740 */ 189, 164, 165, 73, 198, 114, 363, 396, 114, 391, - /* 750 */ 73, 277, 529, 313, 436, 182, 195, 193, 72, 467, - /* 760 */ 256, 623, 68, 245, 191, 70, 71, 188, 163, 113, - /* 770 */ 188, 119, 120, 121, 122, 197, 114, 803, 691, 72, - /* 780 */ 13, 14, 92, 68, 73, 73, 207, 77, 326, 73, - /* 790 */ 199, 807, 99, 436, 452, 293, 189, 223, 474, 325, - /* 800 */ 309, 119, 120, 121, 122, 197, 423, 207, 221, 460, - /* 810 */ 434, 419, 195, 193, 418, 90, 224, 189, 77, 225, - /* 820 */ 191, 70, 71, 73, 442, 113, 420, 114, 325, 444, - /* 830 */ 372, 468, 114, 195, 193, 283, 325, 311, 310, 402, - /* 840 */ 470, 191, 70, 71, 114, 7, 113, 41, 460, 474, - /* 850 */ 18, 20, 22, 386, 296, 114, 457, 119, 120, 121, - /* 860 */ 122, 197, 766, 446, 521, 554, 123, 430, 444, 23, - /* 870 */ 531, 114, 326, 114, 114, 481, 114, 125, 119, 120, - /* 880 */ 121, 122, 197, 510, 72, 441, 114, 238, 68, 114, - /* 890 */ 508, 506, 114, 127, 114, 129, 131, 114, 133, 411, - /* 900 */ 412, 322, 114, 114, 114, 114, 407, 114, 135, 326, - /* 910 */ 660, 137, 207, 114, 139, 114, 141, 451, 114, 143, - /* 920 */ 114, 114, 189, 114, 145, 147, 149, 151, 114, 153, - /* 930 */ 489, 493, 437, 114, 114, 155, 479, 157, 195, 193, - /* 940 */ 167, 77, 176, 178, 114, 190, 191, 70, 71, 114, - /* 950 */ 192, 113, 114, 114, 114, 194, 196, 114, 691, 114, - /* 960 */ 269, 320, 343, 321, 344, 269, 204, 114, 359, 284, - /* 970 */ 321, 206, 114, 555, 216, 218, 220, 114, 364, 234, - /* 980 */ 321, 239, 660, 119, 120, 121, 122, 197, 373, 271, - /* 990 */ 321, 281, 114, 114, 367, 227, 227, 269, 431, 408, - /* 1000 */ 321, 503, 439, 44, 465, 473, 267, 471, 114, 77, - /* 1010 */ 402, 402, 402, 402, 455, 459, 265, 457, 402, 402, - /* 1020 */ 823, 417, 504, 507, 556, 471, 28, 29, 560, 37, - /* 1030 */ 472, 73, 34, 55, 40, 41, 42, 54, 59, 67, - /* 1040 */ 570, 571, 52, 75, 60, 78, 483, 485, 487, 491, - /* 1050 */ 61, 65, 76, 464, 495, 501, 101, 527, 77, 238, - /* 1060 */ 233, 235, 85, 93, 86, 80, 97, 238, 102, 81, - /* 1070 */ 104, 82, 108, 107, 109, 110, 83, 115, 497, 84, - /* 1080 */ 117, 116, 156, 172, 637, 217, 638, 118, 202, 226, - /* 1090 */ 639, 208, 106, 211, 227, 210, 213, 214, 212, 229, - /* 1100 */ 228, 231, 236, 223, 200, 243, 201, 251, 248, 250, - /* 1110 */ 254, 253, 232, 258, 261, 270, 264, 263, 262, 268, - /* 1120 */ 276, 278, 285, 295, 318, 279, 300, 303, 301, 305, - /* 1130 */ 333, 346, 298, 323, 327, 356, 357, 362, 370, 302, - /* 1140 */ 371, 53, 374, 394, 399, 354, 331, 375, 401, 409, - /* 1150 */ 308, 347, 315, 324, 406, 317, 405, 328, 795, 390, - /* 1160 */ 389, 392, 397, 410, 421, 800, 360, 381, 365, 393, - /* 1170 */ 398, 352, 376, 403, 801, 377, 400, 425, 426, 424, - /* 1180 */ 427, 429, 771, 432, 772, 435, 440, 698, 443, 794, - /* 1190 */ 445, 438, 809, 449, 699, 450, 453, 448, 454, 456, - /* 1200 */ 811, 458, 461, 462, 463, 469, 812, 814, 476, 630, - /* 1210 */ 478, 632, 779, 821, 490, 477, 690, 492, 494, 496, - /* 1220 */ 498, 693, 500, 505, 696, 509, 781, 511, 782, 783, - /* 1230 */ 466, 784, 785, 502, 512, 786, 520, 822, 519, 530, - /* 1240 */ 524, 824, 523, 825, 525, 528, 533, 828, 518, 518, - /* 1250 */ 518, 518, 518, 518, 522, 518, 526, 518, 518, 532, + /* 0 */ 263, 261, 261, 154, 124, 126, 128, 130, 132, 134, + /* 10 */ 136, 138, 140, 142, 350, 567, 145, 641, 261, 369, + /* 20 */ 144, 114, 116, 112, 118, 7, 124, 126, 128, 130, + /* 30 */ 132, 134, 136, 138, 140, 142, 136, 138, 140, 142, + /* 40 */ 110, 94, 146, 157, 162, 167, 156, 161, 120, 122, + /* 50 */ 114, 116, 112, 118, 9, 124, 126, 128, 130, 132, + /* 60 */ 134, 136, 138, 140, 142, 574, 223, 262, 262, 124, + /* 70 */ 126, 128, 130, 132, 134, 136, 138, 140, 142, 13, + /* 80 */ 96, 145, 13, 2, 262, 144, 4, 78, 371, 92, + /* 90 */ 10, 373, 380, 385, 132, 134, 136, 138, 140, 142, + /* 100 */ 75, 3, 562, 388, 296, 110, 94, 146, 157, 162, + /* 110 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 77, + /* 120 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, + /* 130 */ 145, 65, 573, 13, 144, 11, 371, 66, 292, 373, + /* 140 */ 380, 385, 870, 1, 563, 14, 15, 4, 14, 15, + /* 150 */ 172, 388, 51, 665, 110, 94, 146, 157, 162, 167, + /* 160 */ 156, 161, 120, 122, 114, 116, 112, 118, 72, 124, + /* 170 */ 126, 128, 130, 132, 134, 136, 138, 140, 142, 51, + /* 180 */ 37, 341, 40, 59, 67, 69, 305, 336, 107, 106, + /* 190 */ 108, 847, 572, 34, 338, 96, 366, 349, 13, 14, + /* 200 */ 15, 371, 12, 145, 373, 380, 385, 144, 564, 40, + /* 210 */ 59, 67, 69, 305, 336, 75, 388, 3, 562, 190, + /* 220 */ 345, 338, 44, 45, 95, 460, 802, 110, 94, 146, + /* 230 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, + /* 240 */ 118, 575, 124, 126, 128, 130, 132, 134, 136, 138, + /* 250 */ 140, 142, 20, 48, 800, 364, 362, 101, 102, 367, + /* 260 */ 499, 295, 49, 596, 14, 15, 191, 32, 33, 27, + /* 270 */ 148, 403, 96, 50, 147, 534, 46, 145, 494, 466, + /* 280 */ 456, 144, 580, 279, 36, 340, 47, 399, 309, 81, + /* 290 */ 368, 401, 75, 335, 398, 505, 176, 501, 150, 151, + /* 300 */ 197, 110, 94, 146, 157, 162, 167, 156, 161, 120, + /* 310 */ 122, 114, 116, 112, 118, 77, 124, 126, 128, 130, + /* 320 */ 132, 134, 136, 138, 140, 142, 149, 280, 258, 169, + /* 330 */ 96, 39, 281, 13, 298, 367, 96, 175, 22, 335, + /* 340 */ 28, 145, 188, 402, 33, 144, 217, 6, 5, 171, + /* 350 */ 75, 173, 174, 25, 176, 581, 75, 57, 58, 507, + /* 360 */ 235, 351, 356, 357, 265, 110, 94, 146, 157, 162, + /* 370 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 503, + /* 380 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, + /* 390 */ 457, 77, 243, 294, 48, 227, 236, 293, 297, 14, + /* 400 */ 15, 288, 96, 49, 217, 152, 222, 163, 168, 278, + /* 410 */ 24, 13, 687, 13, 50, 145, 518, 201, 152, 144, + /* 420 */ 163, 168, 75, 358, 582, 171, 176, 173, 174, 263, + /* 430 */ 171, 261, 173, 174, 354, 356, 357, 588, 211, 110, + /* 440 */ 94, 146, 157, 162, 167, 156, 161, 120, 122, 114, + /* 450 */ 116, 112, 118, 654, 124, 126, 128, 130, 132, 134, + /* 460 */ 136, 138, 140, 142, 303, 13, 688, 96, 250, 817, + /* 470 */ 96, 16, 17, 18, 246, 81, 216, 14, 15, 14, + /* 480 */ 15, 145, 13, 406, 435, 144, 13, 75, 487, 387, + /* 490 */ 75, 493, 248, 258, 235, 660, 358, 262, 310, 852, + /* 500 */ 171, 26, 173, 174, 253, 110, 94, 146, 157, 162, + /* 510 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 397, + /* 520 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, + /* 530 */ 229, 14, 15, 489, 250, 152, 252, 163, 168, 171, + /* 540 */ 839, 173, 174, 360, 361, 96, 145, 533, 14, 15, + /* 550 */ 144, 866, 14, 15, 801, 442, 312, 275, 255, 453, + /* 560 */ 850, 338, 251, 535, 536, 75, 662, 247, 13, 493, + /* 570 */ 110, 94, 146, 157, 162, 167, 156, 161, 120, 122, + /* 580 */ 114, 116, 112, 118, 845, 124, 126, 128, 130, 132, + /* 590 */ 134, 136, 138, 140, 142, 726, 96, 171, 96, 173, + /* 600 */ 174, 171, 252, 173, 174, 152, 583, 163, 168, 42, + /* 610 */ 720, 525, 96, 145, 441, 271, 75, 144, 75, 170, + /* 620 */ 302, 640, 91, 31, 358, 313, 320, 322, 251, 432, + /* 630 */ 434, 433, 75, 844, 14, 15, 176, 110, 94, 146, + /* 640 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, + /* 650 */ 118, 77, 124, 126, 128, 130, 132, 134, 136, 138, + /* 660 */ 140, 142, 171, 96, 173, 174, 331, 52, 171, 96, + /* 670 */ 173, 174, 96, 195, 213, 207, 29, 348, 145, 54, + /* 680 */ 310, 318, 144, 75, 455, 342, 217, 93, 83, 75, + /* 690 */ 30, 452, 75, 109, 587, 286, 111, 171, 265, 173, + /* 700 */ 174, 319, 110, 94, 146, 157, 162, 167, 156, 161, + /* 710 */ 120, 122, 114, 116, 112, 118, 77, 124, 126, 128, + /* 720 */ 130, 132, 134, 136, 138, 140, 142, 244, 96, 187, + /* 730 */ 96, 96, 810, 331, 214, 266, 215, 35, 312, 96, + /* 740 */ 96, 479, 328, 145, 623, 38, 327, 144, 75, 455, + /* 750 */ 75, 75, 113, 689, 115, 117, 315, 461, 426, 75, + /* 760 */ 75, 77, 463, 119, 121, 407, 325, 110, 165, 146, + /* 770 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, + /* 780 */ 118, 77, 124, 126, 128, 130, 132, 134, 136, 138, + /* 790 */ 140, 142, 42, 96, 96, 96, 96, 824, 273, 159, + /* 800 */ 415, 96, 410, 272, 96, 273, 479, 41, 145, 332, + /* 810 */ 537, 43, 144, 75, 75, 75, 75, 123, 125, 127, + /* 820 */ 129, 75, 465, 64, 75, 131, 53, 463, 133, 158, + /* 830 */ 317, 316, 265, 94, 146, 157, 162, 167, 156, 161, + /* 840 */ 120, 122, 114, 116, 112, 118, 219, 124, 126, 128, + /* 850 */ 130, 132, 134, 136, 138, 140, 142, 96, 689, 96, + /* 860 */ 96, 532, 96, 331, 299, 96, 215, 96, 96, 283, + /* 870 */ 96, 261, 219, 96, 145, 96, 840, 75, 144, 75, + /* 880 */ 75, 135, 75, 137, 139, 75, 141, 75, 75, 143, + /* 890 */ 75, 153, 155, 75, 164, 75, 376, 166, 56, 178, + /* 900 */ 146, 157, 162, 167, 156, 161, 120, 122, 114, 116, + /* 910 */ 112, 118, 652, 124, 126, 128, 130, 132, 134, 136, + /* 920 */ 138, 140, 142, 76, 96, 96, 96, 71, 438, 364, + /* 930 */ 362, 437, 96, 96, 96, 96, 331, 262, 233, 332, + /* 940 */ 96, 55, 331, 439, 75, 75, 75, 331, 180, 182, + /* 950 */ 184, 199, 75, 75, 75, 75, 196, 198, 208, 210, + /* 960 */ 75, 107, 106, 108, 212, 720, 326, 177, 327, 382, + /* 970 */ 430, 431, 107, 106, 108, 391, 548, 61, 96, 96, + /* 980 */ 449, 471, 458, 45, 183, 181, 300, 96, 476, 352, + /* 990 */ 96, 353, 179, 73, 74, 343, 346, 95, 75, 75, + /* 1000 */ 290, 96, 224, 240, 345, 275, 42, 75, 95, 76, + /* 1010 */ 75, 245, 332, 71, 277, 383, 275, 327, 332, 96, + /* 1020 */ 75, 75, 404, 332, 287, 386, 96, 392, 421, 327, + /* 1030 */ 101, 102, 103, 104, 105, 185, 189, 199, 96, 75, + /* 1040 */ 96, 101, 102, 427, 414, 60, 75, 107, 106, 108, + /* 1050 */ 474, 470, 486, 177, 77, 450, 421, 327, 75, 484, + /* 1060 */ 75, 273, 478, 436, 491, 492, 423, 490, 421, 421, + /* 1070 */ 183, 181, 421, 421, 483, 421, 77, 421, 179, 73, + /* 1080 */ 74, 476, 244, 95, 77, 81, 526, 860, 490, 421, + /* 1090 */ 689, 522, 62, 64, 500, 70, 597, 63, 523, 68, + /* 1100 */ 598, 76, 81, 79, 81, 71, 502, 504, 84, 80, + /* 1110 */ 506, 510, 244, 514, 239, 520, 101, 102, 103, 104, + /* 1120 */ 105, 185, 189, 77, 546, 241, 82, 558, 86, 199, + /* 1130 */ 85, 225, 90, 87, 97, 88, 99, 142, 89, 107, + /* 1140 */ 106, 108, 160, 98, 516, 177, 100, 218, 666, 667, + /* 1150 */ 668, 186, 209, 193, 192, 194, 200, 204, 203, 202, + /* 1160 */ 206, 205, 183, 181, 219, 220, 221, 226, 228, 232, + /* 1170 */ 179, 73, 74, 230, 233, 95, 234, 231, 237, 242, + /* 1180 */ 238, 215, 260, 249, 257, 276, 267, 254, 256, 259, + /* 1190 */ 264, 269, 270, 76, 274, 282, 301, 71, 219, 268, + /* 1200 */ 285, 291, 284, 306, 324, 307, 311, 308, 101, 102, + /* 1210 */ 103, 104, 105, 185, 189, 803, 355, 329, 375, 304, + /* 1220 */ 314, 199, 321, 337, 330, 365, 334, 372, 309, 333, + /* 1230 */ 323, 107, 106, 108, 344, 339, 347, 177, 374, 378, + /* 1240 */ 400, 359, 370, 377, 381, 379, 384, 389, 363, 390, + /* 1250 */ 393, 394, 396, 54, 183, 181, 289, 408, 395, 409, + /* 1260 */ 411, 413, 179, 73, 74, 412, 416, 95, 417, 420, + /* 1270 */ 428, 422, 832, 429, 443, 440, 444, 837, 838, 76, + /* 1280 */ 446, 445, 448, 71, 451, 808, 809, 459, 454, 447, + /* 1290 */ 418, 727, 728, 831, 464, 462, 846, 457, 469, 419, + /* 1300 */ 101, 102, 103, 104, 105, 185, 189, 199, 467, 468, + /* 1310 */ 472, 473, 475, 424, 848, 477, 480, 107, 106, 108, + /* 1320 */ 425, 482, 488, 177, 485, 849, 481, 495, 496, 851, + /* 1330 */ 659, 661, 816, 858, 497, 509, 511, 719, 513, 515, + /* 1340 */ 183, 181, 722, 517, 725, 519, 521, 524, 179, 73, + /* 1350 */ 74, 818, 528, 95, 530, 819, 820, 531, 538, 821, + /* 1360 */ 8, 822, 539, 823, 549, 19, 21, 23, 405, 541, + /* 1370 */ 542, 544, 543, 859, 547, 861, 862, 865, 545, 540, + /* 1380 */ 551, 867, 557, 555, 552, 550, 101, 102, 103, 104, + /* 1390 */ 105, 185, 189, 554, 560, 559, 561, 868, 529, 545, + /* 1400 */ 460, 545, 545, 545, 545, 527, 545, 553, 545, 545, + /* 1410 */ 545, 545, 556, 545, 545, 545, 545, 545, 545, 545, + /* 1420 */ 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, + /* 1430 */ 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, + /* 1440 */ 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, + /* 1450 */ 545, 545, 545, 508, 512, 456, 545, 545, 545, 498, + /* 1460 */ 545, 545, 545, 545, 81, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 24, 139, 26, 72, 73, 74, 75, 76, 77, 78, - /* 10 */ 79, 80, 81, 154, 155, 156, 40, 26, 135, 136, - /* 20 */ 44, 0, 158, 140, 131, 132, 133, 134, 164, 146, - /* 30 */ 9, 10, 170, 60, 58, 59, 60, 61, 62, 63, + /* 0 */ 24, 26, 26, 78, 79, 80, 81, 82, 83, 84, + /* 10 */ 85, 86, 87, 88, 22, 9, 40, 23, 26, 25, + /* 20 */ 44, 74, 75, 76, 77, 9, 79, 80, 81, 82, + /* 30 */ 83, 84, 85, 86, 87, 88, 85, 86, 87, 88, /* 40 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - /* 50 */ 74, 75, 76, 77, 78, 79, 80, 81, 22, 176, - /* 60 */ 24, 85, 89, 90, 91, 92, 93, 94, 23, 23, - /* 70 */ 25, 25, 213, 100, 212, 40, 85, 86, 87, 44, - /* 80 */ 9, 90, 91, 92, 201, 76, 77, 78, 79, 80, - /* 90 */ 81, 26, 101, 58, 59, 60, 61, 62, 63, 64, - /* 100 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - /* 110 */ 75, 76, 77, 78, 79, 80, 81, 68, 69, 70, - /* 120 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - /* 130 */ 81, 23, 87, 25, 29, 90, 91, 92, 179, 26, - /* 140 */ 35, 76, 77, 23, 40, 186, 101, 139, 44, 22, - /* 150 */ 85, 86, 144, 26, 9, 147, 148, 12, 159, 146, - /* 160 */ 95, 126, 58, 59, 60, 61, 62, 63, 64, 65, - /* 170 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 180 */ 76, 77, 78, 79, 80, 81, 17, 139, 18, 176, - /* 190 */ 23, 17, 25, 139, 86, 147, 148, 27, 85, 86, - /* 200 */ 146, 188, 189, 204, 205, 206, 193, 45, 38, 137, - /* 210 */ 26, 41, 85, 86, 40, 161, 168, 169, 44, 111, - /* 220 */ 51, 51, 60, 103, 111, 105, 106, 13, 14, 15, - /* 230 */ 176, 127, 58, 59, 60, 61, 62, 63, 64, 65, - /* 240 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 250 */ 76, 77, 78, 79, 80, 81, 9, 95, 58, 40, - /* 260 */ 76, 77, 100, 44, 22, 96, 97, 98, 26, 85, - /* 270 */ 104, 26, 45, 89, 108, 60, 107, 58, 59, 60, - /* 280 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - /* 290 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - /* 300 */ 81, 9, 87, 88, 89, 90, 91, 92, 93, 94, - /* 310 */ 157, 158, 23, 9, 139, 100, 139, 164, 26, 119, - /* 320 */ 87, 23, 95, 90, 91, 92, 21, 85, 86, 40, - /* 330 */ 85, 86, 104, 44, 101, 107, 161, 152, 161, 17, - /* 340 */ 154, 155, 156, 154, 155, 156, 127, 58, 59, 60, - /* 350 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - /* 360 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - /* 370 */ 81, 23, 187, 139, 199, 89, 199, 85, 86, 78, - /* 380 */ 79, 80, 81, 139, 26, 210, 100, 210, 40, 204, - /* 390 */ 205, 206, 44, 164, 165, 161, 91, 23, 22, 213, - /* 400 */ 171, 103, 213, 105, 106, 161, 58, 59, 60, 61, - /* 410 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 420 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 430 */ 196, 197, 9, 40, 129, 26, 78, 44, 9, 9, - /* 440 */ 10, 197, 9, 85, 86, 204, 205, 206, 126, 11, - /* 450 */ 128, 58, 59, 60, 61, 62, 63, 64, 65, 66, - /* 460 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 470 */ 77, 78, 79, 80, 81, 133, 134, 103, 40, 105, - /* 480 */ 106, 9, 44, 173, 174, 109, 149, 9, 95, 152, - /* 490 */ 153, 96, 97, 98, 85, 86, 58, 59, 60, 61, - /* 500 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 510 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 520 */ 111, 152, 9, 40, 155, 156, 103, 44, 105, 106, - /* 530 */ 13, 14, 103, 139, 105, 106, 103, 47, 105, 106, - /* 540 */ 139, 58, 59, 60, 61, 62, 63, 64, 65, 66, - /* 550 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 560 */ 77, 78, 79, 80, 81, 154, 155, 156, 40, 154, - /* 570 */ 155, 156, 44, 76, 77, 103, 175, 105, 106, 25, - /* 580 */ 138, 103, 213, 105, 106, 95, 58, 59, 60, 61, - /* 590 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 600 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 610 */ 9, 22, 24, 40, 26, 26, 103, 44, 105, 106, - /* 620 */ 121, 122, 20, 22, 213, 96, 97, 98, 213, 9, - /* 630 */ 139, 60, 59, 60, 61, 62, 63, 64, 65, 66, + /* 50 */ 74, 75, 76, 77, 148, 79, 80, 81, 82, 83, + /* 60 */ 84, 85, 86, 87, 88, 9, 25, 92, 92, 79, + /* 70 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 26, + /* 80 */ 150, 40, 26, 144, 92, 44, 147, 157, 94, 48, + /* 90 */ 149, 97, 98, 99, 83, 84, 85, 86, 87, 88, + /* 100 */ 170, 9, 10, 109, 174, 64, 65, 66, 67, 68, + /* 110 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 189, + /* 120 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 130 */ 40, 29, 9, 26, 44, 12, 94, 35, 85, 97, + /* 140 */ 98, 99, 142, 143, 144, 92, 93, 147, 92, 93, + /* 150 */ 112, 109, 66, 115, 64, 65, 66, 67, 68, 69, + /* 160 */ 70, 71, 72, 73, 74, 75, 76, 77, 22, 79, + /* 170 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 66, + /* 180 */ 94, 95, 96, 97, 98, 99, 100, 101, 60, 61, + /* 190 */ 62, 17, 9, 160, 108, 150, 163, 164, 26, 92, + /* 200 */ 93, 94, 150, 40, 97, 98, 99, 44, 0, 96, + /* 210 */ 97, 98, 99, 100, 101, 170, 109, 9, 10, 174, + /* 220 */ 92, 108, 186, 187, 96, 51, 136, 64, 65, 66, + /* 230 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 240 */ 77, 9, 79, 80, 81, 82, 83, 84, 85, 86, + /* 250 */ 87, 88, 149, 18, 17, 83, 84, 129, 130, 150, + /* 260 */ 20, 23, 27, 117, 92, 93, 221, 158, 159, 22, + /* 270 */ 40, 24, 150, 38, 44, 103, 41, 40, 104, 105, + /* 280 */ 106, 44, 9, 157, 168, 169, 51, 177, 178, 115, + /* 290 */ 181, 182, 170, 177, 184, 55, 174, 57, 68, 69, + /* 300 */ 137, 64, 65, 66, 67, 68, 69, 70, 71, 72, + /* 310 */ 73, 74, 75, 76, 77, 189, 79, 80, 81, 82, + /* 320 */ 83, 84, 85, 86, 87, 88, 96, 201, 202, 22, + /* 330 */ 150, 169, 206, 26, 212, 150, 150, 23, 149, 177, + /* 340 */ 155, 40, 23, 158, 159, 44, 224, 145, 146, 111, + /* 350 */ 170, 113, 114, 151, 174, 9, 170, 13, 14, 157, + /* 360 */ 174, 165, 166, 167, 163, 64, 65, 66, 67, 68, + /* 370 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 139, + /* 380 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 390 */ 64, 189, 212, 112, 18, 209, 210, 116, 23, 92, + /* 400 */ 93, 200, 150, 27, 224, 217, 218, 219, 220, 22, + /* 410 */ 149, 26, 23, 26, 38, 40, 214, 41, 217, 44, + /* 420 */ 219, 220, 170, 227, 9, 111, 174, 113, 114, 24, + /* 430 */ 111, 26, 113, 114, 165, 166, 167, 9, 137, 64, + /* 440 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 450 */ 75, 76, 77, 127, 79, 80, 81, 82, 83, 84, + /* 460 */ 85, 86, 87, 88, 23, 26, 23, 150, 25, 9, + /* 470 */ 150, 13, 14, 15, 25, 115, 224, 92, 93, 92, + /* 480 */ 93, 40, 26, 153, 47, 44, 26, 170, 128, 171, + /* 490 */ 170, 174, 201, 202, 174, 9, 227, 92, 45, 9, + /* 500 */ 111, 152, 113, 114, 119, 64, 65, 66, 67, 68, + /* 510 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 66, + /* 520 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 530 */ 210, 92, 93, 216, 25, 217, 93, 219, 220, 111, + /* 540 */ 103, 113, 114, 129, 130, 150, 40, 150, 92, 93, + /* 550 */ 44, 9, 92, 93, 17, 225, 103, 150, 119, 229, + /* 560 */ 9, 108, 119, 166, 167, 170, 9, 118, 26, 174, + /* 570 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + /* 580 */ 74, 75, 76, 77, 11, 79, 80, 81, 82, 83, + /* 590 */ 84, 85, 86, 87, 88, 9, 150, 111, 150, 113, + /* 600 */ 114, 111, 93, 113, 114, 217, 9, 219, 220, 103, + /* 610 */ 9, 216, 150, 40, 21, 208, 170, 44, 170, 157, + /* 620 */ 174, 23, 174, 25, 227, 104, 105, 106, 119, 104, + /* 630 */ 105, 106, 170, 11, 92, 93, 174, 64, 65, 66, /* 640 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 650 */ 77, 78, 79, 80, 81, 26, 141, 55, 40, 57, - /* 660 */ 89, 170, 44, 138, 110, 188, 189, 23, 67, 25, - /* 670 */ 152, 9, 22, 85, 85, 139, 26, 25, 60, 61, - /* 680 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 690 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 700 */ 50, 26, 22, 212, 9, 187, 26, 25, 139, 18, - /* 710 */ 60, 175, 20, 146, 85, 139, 152, 138, 27, 40, - /* 720 */ 146, 26, 139, 44, 155, 156, 76, 77, 78, 38, - /* 730 */ 50, 129, 41, 32, 84, 85, 86, 142, 86, 89, - /* 740 */ 60, 62, 63, 176, 161, 139, 170, 55, 139, 57, - /* 750 */ 176, 187, 123, 52, 146, 146, 76, 77, 22, 146, - /* 760 */ 85, 9, 26, 111, 84, 85, 86, 161, 89, 89, - /* 770 */ 161, 121, 122, 123, 124, 125, 139, 95, 9, 22, - /* 780 */ 85, 86, 213, 26, 176, 176, 50, 107, 212, 176, - /* 790 */ 207, 11, 25, 146, 25, 23, 60, 25, 161, 139, - /* 800 */ 99, 121, 122, 123, 124, 125, 211, 50, 199, 201, - /* 810 */ 215, 28, 76, 77, 31, 48, 210, 60, 107, 210, - /* 820 */ 84, 85, 86, 176, 216, 89, 43, 139, 139, 221, - /* 830 */ 170, 120, 139, 76, 77, 78, 139, 88, 89, 139, - /* 840 */ 203, 84, 85, 86, 139, 11, 89, 95, 201, 161, - /* 850 */ 16, 17, 18, 19, 161, 139, 139, 121, 122, 123, - /* 860 */ 124, 125, 126, 216, 30, 9, 161, 170, 221, 138, - /* 870 */ 36, 139, 212, 139, 139, 175, 139, 161, 121, 122, - /* 880 */ 123, 124, 125, 49, 22, 51, 139, 118, 26, 139, - /* 890 */ 56, 203, 139, 161, 139, 161, 161, 139, 161, 53, - /* 900 */ 54, 212, 139, 139, 139, 139, 126, 139, 161, 212, - /* 910 */ 24, 161, 50, 139, 161, 139, 161, 200, 139, 161, - /* 920 */ 139, 139, 60, 139, 161, 161, 161, 161, 139, 161, - /* 930 */ 96, 97, 98, 139, 139, 161, 102, 161, 76, 77, - /* 940 */ 161, 107, 161, 161, 139, 161, 84, 85, 86, 139, - /* 950 */ 161, 89, 139, 139, 139, 161, 161, 139, 9, 139, - /* 960 */ 139, 23, 23, 25, 25, 139, 161, 139, 23, 139, - /* 970 */ 25, 161, 139, 9, 161, 161, 161, 139, 23, 161, - /* 980 */ 25, 161, 95, 121, 122, 123, 124, 125, 23, 161, - /* 990 */ 25, 161, 139, 139, 161, 109, 109, 139, 23, 161, - /* 1000 */ 25, 146, 173, 174, 23, 23, 25, 25, 139, 107, - /* 1010 */ 139, 139, 139, 139, 161, 161, 195, 139, 139, 139, - /* 1020 */ 9, 195, 120, 23, 9, 25, 145, 23, 9, 139, - /* 1030 */ 161, 176, 150, 42, 159, 95, 33, 167, 46, 22, - /* 1040 */ 109, 109, 159, 177, 160, 178, 175, 175, 175, 175, - /* 1050 */ 159, 159, 176, 195, 175, 175, 113, 46, 107, 118, - /* 1060 */ 116, 115, 185, 214, 117, 180, 214, 118, 114, 181, - /* 1070 */ 25, 182, 94, 160, 26, 151, 183, 109, 200, 184, - /* 1080 */ 109, 139, 81, 89, 107, 126, 107, 139, 17, 139, - /* 1090 */ 107, 22, 198, 174, 109, 23, 139, 23, 25, 143, - /* 1100 */ 139, 198, 114, 25, 208, 190, 209, 111, 139, 139, - /* 1110 */ 143, 139, 160, 139, 191, 95, 22, 112, 192, 139, - /* 1120 */ 23, 191, 109, 23, 22, 192, 139, 165, 162, 139, - /* 1130 */ 167, 23, 159, 198, 198, 46, 22, 22, 46, 163, - /* 1140 */ 22, 100, 93, 24, 217, 139, 151, 139, 95, 39, - /* 1150 */ 166, 152, 166, 160, 220, 166, 219, 160, 11, 143, - /* 1160 */ 139, 139, 139, 37, 47, 95, 159, 169, 159, 143, - /* 1170 */ 143, 169, 162, 143, 95, 163, 218, 139, 143, 129, - /* 1180 */ 95, 22, 9, 159, 129, 11, 172, 119, 17, 9, - /* 1190 */ 9, 58, 17, 139, 119, 99, 139, 172, 67, 181, - /* 1200 */ 9, 67, 119, 139, 22, 22, 9, 9, 110, 9, - /* 1210 */ 181, 9, 9, 9, 110, 139, 9, 181, 172, 99, - /* 1220 */ 181, 9, 119, 22, 9, 139, 9, 139, 9, 9, - /* 1230 */ 202, 9, 9, 202, 143, 9, 23, 9, 139, 34, - /* 1240 */ 24, 9, 152, 9, 139, 152, 139, 9, 224, 224, - /* 1250 */ 224, 224, 224, 224, 222, 224, 223, 224, 224, 222, + /* 650 */ 77, 189, 79, 80, 81, 82, 83, 84, 85, 86, + /* 660 */ 87, 88, 111, 150, 113, 114, 150, 96, 111, 150, + /* 670 */ 113, 114, 150, 136, 212, 138, 156, 162, 40, 108, + /* 680 */ 45, 32, 44, 170, 157, 170, 224, 174, 192, 170, + /* 690 */ 23, 98, 170, 174, 9, 199, 174, 111, 163, 113, + /* 700 */ 114, 52, 64, 65, 66, 67, 68, 69, 70, 71, + /* 710 */ 72, 73, 74, 75, 76, 77, 189, 79, 80, 81, + /* 720 */ 82, 83, 84, 85, 86, 87, 88, 126, 150, 157, + /* 730 */ 150, 150, 139, 150, 23, 200, 25, 161, 103, 150, + /* 740 */ 150, 214, 226, 40, 23, 150, 25, 44, 170, 157, + /* 750 */ 170, 170, 174, 24, 174, 174, 107, 230, 136, 170, + /* 760 */ 170, 189, 235, 174, 174, 20, 183, 64, 65, 66, + /* 770 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 780 */ 77, 189, 79, 80, 81, 82, 83, 84, 85, 86, + /* 790 */ 87, 88, 103, 150, 150, 150, 150, 9, 25, 66, + /* 800 */ 55, 150, 57, 23, 150, 25, 214, 171, 40, 226, + /* 810 */ 22, 33, 44, 170, 170, 170, 170, 174, 174, 174, + /* 820 */ 174, 170, 230, 102, 170, 174, 171, 235, 174, 96, + /* 830 */ 95, 96, 163, 65, 66, 67, 68, 69, 70, 71, + /* 840 */ 72, 73, 74, 75, 76, 77, 117, 79, 80, 81, + /* 850 */ 82, 83, 84, 85, 86, 87, 88, 150, 103, 150, + /* 860 */ 150, 73, 150, 150, 23, 150, 25, 150, 150, 200, + /* 870 */ 150, 26, 117, 150, 40, 150, 103, 170, 44, 170, + /* 880 */ 170, 174, 170, 174, 174, 170, 174, 170, 170, 174, + /* 890 */ 170, 174, 174, 170, 174, 170, 183, 174, 42, 174, + /* 900 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 910 */ 76, 77, 9, 79, 80, 81, 82, 83, 84, 85, + /* 920 */ 86, 87, 88, 22, 150, 150, 150, 26, 28, 83, + /* 930 */ 84, 31, 150, 150, 150, 150, 150, 92, 26, 226, + /* 940 */ 150, 180, 150, 43, 170, 170, 170, 150, 174, 174, + /* 950 */ 174, 50, 170, 170, 170, 170, 174, 174, 174, 174, + /* 960 */ 170, 60, 61, 62, 174, 9, 23, 66, 25, 183, + /* 970 */ 53, 54, 60, 61, 62, 183, 131, 172, 150, 150, + /* 980 */ 183, 25, 186, 187, 83, 84, 85, 150, 150, 23, + /* 990 */ 150, 25, 91, 92, 93, 83, 84, 96, 170, 170, + /* 1000 */ 150, 150, 174, 174, 92, 150, 103, 170, 96, 22, + /* 1010 */ 170, 174, 226, 26, 174, 23, 150, 25, 226, 150, + /* 1020 */ 170, 170, 157, 226, 174, 174, 150, 23, 150, 25, + /* 1030 */ 129, 130, 131, 132, 133, 134, 135, 50, 150, 170, + /* 1040 */ 150, 129, 130, 174, 157, 46, 170, 60, 61, 62, + /* 1050 */ 174, 213, 157, 66, 189, 23, 150, 25, 170, 23, + /* 1060 */ 170, 25, 174, 208, 174, 23, 188, 25, 150, 150, + /* 1070 */ 83, 84, 150, 150, 208, 150, 189, 150, 91, 92, + /* 1080 */ 93, 150, 126, 96, 189, 115, 23, 9, 25, 150, + /* 1090 */ 9, 157, 171, 102, 188, 22, 117, 173, 128, 171, + /* 1100 */ 117, 22, 115, 190, 115, 26, 188, 188, 193, 189, + /* 1110 */ 188, 188, 126, 188, 124, 188, 129, 130, 131, 132, + /* 1120 */ 133, 134, 135, 189, 46, 123, 191, 188, 195, 50, + /* 1130 */ 194, 121, 125, 196, 117, 197, 117, 88, 198, 60, + /* 1140 */ 61, 62, 96, 150, 213, 66, 150, 150, 115, 115, + /* 1150 */ 115, 22, 136, 223, 222, 17, 22, 25, 187, 23, + /* 1160 */ 23, 150, 83, 84, 117, 150, 154, 122, 25, 101, + /* 1170 */ 91, 92, 93, 211, 26, 96, 162, 172, 211, 122, + /* 1180 */ 172, 25, 154, 203, 119, 103, 204, 150, 150, 150, + /* 1190 */ 150, 120, 22, 22, 150, 23, 23, 26, 117, 205, + /* 1200 */ 205, 117, 204, 150, 22, 175, 150, 176, 129, 130, + /* 1210 */ 131, 132, 133, 134, 135, 136, 23, 211, 22, 171, + /* 1220 */ 179, 50, 179, 162, 172, 163, 172, 150, 178, 211, + /* 1230 */ 179, 60, 61, 62, 170, 180, 170, 66, 46, 23, + /* 1240 */ 182, 228, 182, 173, 22, 171, 171, 46, 228, 22, + /* 1250 */ 100, 150, 176, 108, 83, 84, 85, 150, 175, 154, + /* 1260 */ 150, 24, 91, 92, 93, 154, 150, 96, 154, 103, + /* 1270 */ 39, 154, 11, 37, 139, 47, 150, 103, 103, 22, + /* 1280 */ 103, 154, 22, 26, 171, 9, 139, 185, 11, 150, + /* 1290 */ 231, 127, 127, 9, 9, 17, 17, 64, 107, 232, + /* 1300 */ 129, 130, 131, 132, 133, 134, 135, 50, 185, 150, + /* 1310 */ 150, 73, 194, 233, 9, 73, 127, 60, 61, 62, + /* 1320 */ 234, 22, 22, 66, 215, 9, 150, 118, 150, 9, + /* 1330 */ 9, 9, 9, 9, 194, 118, 194, 9, 185, 107, + /* 1340 */ 83, 84, 9, 194, 9, 127, 215, 22, 91, 92, + /* 1350 */ 93, 9, 150, 96, 150, 9, 9, 154, 150, 9, + /* 1360 */ 11, 9, 23, 9, 34, 16, 17, 18, 19, 236, + /* 1370 */ 163, 150, 24, 9, 163, 9, 9, 9, 237, 30, + /* 1380 */ 236, 9, 20, 154, 150, 36, 129, 130, 131, 132, + /* 1390 */ 133, 134, 135, 150, 140, 59, 150, 9, 49, 238, + /* 1400 */ 51, 238, 238, 238, 238, 56, 238, 58, 238, 238, + /* 1410 */ 238, 238, 63, 238, 238, 238, 238, 238, 238, 238, + /* 1420 */ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, + /* 1430 */ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, + /* 1440 */ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, + /* 1450 */ 238, 238, 238, 104, 105, 106, 238, 238, 238, 110, + /* 1460 */ 238, 238, 238, 238, 115, }; -#define YY_SHIFT_USE_DFLT (-70) +#define YY_SHIFT_USE_DFLT (-76) static const short yy_shift_ofst[] = { - /* 0 */ 430, 21, -70, 834, 71, -70, 247, 214, 145, 304, - /* 10 */ 292, 620, -70, -70, -70, -70, -70, -70, 145, 662, - /* 20 */ 145, 856, 145, 964, 36, 1015, 245, 46, 1004, 1019, - /* 30 */ -9, -70, 675, -70, 215, -70, 245, -27, -70, 940, - /* 40 */ -70, 1003, 170, -70, -70, -70, -70, -70, -70, -70, - /* 50 */ 286, 940, -70, 991, -70, 517, -70, -70, 992, 105, - /* 60 */ 940, -70, -70, -70, 940, -70, 1017, 862, 376, 650, - /* 70 */ 931, 932, 680, -70, 120, 951, -70, 166, -70, 554, - /* 80 */ 941, 946, 944, 943, 947, -70, 497, -70, -70, 767, - /* 90 */ 497, -70, 499, -70, -70, -70, 499, -70, -70, 497, - /* 100 */ -70, 954, 862, 1045, 862, 978, 105, -70, 1048, -70, - /* 110 */ -70, 483, 862, -70, 968, 245, 971, 245, -70, -70, - /* 120 */ -70, -70, -70, 618, 862, 573, 862, -69, 862, -69, - /* 130 */ 862, -69, 862, -69, 862, 49, 862, 49, 862, 9, - /* 140 */ 862, 9, 862, 9, 862, 9, 862, 301, 862, 301, - /* 150 */ 862, 1001, 862, 1001, 862, 1001, 862, -70, -70, -70, - /* 160 */ 679, -70, -70, -70, -70, -70, 862, 49, -70, 571, - /* 170 */ -70, 994, -70, -70, -70, 862, 528, 862, 49, -70, - /* 180 */ 127, 680, 298, 228, 977, 979, 983, -70, 483, 862, - /* 190 */ 618, 862, -70, 862, -70, 862, -70, 736, 35, 959, - /* 200 */ 322, 1071, -70, 862, 104, 862, 483, 1069, 691, 1072, - /* 210 */ -70, 1073, 245, 1074, -70, 862, 174, 862, 219, 862, - /* 220 */ 483, 167, -70, 862, -70, -70, 985, 245, -70, -70, - /* 230 */ 978, 105, -70, 862, 483, 988, 862, 1078, 862, 483, - /* 240 */ -70, -70, 652, -70, -70, -70, 113, -70, 409, -70, - /* 250 */ 996, -70, 242, 985, 588, -70, -70, 245, -70, -70, - /* 260 */ 1020, 1005, -70, 1094, 245, 644, -70, 245, -70, -70, - /* 270 */ 862, 483, 951, 374, 108, 1097, 588, 1020, 1005, -70, - /* 280 */ 757, -24, -70, -70, 1013, 358, -70, -70, -70, -70, - /* 290 */ 289, -70, 772, -70, 1100, -70, 348, 940, -70, 245, - /* 300 */ 1102, -70, 227, -70, 245, -70, 529, 701, -70, 749, - /* 310 */ -70, -70, -70, -70, 701, -70, 701, -70, 245, 938, - /* 320 */ -70, 245, 978, 105, -70, -70, 978, 105, -70, -70, - /* 330 */ 1048, -70, 991, -70, -70, 184, -70, -70, -70, -70, - /* 340 */ 589, 497, 939, -70, 497, 1108, -70, -70, -70, -70, - /* 350 */ 45, 233, -70, 245, -70, 1089, 1114, 245, 945, 940, - /* 360 */ -70, 1115, 245, 955, 940, -70, 862, 393, -70, 1092, - /* 370 */ 1118, 245, 965, 1049, 245, 1102, -70, 162, 1041, -70, - /* 380 */ -70, -70, -70, -70, 951, 423, 305, 692, 245, 985, - /* 390 */ -70, 245, 886, 1119, 951, 429, 245, 985, 783, 395, - /* 400 */ 1053, 245, 985, -70, 1110, 780, 1147, 862, 438, 1126, - /* 410 */ 846, -70, -70, 1070, 1079, 490, 245, 682, -70, -70, - /* 420 */ 1117, -70, -70, 1050, 245, 887, 1085, 245, 1159, 245, - /* 430 */ 975, 752, 1173, 1055, 1174, 169, 433, 200, 170, -70, - /* 440 */ 1068, 1075, 1171, 1180, 1181, 169, 1175, 1133, 245, 1096, - /* 450 */ 245, 769, 245, 1131, 862, 483, 1191, 1134, 862, 483, - /* 460 */ 1083, 245, 1182, 245, 981, -70, 711, 472, 1183, 862, - /* 470 */ 982, 862, 483, 1197, 483, 1098, 245, 949, 1198, 602, - /* 480 */ 245, 1200, 245, 1202, 245, 1203, 245, 1204, 478, 1104, - /* 490 */ 245, 949, 1207, 1133, 245, 1120, 245, 769, 1212, 1103, - /* 500 */ 245, 1182, 902, 513, 1201, 862, 1000, 1215, 695, 1217, - /* 510 */ 245, 985, 601, 65, 1219, 1220, 1222, 1223, 245, 1213, - /* 520 */ 1226, 1205, 675, 1216, 245, 1011, 1228, 629, 1232, 1234, - /* 530 */ -70, 1205, 245, 1238, -70, -70, -70, + /* 0 */ 92, 208, -76, -76, 1349, 6, 16, -76, 458, 123, + /* 10 */ 183, 56, 232, -76, -76, -76, -76, -76, -76, 123, + /* 20 */ 273, 123, 346, 123, 415, 247, 597, 456, 598, 667, + /* 30 */ 685, 107, -76, -25, -76, 86, -76, 456, 113, -76, + /* 40 */ 689, -76, 778, 235, -76, -76, -76, -76, -76, -76, + /* 50 */ -76, 571, 689, -76, 856, -76, 344, -76, -76, 999, + /* 60 */ 102, 689, 991, -76, -76, -76, -76, 689, -76, 1073, + /* 70 */ 1257, 146, 901, 979, 983, -76, 987, -76, 238, 989, + /* 80 */ -76, 281, -76, 449, 986, 1002, 990, 1010, 1007, -76, + /* 90 */ 1257, 41, 1257, 638, 1257, -76, 1017, 456, 1019, 456, + /* 100 */ -76, -76, -76, -76, -76, -76, -76, -76, -76, 834, + /* 110 */ 1257, 768, 1257, -10, 1257, -10, 1257, -10, 1257, -10, + /* 120 */ 1257, -53, 1257, -53, 1257, 11, 1257, 11, 1257, 11, + /* 130 */ 1257, 11, 1257, -49, 1257, -49, 1257, 1049, 1257, 1049, + /* 140 */ 1257, 1049, 1257, -76, -76, -76, 230, -76, -76, -76, + /* 150 */ -76, -76, 1257, -75, 1257, -10, -76, 733, -76, 1046, + /* 160 */ -76, -76, -76, 1257, 703, 1257, -53, -76, 307, 987, + /* 170 */ 314, 38, 1033, 1034, 1035, -76, 638, 1257, 834, 1257, + /* 180 */ -76, 1257, -76, 1257, -76, 1129, 989, 319, -76, 1079, + /* 190 */ 90, 1016, 537, 1138, -76, 1257, 163, 1257, 638, 1134, + /* 200 */ 376, 1136, -76, 1132, 456, 1137, -76, 1257, 237, 1257, + /* 210 */ 301, 1257, 638, 711, -76, 1257, -76, -76, 1047, 456, + /* 220 */ -76, -76, -76, 1257, 638, 1045, 1257, 1143, 1257, 1068, + /* 230 */ 102, -76, 1148, -76, -76, 638, 1068, 102, -76, 1257, + /* 240 */ 638, 1057, 1257, 1156, 1257, 638, -76, -76, 509, -76, + /* 250 */ -76, -76, 385, -76, 439, -76, 1065, -76, 387, 1047, + /* 260 */ 405, -76, -76, 456, -76, -76, 1082, 1071, -76, 1170, + /* 270 */ 456, 780, -76, 456, -76, -76, 1257, 638, 989, 389, + /* 280 */ 443, 1172, 405, 1082, 1071, -76, 1171, -24, -76, -76, + /* 290 */ 1084, 53, -76, -76, -76, -76, 375, -76, 841, -76, + /* 300 */ 1173, -76, 441, 689, -76, 456, 1182, -76, 635, -76, + /* 310 */ 456, -76, 521, 649, -76, 735, -76, -76, -76, -76, + /* 320 */ 649, -76, 649, -76, 456, 943, -76, 456, 1068, 102, + /* 330 */ -76, -76, 1068, 102, -76, -76, 1148, -76, 856, -76, + /* 340 */ -76, 912, -76, 128, -76, -76, 128, -76, -76, -8, + /* 350 */ 846, 966, -76, 846, 1193, -76, -76, -76, 414, -76, + /* 360 */ -76, -76, 414, -76, -76, -76, -76, -76, -6, 42, + /* 370 */ -76, 456, -76, 1192, 1196, 456, 721, 1216, 689, -76, + /* 380 */ 1222, 456, 992, 689, -76, 1257, 506, -76, 1201, 1227, + /* 390 */ 456, 1004, 1150, 456, 1182, -76, 453, 1145, -76, -76, + /* 400 */ -76, -76, -76, 989, 428, 593, 745, 456, 1047, -76, + /* 410 */ 456, 729, 1237, 989, 486, 456, 1047, 900, 525, 1166, + /* 420 */ 456, 1047, -76, 1231, 622, 1261, 1257, 573, 1236, 917, + /* 430 */ -76, -76, 1174, 1175, 437, 456, 773, -76, -76, 1228, + /* 440 */ -76, -76, 1135, 456, 755, 1177, 456, 1260, 456, 1032, + /* 450 */ 903, 1276, 1147, 1277, 174, 490, 326, 235, -76, 1164, + /* 460 */ 1165, 1278, 1284, 1285, 174, 1279, 1233, 456, 1191, 456, + /* 470 */ 956, 456, 1238, 1257, 638, 1305, 1242, 1257, 638, 1189, + /* 480 */ 456, 1299, 456, 1036, -76, 360, 551, 1300, 1257, 1042, + /* 490 */ 1257, 638, 1316, 638, 1209, 456, 601, 1320, 240, 456, + /* 500 */ 1321, 456, 1322, 456, 1323, 456, 1324, 557, 1217, 456, + /* 510 */ 601, 1328, 1233, 456, 1232, 456, 956, 1333, 1218, 456, + /* 520 */ 1299, 970, 586, 1325, 1257, 1063, 1335, 460, 1342, 456, + /* 530 */ 1047, 788, 172, 1346, 1347, 1350, 1352, 456, 1339, 1354, + /* 540 */ 1330, -25, 1348, 456, 1078, 1364, 845, 1366, 1367, -76, + /* 550 */ 1330, 456, 1368, 542, 1081, 1372, 1362, 456, 1336, 1254, + /* 560 */ 456, 1388, -76, -76, }; -#define YY_REDUCE_USE_DFLT (-142) +#define YY_REDUCE_USE_DFLT (-95) static const short yy_reduce_ofst[] = { - /* 0 */ -107, 342, -142, -117, -142, -142, -142, 72, 442, -142, - /* 10 */ 394, -142, -142, -142, -142, -142, -142, -142, 525, -142, - /* 20 */ 579, -142, 731, -142, 515, -142, 8, 881, -142, -142, - /* 30 */ 48, -142, 337, 882, 153, -142, 890, -136, -142, 875, - /* 40 */ -142, -142, 310, -142, -142, -142, -142, -142, -142, -142, - /* 50 */ -142, 883, -142, 870, -142, -142, -142, -142, -142, 884, - /* 60 */ 891, -142, -142, -142, 892, -142, -142, 693, -142, 175, - /* 70 */ -142, -142, 54, -142, 866, 876, -142, 867, -41, 885, - /* 80 */ 888, 889, 893, 895, 877, -142, -141, -142, -142, -142, - /* 90 */ 186, -142, 849, -142, -142, -142, 852, -142, -142, 189, - /* 100 */ -142, -142, 234, -142, 244, 894, 913, -142, 924, -142, - /* 110 */ -142, 241, 705, -142, -142, 942, -142, 948, -142, -142, - /* 120 */ -142, -142, -142, 241, 716, 241, 732, 241, 734, 241, - /* 130 */ 735, 241, 737, 241, 747, 241, 750, 241, 753, 241, - /* 140 */ 755, 241, 758, 241, 763, 241, 764, 241, 765, 241, - /* 150 */ 766, 241, 768, 241, 774, 241, 776, 241, -142, -142, - /* 160 */ -142, -142, -142, -142, -142, -142, 779, 241, -142, -142, - /* 170 */ -142, -142, -142, -142, -142, 781, 241, 782, 241, -142, - /* 180 */ 950, 609, 866, -142, -142, -142, -142, -142, 241, 784, - /* 190 */ 241, 789, 241, 794, 241, 795, 241, 583, 241, 896, - /* 200 */ 897, -142, -142, 805, 241, 810, 241, -142, 919, -142, - /* 210 */ -142, -142, 957, -142, -142, 813, 241, 814, 241, 815, - /* 220 */ 241, -142, -142, 606, -142, -142, 956, 961, -142, -142, - /* 230 */ 903, 952, -142, 818, 241, -142, 177, -142, 820, 241, - /* 240 */ -142, 477, 915, -142, -142, -142, 969, -142, 970, -142, - /* 250 */ -142, -142, 972, 967, 518, -142, -142, 974, -142, -142, - /* 260 */ 923, 926, -142, -142, 821, -142, -142, 980, -142, -142, - /* 270 */ 828, 241, 13, 866, 915, -142, 564, 930, 933, -142, - /* 280 */ 830, 185, -142, -142, -142, 942, -142, -142, -142, -142, - /* 290 */ 241, -142, -142, -142, -142, -142, 241, 973, -142, 987, - /* 300 */ 966, 976, 962, -142, 990, -142, -142, 984, -142, -142, - /* 310 */ -142, -142, -142, -142, 986, -142, 989, -142, -138, -142, - /* 320 */ -142, 689, 935, 993, -142, -142, 936, 997, -142, -142, - /* 330 */ 995, -142, 963, -142, -142, 369, -142, -142, -142, -142, - /* 340 */ 999, 411, -142, -142, 415, -142, -142, -142, -142, -142, - /* 350 */ 998, 1002, -142, 1006, -142, -142, -142, 491, -142, 1007, - /* 360 */ -142, -142, 576, -142, 1009, -142, 833, -1, -142, -142, - /* 370 */ -142, 660, -142, -142, 1008, 1010, 1012, 229, -142, -142, - /* 380 */ -142, -142, -142, -142, 567, 866, 595, -142, 1021, 1016, - /* 390 */ -142, 1022, 1026, -142, 574, 866, 1023, 1027, 927, 958, - /* 400 */ -142, 401, 1030, -142, 937, 934, -142, 838, 241, -142, - /* 410 */ -142, -142, -142, -142, -142, -142, 826, -142, -142, -142, - /* 420 */ -142, -142, -142, -142, 1038, 1035, -142, 536, -142, 697, - /* 430 */ -142, 1024, -142, -142, -142, 608, 866, 1014, 829, -142, - /* 440 */ -142, -142, -142, -142, -142, 647, -142, 1025, 1054, -142, - /* 450 */ 717, 1018, 1057, -142, 853, 241, -142, -142, 854, 241, - /* 460 */ -142, 1064, 1028, 858, -142, -142, 613, 866, -142, 637, - /* 470 */ -142, 869, 241, -142, 241, -142, 1076, 1029, -142, -142, - /* 480 */ 700, -142, 871, -142, 872, -142, 873, -142, 866, -142, - /* 490 */ 874, 1036, -142, 1046, 879, -142, 878, 1039, -142, -142, - /* 500 */ 880, 1031, 855, 866, -142, 688, -142, -142, 1086, -142, - /* 510 */ 1088, 1091, -142, 569, -142, -142, -142, -142, 1099, -142, - /* 520 */ -142, 1032, 1090, -142, 1105, 1033, -142, 1093, -142, -142, - /* 530 */ -142, 1037, 1107, -142, -142, -142, -142, + /* 0 */ 0, -61, -95, -95, 202, -95, -95, -95, -94, -59, + /* 10 */ -95, 52, -95, -95, -95, -95, -95, -95, -95, 103, + /* 20 */ -95, 189, -95, 261, -95, 349, -95, 185, 520, -95, + /* 30 */ -95, 109, -95, 33, 576, 116, -95, 595, 162, -95, + /* 40 */ 636, -95, -95, 36, -95, -95, -95, -95, -95, -95, + /* 50 */ -95, -95, 655, -95, 761, -95, -95, -95, -95, -95, + /* 60 */ 805, 921, 924, -95, -95, -95, -95, 928, -95, -95, + /* 70 */ 446, -95, 122, -95, -95, -95, -70, -95, 913, 920, + /* 80 */ -95, 935, 496, 915, 936, 933, 937, 938, 940, -95, + /* 90 */ 448, 388, 513, 388, 519, -95, -95, 993, -95, 996, + /* 100 */ -95, -95, -95, -95, -95, -95, -95, -95, -95, 388, + /* 110 */ 522, 388, 578, 388, 580, 388, 581, 388, 589, 388, + /* 120 */ 590, 388, 643, 388, 644, 388, 645, 388, 646, 388, + /* 130 */ 651, 388, 654, 388, 707, 388, 709, 388, 710, 388, + /* 140 */ 712, 388, 715, 388, -95, -95, -95, -95, -95, -95, + /* 150 */ -95, -95, 717, 188, 718, 388, -95, -95, -95, -95, + /* 160 */ -95, -95, -95, 720, 388, 723, 388, -95, 997, 462, + /* 170 */ 913, -95, -95, -95, -95, -95, 388, 725, 388, 774, + /* 180 */ 388, 775, 388, 776, 388, -95, 572, 913, -95, 45, + /* 190 */ 388, 932, 930, -95, -95, 782, 388, 783, 388, -95, + /* 200 */ 971, -95, -95, -95, 1011, -95, -95, 784, 388, 785, + /* 210 */ 388, 790, 388, -95, -95, 252, -95, -95, 1012, 1015, + /* 220 */ -95, -95, -95, 828, 388, -95, 186, -95, 320, 962, + /* 230 */ 1005, -95, 1014, -95, -95, 388, 967, 1008, -95, 829, + /* 240 */ 388, -95, 180, -95, 837, 388, -95, 291, 980, -95, + /* 250 */ -95, -95, 1037, -95, 1038, -95, -95, -95, 1039, 1028, + /* 260 */ 535, -95, -95, 1040, -95, -95, 982, 994, -95, -95, + /* 270 */ 407, -95, -95, 1044, -95, -95, 840, 388, 126, 913, + /* 280 */ 980, -95, 669, 998, 995, -95, 850, 201, -95, -95, + /* 290 */ -95, 993, -95, -95, -95, -95, 388, -95, -95, -95, + /* 300 */ -95, -95, 388, 1048, -95, 1053, 1030, 1031, 1050, -95, + /* 310 */ 1056, -95, -95, 1041, -95, -95, -95, -95, -95, -95, + /* 320 */ 1043, -95, 1051, -95, 583, -95, -95, 516, 1006, 1052, + /* 330 */ -95, -95, 1018, 1054, -95, -95, 1061, -95, 1055, -95, + /* 340 */ -95, 515, -95, 1064, -95, -95, 1066, -95, -95, 1062, + /* 350 */ 196, -95, -95, 269, -95, -95, -95, -95, 1013, -95, + /* 360 */ -95, -95, 1020, -95, -95, -95, -95, -95, 1058, 1060, + /* 370 */ -95, 1077, -95, -95, -95, 713, 1070, -95, 1074, -95, + /* 380 */ -95, 786, -95, 1075, -95, 851, 318, -95, -95, -95, + /* 390 */ 792, -95, -95, 1101, 1083, 1076, 110, -95, -95, -95, + /* 400 */ -95, -95, -95, 865, 913, 330, -95, 1107, 1105, -95, + /* 410 */ 1110, 1111, -95, 887, 913, 1116, 1114, 1059, 1067, -95, + /* 420 */ 878, 1117, -95, 1080, 1086, -95, 869, 388, -95, -95, + /* 430 */ -95, -95, -95, -95, -95, 855, -95, -95, -95, -95, + /* 440 */ -95, -95, -95, 1126, 1127, -95, 1139, -95, 797, -95, + /* 450 */ 1113, -95, -95, -95, 527, 913, 1102, 796, -95, -95, + /* 460 */ -95, -95, -95, -95, 592, -95, 1123, 1159, -95, 838, + /* 470 */ 1118, 1160, -95, 876, 388, -95, -95, 888, 388, -95, + /* 480 */ 1176, 1109, 866, -95, -95, 895, 913, -95, 317, -95, + /* 490 */ 890, 388, -95, 388, -95, 1178, 1140, -95, -95, 906, + /* 500 */ -95, 918, -95, 919, -95, 922, -95, 913, -95, 923, + /* 510 */ 1142, -95, 1153, 925, -95, 931, 1149, -95, -95, 927, + /* 520 */ 1131, 934, 913, -95, 395, -95, -95, 1202, -95, 1204, + /* 530 */ 1203, -95, 397, -95, -95, -95, -95, 1208, -95, -95, + /* 540 */ 1133, 1207, -95, 1221, 1141, -95, 1211, -95, -95, -95, + /* 550 */ 1144, 1234, -95, 1243, 1229, -95, -95, 939, -95, -95, + /* 560 */ 1246, -95, -95, -95, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 544, 544, 538, 829, 829, 540, 829, 549, 829, 829, - /* 10 */ 829, 829, 569, 570, 571, 550, 551, 552, 829, 829, - /* 20 */ 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, - /* 30 */ 829, 562, 572, 581, 564, 580, 829, 829, 582, 623, - /* 40 */ 588, 829, 829, 624, 627, 628, 629, 818, 819, 820, - /* 50 */ 829, 623, 589, 608, 606, 829, 609, 610, 829, 679, - /* 60 */ 623, 590, 677, 678, 623, 591, 829, 829, 708, 770, - /* 70 */ 714, 709, 829, 634, 829, 829, 635, 643, 645, 652, - /* 80 */ 691, 682, 684, 672, 686, 640, 793, 578, 579, 687, - /* 90 */ 793, 688, 829, 788, 790, 791, 829, 789, 792, 793, - /* 100 */ 689, 829, 829, 673, 829, 680, 679, 674, 829, 566, - /* 110 */ 681, 676, 829, 707, 829, 829, 710, 829, 711, 712, - /* 120 */ 713, 715, 716, 719, 829, 720, 829, 721, 829, 722, - /* 130 */ 829, 723, 829, 724, 829, 725, 829, 726, 829, 727, - /* 140 */ 829, 728, 829, 729, 829, 730, 829, 731, 829, 732, - /* 150 */ 829, 733, 829, 734, 829, 735, 829, 736, 737, 738, - /* 160 */ 829, 739, 740, 745, 753, 756, 829, 741, 742, 829, - /* 170 */ 743, 829, 746, 744, 752, 829, 829, 829, 754, 755, - /* 180 */ 829, 770, 829, 829, 829, 829, 829, 758, 769, 829, - /* 190 */ 747, 829, 748, 829, 749, 829, 750, 829, 829, 829, - /* 200 */ 829, 829, 760, 829, 829, 829, 761, 829, 829, 829, - /* 210 */ 816, 829, 829, 829, 817, 829, 829, 829, 829, 829, - /* 220 */ 762, 829, 757, 770, 767, 768, 660, 829, 661, 759, - /* 230 */ 680, 679, 675, 829, 685, 829, 770, 683, 829, 692, - /* 240 */ 644, 655, 653, 654, 663, 664, 829, 665, 829, 666, - /* 250 */ 829, 667, 829, 660, 651, 567, 568, 829, 649, 650, - /* 260 */ 669, 671, 656, 829, 829, 829, 670, 829, 704, 705, - /* 270 */ 829, 668, 655, 829, 829, 829, 651, 669, 671, 657, - /* 280 */ 829, 651, 646, 647, 829, 829, 648, 641, 642, 751, - /* 290 */ 829, 706, 829, 717, 829, 718, 829, 623, 592, 829, - /* 300 */ 774, 596, 593, 597, 829, 598, 829, 829, 599, 829, - /* 310 */ 602, 603, 604, 605, 829, 600, 829, 601, 829, 829, - /* 320 */ 775, 829, 680, 679, 776, 778, 680, 679, 777, 594, - /* 330 */ 829, 595, 608, 607, 583, 793, 584, 585, 586, 587, - /* 340 */ 573, 793, 829, 574, 793, 829, 575, 577, 576, 565, - /* 350 */ 829, 829, 613, 829, 616, 829, 829, 829, 829, 623, - /* 360 */ 617, 829, 829, 829, 623, 618, 829, 623, 619, 829, - /* 370 */ 829, 829, 829, 829, 829, 774, 596, 621, 829, 620, - /* 380 */ 622, 614, 615, 563, 829, 829, 559, 829, 829, 660, - /* 390 */ 557, 829, 829, 829, 829, 829, 829, 660, 799, 829, - /* 400 */ 829, 829, 660, 662, 804, 829, 829, 829, 829, 829, - /* 410 */ 829, 805, 806, 829, 829, 829, 829, 829, 796, 797, - /* 420 */ 829, 798, 558, 829, 829, 829, 829, 829, 829, 829, - /* 430 */ 829, 829, 829, 829, 829, 829, 829, 829, 829, 626, - /* 440 */ 829, 829, 829, 829, 829, 829, 829, 625, 829, 829, - /* 450 */ 829, 829, 829, 829, 829, 694, 829, 829, 829, 695, - /* 460 */ 829, 829, 702, 829, 829, 703, 829, 829, 829, 829, - /* 470 */ 829, 829, 700, 829, 701, 829, 829, 829, 829, 829, - /* 480 */ 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, - /* 490 */ 829, 829, 829, 625, 829, 829, 829, 829, 829, 829, - /* 500 */ 829, 702, 829, 829, 829, 829, 829, 829, 829, 829, - /* 510 */ 829, 660, 829, 793, 829, 829, 829, 829, 829, 829, - /* 520 */ 829, 827, 829, 829, 829, 829, 829, 829, 829, 829, - /* 530 */ 826, 827, 829, 829, 541, 543, 539, + /* 0 */ 570, 570, 565, 568, 869, 869, 869, 569, 576, 869, + /* 10 */ 869, 869, 869, 596, 597, 598, 577, 578, 579, 869, + /* 20 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + /* 30 */ 869, 869, 589, 599, 608, 591, 607, 869, 869, 609, + /* 40 */ 652, 615, 869, 869, 653, 656, 657, 658, 855, 856, + /* 50 */ 857, 869, 652, 616, 637, 635, 869, 638, 639, 869, + /* 60 */ 708, 652, 623, 617, 624, 706, 707, 652, 618, 869, + /* 70 */ 869, 738, 807, 744, 739, 735, 869, 663, 869, 869, + /* 80 */ 664, 672, 674, 681, 720, 711, 713, 701, 715, 669, + /* 90 */ 869, 716, 869, 717, 869, 737, 869, 869, 740, 869, + /* 100 */ 741, 742, 743, 745, 746, 747, 750, 751, 752, 753, + /* 110 */ 869, 754, 869, 755, 869, 756, 869, 757, 869, 758, + /* 120 */ 869, 759, 869, 760, 869, 761, 869, 762, 869, 763, + /* 130 */ 869, 764, 869, 765, 869, 766, 869, 767, 869, 768, + /* 140 */ 869, 769, 869, 770, 771, 772, 869, 773, 774, 781, + /* 150 */ 788, 791, 869, 776, 869, 775, 778, 869, 779, 869, + /* 160 */ 782, 780, 787, 869, 869, 869, 789, 790, 869, 807, + /* 170 */ 869, 869, 869, 869, 869, 794, 806, 869, 783, 869, + /* 180 */ 784, 869, 785, 869, 786, 869, 869, 869, 796, 869, + /* 190 */ 869, 869, 869, 869, 797, 869, 869, 869, 798, 869, + /* 200 */ 869, 869, 853, 869, 869, 869, 854, 869, 869, 869, + /* 210 */ 869, 869, 799, 869, 792, 807, 804, 805, 689, 869, + /* 220 */ 690, 795, 777, 869, 718, 869, 869, 702, 869, 709, + /* 230 */ 708, 703, 869, 593, 710, 705, 709, 708, 704, 869, + /* 240 */ 714, 869, 807, 712, 869, 721, 673, 684, 682, 683, + /* 250 */ 692, 693, 869, 694, 869, 695, 869, 696, 869, 689, + /* 260 */ 680, 594, 595, 869, 678, 679, 698, 700, 685, 869, + /* 270 */ 869, 869, 699, 869, 733, 734, 869, 697, 684, 869, + /* 280 */ 869, 869, 680, 698, 700, 686, 869, 680, 675, 676, + /* 290 */ 869, 869, 677, 670, 671, 793, 869, 736, 869, 748, + /* 300 */ 869, 749, 869, 652, 619, 869, 811, 625, 620, 626, + /* 310 */ 869, 627, 869, 869, 628, 869, 631, 632, 633, 634, + /* 320 */ 869, 629, 869, 630, 869, 869, 812, 869, 709, 708, + /* 330 */ 813, 815, 709, 708, 814, 621, 869, 622, 637, 636, + /* 340 */ 610, 869, 611, 869, 612, 744, 869, 613, 614, 600, + /* 350 */ 830, 869, 601, 830, 869, 602, 605, 606, 869, 825, + /* 360 */ 827, 828, 869, 826, 829, 604, 603, 592, 869, 869, + /* 370 */ 642, 869, 645, 869, 869, 869, 869, 869, 652, 646, + /* 380 */ 869, 869, 869, 652, 647, 869, 652, 648, 869, 869, + /* 390 */ 869, 869, 869, 869, 811, 625, 650, 869, 649, 651, + /* 400 */ 643, 644, 590, 869, 869, 586, 869, 869, 689, 584, + /* 410 */ 869, 869, 869, 869, 869, 869, 689, 836, 869, 869, + /* 420 */ 869, 689, 691, 841, 869, 869, 869, 869, 869, 869, + /* 430 */ 842, 843, 869, 869, 869, 869, 869, 833, 834, 869, + /* 440 */ 835, 585, 869, 869, 869, 869, 869, 869, 869, 869, + /* 450 */ 869, 869, 869, 869, 869, 869, 869, 869, 655, 869, + /* 460 */ 869, 869, 869, 869, 869, 869, 654, 869, 869, 869, + /* 470 */ 869, 869, 869, 869, 723, 869, 869, 869, 724, 869, + /* 480 */ 869, 731, 869, 869, 732, 869, 869, 869, 869, 869, + /* 490 */ 869, 729, 869, 730, 869, 869, 869, 869, 869, 869, + /* 500 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + /* 510 */ 869, 869, 654, 869, 869, 869, 869, 869, 869, 869, + /* 520 */ 731, 869, 869, 869, 869, 869, 869, 869, 869, 869, + /* 530 */ 689, 869, 830, 869, 869, 869, 869, 869, 869, 869, + /* 540 */ 864, 869, 869, 869, 869, 869, 869, 869, 869, 863, + /* 550 */ 864, 869, 869, 869, 869, 869, 869, 869, 869, 869, + /* 560 */ 869, 869, 571, 566, }; #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) @@ -672,6 +723,12 @@ static const YYCODETYPE yyFallback[] = { 26, /* TRIGGER => ID */ 26, /* VACUUM => ID */ 26, /* VIEW => ID */ + 26, /* REINDEX => ID */ + 26, /* RENAME => ID */ + 26, /* CDATE => ID */ + 26, /* CTIME => ID */ + 26, /* CTIMESTAMP => ID */ + 26, /* ALTER => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* NOT => nothing */ @@ -686,6 +743,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* LE => nothing */ 0, /* LT => nothing */ 0, /* GE => nothing */ + 0, /* ESCAPE => nothing */ 0, /* BITAND => nothing */ 0, /* BITOR => nothing */ 0, /* LSHIFT => nothing */ @@ -709,6 +767,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* CHECK => nothing */ 0, /* REFERENCES => nothing */ 0, /* COLLATE => nothing */ + 0, /* AUTOINCR => nothing */ 0, /* ON => nothing */ 0, /* DELETE => nothing */ 0, /* UPDATE => nothing */ @@ -738,12 +797,15 @@ static const YYCODETYPE yyFallback[] = { 0, /* INTEGER => nothing */ 0, /* FLOAT => nothing */ 0, /* BLOB => nothing */ + 0, /* REGISTER => nothing */ 0, /* VARIABLE => nothing */ + 0, /* EXISTS => nothing */ 0, /* CASE => nothing */ 0, /* WHEN => nothing */ 0, /* THEN => nothing */ 0, /* ELSE => nothing */ 0, /* INDEX => nothing */ + 0, /* TO => nothing */ }; #endif /* YYFALLBACK */ @@ -828,16 +890,18 @@ static const char *const yyTokenName[] = { "LIKE", "MATCH", "KEY", "OF", "OFFSET", "PRAGMA", "RAISE", "REPLACE", "RESTRICT", "ROW", "STATEMENT", "TRIGGER", - "VACUUM", "VIEW", "OR", "AND", - "NOT", "IS", "BETWEEN", "IN", - "ISNULL", "NOTNULL", "NE", "EQ", - "GT", "LE", "LT", "GE", - "BITAND", "BITOR", "LSHIFT", "RSHIFT", - "PLUS", "MINUS", "STAR", "SLASH", - "REM", "CONCAT", "UMINUS", "UPLUS", - "BITNOT", "STRING", "JOIN_KW", "CONSTRAINT", - "DEFAULT", "NULL", "PRIMARY", "UNIQUE", - "CHECK", "REFERENCES", "COLLATE", "ON", + "VACUUM", "VIEW", "REINDEX", "RENAME", + "CDATE", "CTIME", "CTIMESTAMP", "ALTER", + "OR", "AND", "NOT", "IS", + "BETWEEN", "IN", "ISNULL", "NOTNULL", + "NE", "EQ", "GT", "LE", + "LT", "GE", "ESCAPE", "BITAND", + "BITOR", "LSHIFT", "RSHIFT", "PLUS", + "MINUS", "STAR", "SLASH", "REM", + "CONCAT", "UMINUS", "UPLUS", "BITNOT", + "STRING", "JOIN_KW", "CONSTRAINT", "DEFAULT", + "NULL", "PRIMARY", "UNIQUE", "CHECK", + "REFERENCES", "COLLATE", "AUTOINCR", "ON", "DELETE", "UPDATE", "INSERT", "SET", "DEFERRABLE", "FOREIGN", "DROP", "UNION", "ALL", "INTERSECT", "EXCEPT", "SELECT", @@ -845,31 +909,33 @@ static const char *const yyTokenName[] = { "USING", "ORDER", "BY", "GROUP", "HAVING", "LIMIT", "WHERE", "INTO", "VALUES", "INTEGER", "FLOAT", "BLOB", - "VARIABLE", "CASE", "WHEN", "THEN", - "ELSE", "INDEX", "error", "input", - "cmdlist", "ecmd", "explain", "cmdx", - "cmd", "transtype", "trans_opt", "nm", - "create_table", "create_table_args", "temp", "dbnm", - "columnlist", "conslist_opt", "select", "column", - "columnid", "type", "carglist", "id", - "ids", "typename", "signed", "plus_num", - "minus_num", "carg", "ccons", "onconf", - "sortorder", "expr", "idxlist_opt", "refargs", - "defer_subclause", "refarg", "refact", "init_deferred_pred_opt", - "conslist", "tcons", "idxlist", "defer_subclause_opt", - "orconf", "resolvetype", "raisetype", "fullname", - "oneselect", "multiselect_op", "distinct", "selcollist", - "from", "where_opt", "groupby_opt", "having_opt", - "orderby_opt", "limit_opt", "sclp", "as", - "seltablist", "stl_prefix", "joinop", "on_opt", - "using_opt", "seltablist_paren", "joinop2", "inscollist", - "sortlist", "sortitem", "collate", "exprlist", - "setlist", "insert_cmd", "inscollist_opt", "itemlist", - "likeop", "between_op", "in_op", "case_operand", - "case_exprlist", "case_else", "expritem", "uniqueflag", - "idxitem", "plus_opt", "number", "trigger_decl", - "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", - "when_clause", "trigger_cmd", "database_kw_opt", "key_opt", + "REGISTER", "VARIABLE", "EXISTS", "CASE", + "WHEN", "THEN", "ELSE", "INDEX", + "TO", "error", "input", "cmdlist", + "ecmd", "cmdx", "cmd", "explain", + "transtype", "trans_opt", "nm", "create_table", + "create_table_args", "temp", "dbnm", "columnlist", + "conslist_opt", "select", "column", "columnid", + "type", "carglist", "id", "ids", + "typename", "signed", "plus_num", "minus_num", + "carg", "ccons", "term", "onconf", + "sortorder", "autoinc", "expr", "idxlist_opt", + "refargs", "defer_subclause", "refarg", "refact", + "init_deferred_pred_opt", "conslist", "tcons", "idxlist", + "defer_subclause_opt", "orconf", "resolvetype", "raisetype", + "fullname", "oneselect", "multiselect_op", "distinct", + "selcollist", "from", "where_opt", "groupby_opt", + "having_opt", "orderby_opt", "limit_opt", "sclp", + "as", "seltablist", "stl_prefix", "joinop", + "on_opt", "using_opt", "seltablist_paren", "joinop2", + "inscollist", "sortlist", "sortitem", "collate", + "exprlist", "setlist", "insert_cmd", "inscollist_opt", + "itemlist", "likeop", "escape", "between_op", + "in_op", "case_operand", "case_exprlist", "case_else", + "expritem", "uniqueflag", "idxitem", "plus_opt", + "number", "trigger_decl", "trigger_cmd_list", "trigger_time", + "trigger_event", "foreach_clause", "when_clause", "trigger_cmd", + "database_kw_opt", "key_opt", }; #endif /* NDEBUG */ @@ -880,11 +946,11 @@ static const char *const yyRuleName[] = { /* 0 */ "input ::= cmdlist", /* 1 */ "cmdlist ::= cmdlist ecmd", /* 2 */ "cmdlist ::= ecmd", - /* 3 */ "ecmd ::= explain cmdx SEMI", + /* 3 */ "cmdx ::= cmd", /* 4 */ "ecmd ::= SEMI", - /* 5 */ "cmdx ::= cmd", - /* 6 */ "explain ::= EXPLAIN", - /* 7 */ "explain ::=", + /* 5 */ "ecmd ::= explain cmdx SEMI", + /* 6 */ "explain ::=", + /* 7 */ "explain ::= EXPLAIN", /* 8 */ "cmd ::= BEGIN transtype trans_opt", /* 9 */ "trans_opt ::=", /* 10 */ "trans_opt ::= TRANSACTION", @@ -924,251 +990,264 @@ static const char *const yyRuleName[] = { /* 44 */ "carglist ::=", /* 45 */ "carg ::= CONSTRAINT nm ccons", /* 46 */ "carg ::= ccons", - /* 47 */ "carg ::= DEFAULT ids", - /* 48 */ "carg ::= DEFAULT plus_num", - /* 49 */ "carg ::= DEFAULT minus_num", - /* 50 */ "carg ::= DEFAULT NULL", + /* 47 */ "carg ::= DEFAULT term", + /* 48 */ "carg ::= DEFAULT PLUS term", + /* 49 */ "carg ::= DEFAULT MINUS term", + /* 50 */ "carg ::= DEFAULT id", /* 51 */ "ccons ::= NULL onconf", /* 52 */ "ccons ::= NOT NULL onconf", - /* 53 */ "ccons ::= PRIMARY KEY sortorder onconf", + /* 53 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", /* 54 */ "ccons ::= UNIQUE onconf", /* 55 */ "ccons ::= CHECK LP expr RP onconf", /* 56 */ "ccons ::= REFERENCES nm idxlist_opt refargs", /* 57 */ "ccons ::= defer_subclause", /* 58 */ "ccons ::= COLLATE id", - /* 59 */ "refargs ::=", - /* 60 */ "refargs ::= refargs refarg", - /* 61 */ "refarg ::= MATCH nm", - /* 62 */ "refarg ::= ON DELETE refact", - /* 63 */ "refarg ::= ON UPDATE refact", - /* 64 */ "refarg ::= ON INSERT refact", - /* 65 */ "refact ::= SET NULL", - /* 66 */ "refact ::= SET DEFAULT", - /* 67 */ "refact ::= CASCADE", - /* 68 */ "refact ::= RESTRICT", - /* 69 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", - /* 70 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", - /* 71 */ "init_deferred_pred_opt ::=", - /* 72 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", - /* 73 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", - /* 74 */ "conslist_opt ::=", - /* 75 */ "conslist_opt ::= COMMA conslist", - /* 76 */ "conslist ::= conslist COMMA tcons", - /* 77 */ "conslist ::= conslist tcons", - /* 78 */ "conslist ::= tcons", - /* 79 */ "tcons ::= CONSTRAINT nm", - /* 80 */ "tcons ::= PRIMARY KEY LP idxlist RP onconf", - /* 81 */ "tcons ::= UNIQUE LP idxlist RP onconf", - /* 82 */ "tcons ::= CHECK expr onconf", - /* 83 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", - /* 84 */ "defer_subclause_opt ::=", - /* 85 */ "defer_subclause_opt ::= defer_subclause", - /* 86 */ "onconf ::=", - /* 87 */ "onconf ::= ON CONFLICT resolvetype", - /* 88 */ "orconf ::=", - /* 89 */ "orconf ::= OR resolvetype", - /* 90 */ "resolvetype ::= raisetype", - /* 91 */ "resolvetype ::= IGNORE", - /* 92 */ "resolvetype ::= REPLACE", - /* 93 */ "cmd ::= DROP TABLE fullname", - /* 94 */ "cmd ::= CREATE temp VIEW nm dbnm AS select", - /* 95 */ "cmd ::= DROP VIEW fullname", - /* 96 */ "cmd ::= select", - /* 97 */ "select ::= oneselect", - /* 98 */ "select ::= select multiselect_op oneselect", - /* 99 */ "multiselect_op ::= UNION", - /* 100 */ "multiselect_op ::= UNION ALL", - /* 101 */ "multiselect_op ::= INTERSECT", - /* 102 */ "multiselect_op ::= EXCEPT", - /* 103 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", - /* 104 */ "distinct ::= DISTINCT", - /* 105 */ "distinct ::= ALL", - /* 106 */ "distinct ::=", - /* 107 */ "sclp ::= selcollist COMMA", - /* 108 */ "sclp ::=", - /* 109 */ "selcollist ::= sclp expr as", - /* 110 */ "selcollist ::= sclp STAR", - /* 111 */ "selcollist ::= sclp nm DOT STAR", - /* 112 */ "as ::= AS nm", - /* 113 */ "as ::= ids", - /* 114 */ "as ::=", - /* 115 */ "from ::=", - /* 116 */ "from ::= FROM seltablist", - /* 117 */ "stl_prefix ::= seltablist joinop", - /* 118 */ "stl_prefix ::=", - /* 119 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt", - /* 120 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt", - /* 121 */ "seltablist_paren ::= select", - /* 122 */ "seltablist_paren ::= seltablist", - /* 123 */ "dbnm ::=", - /* 124 */ "dbnm ::= DOT nm", - /* 125 */ "fullname ::= nm dbnm", - /* 126 */ "joinop ::= COMMA", - /* 127 */ "joinop ::= JOIN", - /* 128 */ "joinop ::= JOIN_KW JOIN", - /* 129 */ "joinop ::= JOIN_KW nm JOIN", - /* 130 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 131 */ "on_opt ::= ON expr", - /* 132 */ "on_opt ::=", - /* 133 */ "using_opt ::= USING LP inscollist RP", - /* 134 */ "using_opt ::=", - /* 135 */ "orderby_opt ::=", - /* 136 */ "orderby_opt ::= ORDER BY sortlist", - /* 137 */ "sortlist ::= sortlist COMMA sortitem collate sortorder", - /* 138 */ "sortlist ::= sortitem collate sortorder", - /* 139 */ "sortitem ::= expr", - /* 140 */ "sortorder ::= ASC", - /* 141 */ "sortorder ::= DESC", - /* 142 */ "sortorder ::=", - /* 143 */ "collate ::=", - /* 144 */ "collate ::= COLLATE id", - /* 145 */ "groupby_opt ::=", - /* 146 */ "groupby_opt ::= GROUP BY exprlist", - /* 147 */ "having_opt ::=", - /* 148 */ "having_opt ::= HAVING expr", - /* 149 */ "limit_opt ::=", - /* 150 */ "limit_opt ::= LIMIT signed", - /* 151 */ "limit_opt ::= LIMIT signed OFFSET signed", - /* 152 */ "limit_opt ::= LIMIT signed COMMA signed", - /* 153 */ "cmd ::= DELETE FROM fullname where_opt", - /* 154 */ "where_opt ::=", - /* 155 */ "where_opt ::= WHERE expr", - /* 156 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", - /* 157 */ "setlist ::= setlist COMMA nm EQ expr", - /* 158 */ "setlist ::= nm EQ expr", - /* 159 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", - /* 160 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", - /* 161 */ "insert_cmd ::= INSERT orconf", - /* 162 */ "insert_cmd ::= REPLACE", - /* 163 */ "itemlist ::= itemlist COMMA expr", - /* 164 */ "itemlist ::= expr", - /* 165 */ "inscollist_opt ::=", - /* 166 */ "inscollist_opt ::= LP inscollist RP", - /* 167 */ "inscollist ::= inscollist COMMA nm", - /* 168 */ "inscollist ::= nm", - /* 169 */ "expr ::= LP expr RP", - /* 170 */ "expr ::= NULL", - /* 171 */ "expr ::= ID", - /* 172 */ "expr ::= JOIN_KW", - /* 173 */ "expr ::= nm DOT nm", - /* 174 */ "expr ::= nm DOT nm DOT nm", - /* 175 */ "expr ::= INTEGER", - /* 176 */ "expr ::= FLOAT", - /* 177 */ "expr ::= STRING", - /* 178 */ "expr ::= BLOB", - /* 179 */ "expr ::= VARIABLE", - /* 180 */ "expr ::= ID LP exprlist RP", - /* 181 */ "expr ::= ID LP STAR RP", - /* 182 */ "expr ::= expr AND expr", - /* 183 */ "expr ::= expr OR expr", - /* 184 */ "expr ::= expr LT expr", - /* 185 */ "expr ::= expr GT expr", - /* 186 */ "expr ::= expr LE expr", - /* 187 */ "expr ::= expr GE expr", - /* 188 */ "expr ::= expr NE expr", - /* 189 */ "expr ::= expr EQ expr", - /* 190 */ "expr ::= expr BITAND expr", - /* 191 */ "expr ::= expr BITOR expr", - /* 192 */ "expr ::= expr LSHIFT expr", - /* 193 */ "expr ::= expr RSHIFT expr", - /* 194 */ "expr ::= expr PLUS expr", - /* 195 */ "expr ::= expr MINUS expr", - /* 196 */ "expr ::= expr STAR expr", - /* 197 */ "expr ::= expr SLASH expr", - /* 198 */ "expr ::= expr REM expr", - /* 199 */ "expr ::= expr CONCAT expr", - /* 200 */ "likeop ::= LIKE", - /* 201 */ "likeop ::= GLOB", - /* 202 */ "likeop ::= NOT LIKE", - /* 203 */ "likeop ::= NOT GLOB", - /* 204 */ "expr ::= expr likeop expr", - /* 205 */ "expr ::= expr ISNULL", - /* 206 */ "expr ::= expr IS NULL", - /* 207 */ "expr ::= expr NOTNULL", - /* 208 */ "expr ::= expr NOT NULL", - /* 209 */ "expr ::= expr IS NOT NULL", - /* 210 */ "expr ::= NOT expr", - /* 211 */ "expr ::= BITNOT expr", - /* 212 */ "expr ::= MINUS expr", - /* 213 */ "expr ::= PLUS expr", - /* 214 */ "expr ::= LP select RP", - /* 215 */ "between_op ::= BETWEEN", - /* 216 */ "between_op ::= NOT BETWEEN", - /* 217 */ "expr ::= expr between_op expr AND expr", - /* 218 */ "in_op ::= IN", - /* 219 */ "in_op ::= NOT IN", - /* 220 */ "expr ::= expr in_op LP exprlist RP", - /* 221 */ "expr ::= expr in_op LP select RP", - /* 222 */ "expr ::= expr in_op nm dbnm", - /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 225 */ "case_exprlist ::= WHEN expr THEN expr", - /* 226 */ "case_else ::= ELSE expr", - /* 227 */ "case_else ::=", - /* 228 */ "case_operand ::= expr", - /* 229 */ "case_operand ::=", - /* 230 */ "exprlist ::= exprlist COMMA expritem", - /* 231 */ "exprlist ::= expritem", - /* 232 */ "expritem ::= expr", - /* 233 */ "expritem ::=", - /* 234 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON fullname LP idxlist RP onconf", - /* 235 */ "uniqueflag ::= UNIQUE", - /* 236 */ "uniqueflag ::=", - /* 237 */ "idxlist_opt ::=", - /* 238 */ "idxlist_opt ::= LP idxlist RP", - /* 239 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", - /* 240 */ "idxlist ::= idxitem collate sortorder", - /* 241 */ "idxitem ::= nm", - /* 242 */ "cmd ::= DROP INDEX fullname", - /* 243 */ "cmd ::= VACUUM", - /* 244 */ "cmd ::= VACUUM nm", - /* 245 */ "cmd ::= PRAGMA nm dbnm EQ nm", - /* 246 */ "cmd ::= PRAGMA nm dbnm EQ ON", - /* 247 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", - /* 248 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 249 */ "cmd ::= PRAGMA nm dbnm LP nm RP", - /* 250 */ "cmd ::= PRAGMA nm dbnm", - /* 251 */ "plus_num ::= plus_opt number", - /* 252 */ "minus_num ::= MINUS number", - /* 253 */ "number ::= INTEGER", - /* 254 */ "number ::= FLOAT", - /* 255 */ "plus_opt ::= PLUS", - /* 256 */ "plus_opt ::=", - /* 257 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", - /* 258 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 259 */ "trigger_time ::= BEFORE", - /* 260 */ "trigger_time ::= AFTER", - /* 261 */ "trigger_time ::= INSTEAD OF", - /* 262 */ "trigger_time ::=", - /* 263 */ "trigger_event ::= DELETE", - /* 264 */ "trigger_event ::= INSERT", - /* 265 */ "trigger_event ::= UPDATE", - /* 266 */ "trigger_event ::= UPDATE OF inscollist", - /* 267 */ "foreach_clause ::=", - /* 268 */ "foreach_clause ::= FOR EACH ROW", - /* 269 */ "foreach_clause ::= FOR EACH STATEMENT", - /* 270 */ "when_clause ::=", - /* 271 */ "when_clause ::= WHEN expr", - /* 272 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", - /* 273 */ "trigger_cmd_list ::=", - /* 274 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 276 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 277 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 278 */ "trigger_cmd ::= select", - /* 279 */ "expr ::= RAISE LP IGNORE RP", - /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 281 */ "raisetype ::= ROLLBACK", - /* 282 */ "raisetype ::= ABORT", - /* 283 */ "raisetype ::= FAIL", - /* 284 */ "cmd ::= DROP TRIGGER fullname", - /* 285 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", - /* 286 */ "key_opt ::=", - /* 287 */ "key_opt ::= KEY ids", - /* 288 */ "key_opt ::= KEY BLOB", - /* 289 */ "database_kw_opt ::= DATABASE", - /* 290 */ "database_kw_opt ::=", - /* 291 */ "cmd ::= DETACH database_kw_opt nm", + /* 59 */ "autoinc ::=", + /* 60 */ "autoinc ::= AUTOINCR", + /* 61 */ "refargs ::=", + /* 62 */ "refargs ::= refargs refarg", + /* 63 */ "refarg ::= MATCH nm", + /* 64 */ "refarg ::= ON DELETE refact", + /* 65 */ "refarg ::= ON UPDATE refact", + /* 66 */ "refarg ::= ON INSERT refact", + /* 67 */ "refact ::= SET NULL", + /* 68 */ "refact ::= SET DEFAULT", + /* 69 */ "refact ::= CASCADE", + /* 70 */ "refact ::= RESTRICT", + /* 71 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 72 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 73 */ "init_deferred_pred_opt ::=", + /* 74 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 75 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 76 */ "conslist_opt ::=", + /* 77 */ "conslist_opt ::= COMMA conslist", + /* 78 */ "conslist ::= conslist COMMA tcons", + /* 79 */ "conslist ::= conslist tcons", + /* 80 */ "conslist ::= tcons", + /* 81 */ "tcons ::= CONSTRAINT nm", + /* 82 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", + /* 83 */ "tcons ::= UNIQUE LP idxlist RP onconf", + /* 84 */ "tcons ::= CHECK expr onconf", + /* 85 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", + /* 86 */ "defer_subclause_opt ::=", + /* 87 */ "defer_subclause_opt ::= defer_subclause", + /* 88 */ "onconf ::=", + /* 89 */ "onconf ::= ON CONFLICT resolvetype", + /* 90 */ "orconf ::=", + /* 91 */ "orconf ::= OR resolvetype", + /* 92 */ "resolvetype ::= raisetype", + /* 93 */ "resolvetype ::= IGNORE", + /* 94 */ "resolvetype ::= REPLACE", + /* 95 */ "cmd ::= DROP TABLE fullname", + /* 96 */ "cmd ::= CREATE temp VIEW nm dbnm AS select", + /* 97 */ "cmd ::= DROP VIEW fullname", + /* 98 */ "cmd ::= select", + /* 99 */ "select ::= oneselect", + /* 100 */ "select ::= select multiselect_op oneselect", + /* 101 */ "multiselect_op ::= UNION", + /* 102 */ "multiselect_op ::= UNION ALL", + /* 103 */ "multiselect_op ::= INTERSECT", + /* 104 */ "multiselect_op ::= EXCEPT", + /* 105 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 106 */ "distinct ::= DISTINCT", + /* 107 */ "distinct ::= ALL", + /* 108 */ "distinct ::=", + /* 109 */ "sclp ::= selcollist COMMA", + /* 110 */ "sclp ::=", + /* 111 */ "selcollist ::= sclp expr as", + /* 112 */ "selcollist ::= sclp STAR", + /* 113 */ "selcollist ::= sclp nm DOT STAR", + /* 114 */ "as ::= AS nm", + /* 115 */ "as ::= ids", + /* 116 */ "as ::=", + /* 117 */ "from ::=", + /* 118 */ "from ::= FROM seltablist", + /* 119 */ "stl_prefix ::= seltablist joinop", + /* 120 */ "stl_prefix ::=", + /* 121 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt", + /* 122 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt", + /* 123 */ "seltablist_paren ::= select", + /* 124 */ "seltablist_paren ::= seltablist", + /* 125 */ "dbnm ::=", + /* 126 */ "dbnm ::= DOT nm", + /* 127 */ "fullname ::= nm dbnm", + /* 128 */ "joinop ::= COMMA", + /* 129 */ "joinop ::= JOIN", + /* 130 */ "joinop ::= JOIN_KW JOIN", + /* 131 */ "joinop ::= JOIN_KW nm JOIN", + /* 132 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 133 */ "on_opt ::= ON expr", + /* 134 */ "on_opt ::=", + /* 135 */ "using_opt ::= USING LP inscollist RP", + /* 136 */ "using_opt ::=", + /* 137 */ "orderby_opt ::=", + /* 138 */ "orderby_opt ::= ORDER BY sortlist", + /* 139 */ "sortlist ::= sortlist COMMA sortitem collate sortorder", + /* 140 */ "sortlist ::= sortitem collate sortorder", + /* 141 */ "sortitem ::= expr", + /* 142 */ "sortorder ::= ASC", + /* 143 */ "sortorder ::= DESC", + /* 144 */ "sortorder ::=", + /* 145 */ "collate ::=", + /* 146 */ "collate ::= COLLATE id", + /* 147 */ "groupby_opt ::=", + /* 148 */ "groupby_opt ::= GROUP BY exprlist", + /* 149 */ "having_opt ::=", + /* 150 */ "having_opt ::= HAVING expr", + /* 151 */ "limit_opt ::=", + /* 152 */ "limit_opt ::= LIMIT expr", + /* 153 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 154 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 155 */ "cmd ::= DELETE FROM fullname where_opt", + /* 156 */ "where_opt ::=", + /* 157 */ "where_opt ::= WHERE expr", + /* 158 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", + /* 159 */ "setlist ::= setlist COMMA nm EQ expr", + /* 160 */ "setlist ::= nm EQ expr", + /* 161 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", + /* 162 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", + /* 163 */ "insert_cmd ::= INSERT orconf", + /* 164 */ "insert_cmd ::= REPLACE", + /* 165 */ "itemlist ::= itemlist COMMA expr", + /* 166 */ "itemlist ::= expr", + /* 167 */ "inscollist_opt ::=", + /* 168 */ "inscollist_opt ::= LP inscollist RP", + /* 169 */ "inscollist ::= inscollist COMMA nm", + /* 170 */ "inscollist ::= nm", + /* 171 */ "expr ::= term", + /* 172 */ "expr ::= LP expr RP", + /* 173 */ "term ::= NULL", + /* 174 */ "expr ::= ID", + /* 175 */ "expr ::= JOIN_KW", + /* 176 */ "expr ::= nm DOT nm", + /* 177 */ "expr ::= nm DOT nm DOT nm", + /* 178 */ "term ::= INTEGER", + /* 179 */ "term ::= FLOAT", + /* 180 */ "term ::= STRING", + /* 181 */ "expr ::= BLOB", + /* 182 */ "expr ::= REGISTER", + /* 183 */ "expr ::= VARIABLE", + /* 184 */ "expr ::= ID LP exprlist RP", + /* 185 */ "expr ::= ID LP STAR RP", + /* 186 */ "term ::= CTIME", + /* 187 */ "term ::= CDATE", + /* 188 */ "term ::= CTIMESTAMP", + /* 189 */ "expr ::= expr AND expr", + /* 190 */ "expr ::= expr OR expr", + /* 191 */ "expr ::= expr LT expr", + /* 192 */ "expr ::= expr GT expr", + /* 193 */ "expr ::= expr LE expr", + /* 194 */ "expr ::= expr GE expr", + /* 195 */ "expr ::= expr NE expr", + /* 196 */ "expr ::= expr EQ expr", + /* 197 */ "expr ::= expr BITAND expr", + /* 198 */ "expr ::= expr BITOR expr", + /* 199 */ "expr ::= expr LSHIFT expr", + /* 200 */ "expr ::= expr RSHIFT expr", + /* 201 */ "expr ::= expr PLUS expr", + /* 202 */ "expr ::= expr MINUS expr", + /* 203 */ "expr ::= expr STAR expr", + /* 204 */ "expr ::= expr SLASH expr", + /* 205 */ "expr ::= expr REM expr", + /* 206 */ "expr ::= expr CONCAT expr", + /* 207 */ "likeop ::= LIKE", + /* 208 */ "likeop ::= GLOB", + /* 209 */ "likeop ::= NOT LIKE", + /* 210 */ "likeop ::= NOT GLOB", + /* 211 */ "escape ::= ESCAPE expr", + /* 212 */ "escape ::=", + /* 213 */ "expr ::= expr likeop expr escape", + /* 214 */ "expr ::= expr ISNULL", + /* 215 */ "expr ::= expr IS NULL", + /* 216 */ "expr ::= expr NOTNULL", + /* 217 */ "expr ::= expr NOT NULL", + /* 218 */ "expr ::= expr IS NOT NULL", + /* 219 */ "expr ::= NOT expr", + /* 220 */ "expr ::= BITNOT expr", + /* 221 */ "expr ::= MINUS expr", + /* 222 */ "expr ::= PLUS expr", + /* 223 */ "between_op ::= BETWEEN", + /* 224 */ "between_op ::= NOT BETWEEN", + /* 225 */ "expr ::= expr between_op expr AND expr", + /* 226 */ "in_op ::= IN", + /* 227 */ "in_op ::= NOT IN", + /* 228 */ "expr ::= expr in_op LP exprlist RP", + /* 229 */ "expr ::= LP select RP", + /* 230 */ "expr ::= expr in_op LP select RP", + /* 231 */ "expr ::= expr in_op nm dbnm", + /* 232 */ "expr ::= EXISTS LP select RP", + /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 235 */ "case_exprlist ::= WHEN expr THEN expr", + /* 236 */ "case_else ::= ELSE expr", + /* 237 */ "case_else ::=", + /* 238 */ "case_operand ::= expr", + /* 239 */ "case_operand ::=", + /* 240 */ "exprlist ::= exprlist COMMA expritem", + /* 241 */ "exprlist ::= expritem", + /* 242 */ "expritem ::= expr", + /* 243 */ "expritem ::=", + /* 244 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf", + /* 245 */ "uniqueflag ::= UNIQUE", + /* 246 */ "uniqueflag ::=", + /* 247 */ "idxlist_opt ::=", + /* 248 */ "idxlist_opt ::= LP idxlist RP", + /* 249 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", + /* 250 */ "idxlist ::= idxitem collate sortorder", + /* 251 */ "idxitem ::= nm", + /* 252 */ "cmd ::= DROP INDEX fullname", + /* 253 */ "cmd ::= VACUUM", + /* 254 */ "cmd ::= VACUUM nm", + /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nm", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ ON", + /* 257 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", + /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 259 */ "cmd ::= PRAGMA nm dbnm LP nm RP", + /* 260 */ "cmd ::= PRAGMA nm dbnm", + /* 261 */ "plus_num ::= plus_opt number", + /* 262 */ "minus_num ::= MINUS number", + /* 263 */ "number ::= INTEGER", + /* 264 */ "number ::= FLOAT", + /* 265 */ "plus_opt ::= PLUS", + /* 266 */ "plus_opt ::=", + /* 267 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", + /* 268 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 269 */ "trigger_time ::= BEFORE", + /* 270 */ "trigger_time ::= AFTER", + /* 271 */ "trigger_time ::= INSTEAD OF", + /* 272 */ "trigger_time ::=", + /* 273 */ "trigger_event ::= DELETE", + /* 274 */ "trigger_event ::= INSERT", + /* 275 */ "trigger_event ::= UPDATE", + /* 276 */ "trigger_event ::= UPDATE OF inscollist", + /* 277 */ "foreach_clause ::=", + /* 278 */ "foreach_clause ::= FOR EACH ROW", + /* 279 */ "foreach_clause ::= FOR EACH STATEMENT", + /* 280 */ "when_clause ::=", + /* 281 */ "when_clause ::= WHEN expr", + /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", + /* 283 */ "trigger_cmd_list ::=", + /* 284 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", + /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", + /* 286 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", + /* 287 */ "trigger_cmd ::= DELETE FROM nm where_opt", + /* 288 */ "trigger_cmd ::= select", + /* 289 */ "expr ::= RAISE LP IGNORE RP", + /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 291 */ "raisetype ::= ROLLBACK", + /* 292 */ "raisetype ::= ABORT", + /* 293 */ "raisetype ::= FAIL", + /* 294 */ "cmd ::= DROP TRIGGER fullname", + /* 295 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", + /* 296 */ "key_opt ::=", + /* 297 */ "key_opt ::= KEY ids", + /* 298 */ "key_opt ::= KEY BLOB", + /* 299 */ "database_kw_opt ::= DATABASE", + /* 300 */ "database_kw_opt ::=", + /* 301 */ "cmd ::= DETACH database_kw_opt nm", + /* 302 */ "cmd ::= REINDEX", + /* 303 */ "cmd ::= REINDEX nm dbnm", + /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", }; #endif /* NDEBUG */ @@ -1226,63 +1305,72 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ - case 146: - case 176: - case 193: -#line 303 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3SelectDelete((yypminor->yy107));} -#line 1236 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 161: - case 181: - case 183: - case 191: - case 197: - case 210: -#line 552 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3ExprDelete((yypminor->yy258));} -#line 1246 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 157: + case 189: + case 206: +#line 325 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3SelectDelete((yypminor->yy331));} +#line 1315 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 162: case 170: - case 179: - case 182: - case 184: - case 186: + case 174: + case 194: case 196: - case 199: - case 200: - case 203: - case 208: -#line 744 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3ExprListDelete((yypminor->yy210));} -#line 1261 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 204: + case 210: + case 224: +#line 584 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3ExprDelete((yypminor->yy454));} +#line 1326 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 175: - case 180: - case 188: - case 189: -#line 428 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3SrcListDelete((yypminor->yy259));} -#line 1269 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; + case 183: case 192: case 195: + case 197: + case 199: + case 209: + case 212: + case 213: + case 216: + case 222: +#line 796 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3ExprListDelete((yypminor->yy266));} +#line 1341 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 188: + case 193: + case 201: case 202: -#line 446 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 454 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3SrcListDelete((yypminor->yy427));} +#line 1349 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 198: +#line 516 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + sqlite3ExprDelete((yypminor->yy348).pLimit); + sqlite3ExprDelete((yypminor->yy348).pOffset); +} +#line 1357 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 205: + case 208: + case 215: +#line 472 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" {sqlite3IdListDelete((yypminor->yy272));} -#line 1276 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 1364 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 216: - case 221: -#line 833 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DeleteTriggerStep((yypminor->yy91));} -#line 1282 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 230: + case 235: +#line 889 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3DeleteTriggerStep((yypminor->yy455));} +#line 1370 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 218: -#line 817 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3IdListDelete((yypminor->yy146).b);} -#line 1287 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 232: +#line 873 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3IdListDelete((yypminor->yy62).b);} +#line 1375 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; default: break; /* If no destructor action specified: do nothing */ } @@ -1458,298 +1546,311 @@ 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[] = { - { 131, 1 }, - { 132, 2 }, - { 132, 1 }, - { 133, 3 }, - { 133, 1 }, - { 135, 1 }, - { 134, 1 }, - { 134, 0 }, - { 136, 3 }, - { 138, 0 }, - { 138, 1 }, - { 138, 2 }, - { 137, 0 }, - { 137, 1 }, - { 137, 1 }, - { 137, 1 }, - { 136, 2 }, - { 136, 2 }, - { 136, 2 }, - { 136, 2 }, - { 140, 5 }, { 142, 1 }, - { 142, 0 }, - { 141, 4 }, - { 141, 2 }, - { 144, 3 }, + { 143, 2 }, + { 143, 1 }, + { 145, 1 }, { 144, 1 }, - { 147, 3 }, - { 148, 1 }, - { 151, 1 }, - { 152, 1 }, - { 152, 1 }, - { 139, 1 }, - { 139, 1 }, - { 139, 1 }, + { 144, 3 }, + { 147, 0 }, + { 147, 1 }, + { 146, 3 }, { 149, 0 }, { 149, 1 }, - { 149, 4 }, - { 149, 6 }, + { 149, 2 }, + { 148, 0 }, + { 148, 1 }, + { 148, 1 }, + { 148, 1 }, + { 146, 2 }, + { 146, 2 }, + { 146, 2 }, + { 146, 2 }, + { 151, 5 }, { 153, 1 }, - { 153, 2 }, - { 154, 1 }, - { 154, 1 }, - { 150, 2 }, - { 150, 0 }, - { 157, 3 }, - { 157, 1 }, - { 157, 2 }, - { 157, 2 }, - { 157, 2 }, - { 157, 2 }, - { 158, 2 }, + { 153, 0 }, + { 152, 4 }, + { 152, 2 }, + { 155, 3 }, + { 155, 1 }, { 158, 3 }, - { 158, 4 }, - { 158, 2 }, - { 158, 5 }, - { 158, 4 }, - { 158, 1 }, - { 158, 2 }, - { 163, 0 }, - { 163, 2 }, - { 165, 2 }, - { 165, 3 }, - { 165, 3 }, - { 165, 3 }, - { 166, 2 }, - { 166, 2 }, - { 166, 1 }, - { 166, 1 }, - { 164, 3 }, + { 159, 1 }, + { 162, 1 }, + { 163, 1 }, + { 163, 1 }, + { 150, 1 }, + { 150, 1 }, + { 150, 1 }, + { 160, 0 }, + { 160, 1 }, + { 160, 4 }, + { 160, 6 }, + { 164, 1 }, { 164, 2 }, - { 167, 0 }, - { 167, 2 }, - { 167, 2 }, - { 145, 0 }, - { 145, 2 }, + { 165, 1 }, + { 165, 1 }, + { 161, 2 }, + { 161, 0 }, { 168, 3 }, - { 168, 2 }, { 168, 1 }, + { 168, 2 }, + { 168, 3 }, + { 168, 3 }, + { 168, 2 }, { 169, 2 }, - { 169, 6 }, - { 169, 5 }, { 169, 3 }, - { 169, 10 }, - { 171, 0 }, - { 171, 1 }, - { 159, 0 }, - { 159, 3 }, - { 172, 0 }, - { 172, 2 }, - { 173, 1 }, - { 173, 1 }, + { 169, 5 }, + { 169, 2 }, + { 169, 5 }, + { 169, 4 }, + { 169, 1 }, + { 169, 2 }, + { 173, 0 }, { 173, 1 }, - { 136, 3 }, - { 136, 7 }, - { 136, 3 }, - { 136, 1 }, - { 146, 1 }, - { 146, 3 }, - { 177, 1 }, - { 177, 2 }, - { 177, 1 }, - { 177, 1 }, - { 176, 9 }, - { 178, 1 }, - { 178, 1 }, - { 178, 0 }, - { 186, 2 }, - { 186, 0 }, - { 179, 3 }, + { 176, 0 }, + { 176, 2 }, + { 178, 2 }, + { 178, 3 }, + { 178, 3 }, + { 178, 3 }, { 179, 2 }, - { 179, 4 }, - { 187, 2 }, - { 187, 1 }, - { 187, 0 }, + { 179, 2 }, + { 179, 1 }, + { 179, 1 }, + { 177, 3 }, + { 177, 2 }, { 180, 0 }, { 180, 2 }, - { 189, 2 }, - { 189, 0 }, - { 188, 6 }, - { 188, 7 }, - { 193, 1 }, - { 193, 1 }, - { 143, 0 }, - { 143, 2 }, - { 175, 2 }, - { 190, 1 }, + { 180, 2 }, + { 156, 0 }, + { 156, 2 }, + { 181, 3 }, + { 181, 2 }, + { 181, 1 }, + { 182, 2 }, + { 182, 7 }, + { 182, 5 }, + { 182, 3 }, + { 182, 10 }, + { 184, 0 }, + { 184, 1 }, + { 171, 0 }, + { 171, 3 }, + { 185, 0 }, + { 185, 2 }, + { 186, 1 }, + { 186, 1 }, + { 186, 1 }, + { 146, 3 }, + { 146, 7 }, + { 146, 3 }, + { 146, 1 }, + { 157, 1 }, + { 157, 3 }, { 190, 1 }, { 190, 2 }, - { 190, 3 }, - { 190, 4 }, - { 191, 2 }, + { 190, 1 }, + { 190, 1 }, + { 189, 9 }, + { 191, 1 }, + { 191, 1 }, { 191, 0 }, + { 199, 2 }, + { 199, 0 }, + { 192, 3 }, + { 192, 2 }, { 192, 4 }, - { 192, 0 }, - { 184, 0 }, - { 184, 3 }, - { 196, 5 }, - { 196, 3 }, - { 197, 1 }, - { 160, 1 }, - { 160, 1 }, - { 160, 0 }, - { 198, 0 }, - { 198, 2 }, - { 182, 0 }, - { 182, 3 }, - { 183, 0 }, - { 183, 2 }, - { 185, 0 }, - { 185, 2 }, - { 185, 4 }, - { 185, 4 }, - { 136, 4 }, - { 181, 0 }, - { 181, 2 }, - { 136, 6 }, - { 200, 5 }, - { 200, 3 }, - { 136, 8 }, - { 136, 5 }, - { 201, 2 }, - { 201, 1 }, - { 203, 3 }, - { 203, 1 }, + { 200, 2 }, + { 200, 1 }, + { 200, 0 }, + { 193, 0 }, + { 193, 2 }, + { 202, 2 }, { 202, 0 }, - { 202, 3 }, - { 195, 3 }, - { 195, 1 }, - { 161, 3 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 3 }, - { 161, 5 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 4 }, - { 161, 4 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 204, 1 }, - { 204, 1 }, - { 204, 2 }, - { 204, 2 }, - { 161, 3 }, - { 161, 2 }, - { 161, 3 }, - { 161, 2 }, - { 161, 3 }, - { 161, 4 }, - { 161, 2 }, - { 161, 2 }, - { 161, 2 }, - { 161, 2 }, - { 161, 3 }, - { 205, 1 }, - { 205, 2 }, - { 161, 5 }, + { 201, 6 }, + { 201, 7 }, { 206, 1 }, - { 206, 2 }, - { 161, 5 }, - { 161, 5 }, - { 161, 4 }, - { 161, 5 }, - { 208, 5 }, - { 208, 4 }, - { 209, 2 }, - { 209, 0 }, - { 207, 1 }, - { 207, 0 }, - { 199, 3 }, - { 199, 1 }, + { 206, 1 }, + { 154, 0 }, + { 154, 2 }, + { 188, 2 }, + { 203, 1 }, + { 203, 1 }, + { 203, 2 }, + { 203, 3 }, + { 203, 4 }, + { 204, 2 }, + { 204, 0 }, + { 205, 4 }, + { 205, 0 }, + { 197, 0 }, + { 197, 3 }, + { 209, 5 }, + { 209, 3 }, { 210, 1 }, - { 210, 0 }, - { 136, 11 }, - { 211, 1 }, + { 172, 1 }, + { 172, 1 }, + { 172, 0 }, { 211, 0 }, - { 162, 0 }, - { 162, 3 }, - { 170, 5 }, - { 170, 3 }, - { 212, 1 }, - { 136, 3 }, - { 136, 1 }, - { 136, 2 }, - { 136, 5 }, - { 136, 5 }, - { 136, 5 }, - { 136, 5 }, - { 136, 6 }, - { 136, 3 }, - { 155, 2 }, - { 156, 2 }, - { 214, 1 }, + { 211, 2 }, + { 195, 0 }, + { 195, 3 }, + { 196, 0 }, + { 196, 2 }, + { 198, 0 }, + { 198, 2 }, + { 198, 4 }, + { 198, 4 }, + { 146, 4 }, + { 194, 0 }, + { 194, 2 }, + { 146, 6 }, + { 213, 5 }, + { 213, 3 }, + { 146, 8 }, + { 146, 5 }, + { 214, 2 }, { 214, 1 }, - { 213, 1 }, - { 213, 0 }, - { 136, 5 }, - { 215, 10 }, - { 217, 1 }, - { 217, 1 }, - { 217, 2 }, - { 217, 0 }, - { 218, 1 }, - { 218, 1 }, - { 218, 1 }, - { 218, 3 }, - { 219, 0 }, - { 219, 3 }, - { 219, 3 }, - { 220, 0 }, - { 220, 2 }, { 216, 3 }, - { 216, 0 }, - { 221, 6 }, - { 221, 8 }, - { 221, 5 }, - { 221, 4 }, - { 221, 1 }, - { 161, 4 }, - { 161, 6 }, + { 216, 1 }, + { 215, 0 }, + { 215, 3 }, + { 208, 3 }, + { 208, 1 }, { 174, 1 }, + { 174, 3 }, + { 170, 1 }, { 174, 1 }, { 174, 1 }, - { 136, 3 }, - { 136, 6 }, - { 223, 0 }, - { 223, 2 }, + { 174, 3 }, + { 174, 5 }, + { 170, 1 }, + { 170, 1 }, + { 170, 1 }, + { 174, 1 }, + { 174, 1 }, + { 174, 1 }, + { 174, 4 }, + { 174, 4 }, + { 170, 1 }, + { 170, 1 }, + { 170, 1 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 174, 3 }, + { 217, 1 }, + { 217, 1 }, + { 217, 2 }, + { 217, 2 }, + { 218, 2 }, + { 218, 0 }, + { 174, 4 }, + { 174, 2 }, + { 174, 3 }, + { 174, 2 }, + { 174, 3 }, + { 174, 4 }, + { 174, 2 }, + { 174, 2 }, + { 174, 2 }, + { 174, 2 }, + { 219, 1 }, + { 219, 2 }, + { 174, 5 }, + { 220, 1 }, + { 220, 2 }, + { 174, 5 }, + { 174, 3 }, + { 174, 5 }, + { 174, 4 }, + { 174, 4 }, + { 174, 5 }, + { 222, 5 }, + { 222, 4 }, { 223, 2 }, - { 222, 1 }, - { 222, 0 }, - { 136, 3 }, + { 223, 0 }, + { 221, 1 }, + { 221, 0 }, + { 212, 3 }, + { 212, 1 }, + { 224, 1 }, + { 224, 0 }, + { 146, 11 }, + { 225, 1 }, + { 225, 0 }, + { 175, 0 }, + { 175, 3 }, + { 183, 5 }, + { 183, 3 }, + { 226, 1 }, + { 146, 3 }, + { 146, 1 }, + { 146, 2 }, + { 146, 5 }, + { 146, 5 }, + { 146, 5 }, + { 146, 5 }, + { 146, 6 }, + { 146, 3 }, + { 166, 2 }, + { 167, 2 }, + { 228, 1 }, + { 228, 1 }, + { 227, 1 }, + { 227, 0 }, + { 146, 5 }, + { 229, 10 }, + { 231, 1 }, + { 231, 1 }, + { 231, 2 }, + { 231, 0 }, + { 232, 1 }, + { 232, 1 }, + { 232, 1 }, + { 232, 3 }, + { 233, 0 }, + { 233, 3 }, + { 233, 3 }, + { 234, 0 }, + { 234, 2 }, + { 230, 3 }, + { 230, 0 }, + { 235, 6 }, + { 235, 8 }, + { 235, 5 }, + { 235, 4 }, + { 235, 1 }, + { 174, 4 }, + { 174, 6 }, + { 187, 1 }, + { 187, 1 }, + { 187, 1 }, + { 146, 3 }, + { 146, 6 }, + { 237, 0 }, + { 237, 2 }, + { 237, 2 }, + { 236, 1 }, + { 236, 0 }, + { 146, 3 }, + { 146, 1 }, + { 146, 3 }, + { 146, 6 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -1786,99 +1887,101 @@ static void yy_reduce( ** #line ** break; */ - case 5: -#line 86 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 3: +#line 84 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { sqlite3FinishCoding(pParse); } -#line 1794 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 1895 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 6: -#line 87 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ sqlite3BeginParse(pParse, 1); } -#line 1799 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 87 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ sqlite3BeginParse(pParse, 0); } +#line 1900 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 7: -#line 88 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ sqlite3BeginParse(pParse, 0); } -#line 1804 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 89 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ sqlite3BeginParse(pParse, 1); } +#line 1905 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 8: -#line 93 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy284);} -#line 1809 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 95 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy60);} +#line 1910 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 12: -#line 98 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = TK_DEFERRED;} -#line 1814 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 100 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = TK_DEFERRED;} +#line 1915 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 13: case 14: case 15: - case 99: case 101: - case 102: -#line 99 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = yymsp[0].major;} -#line 1824 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 103: + case 104: +#line 101 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = yymsp[0].major;} +#line 1925 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 16: case 17: -#line 102 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 104 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" {sqlite3CommitTransaction(pParse);} -#line 1830 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 1931 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 18: -#line 104 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 106 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" {sqlite3RollbackTransaction(pParse);} -#line 1835 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 1936 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 20: -#line 109 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 111 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98,yymsp[-3].minor.yy284,0); + sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406,yymsp[-3].minor.yy60,0); } -#line 1842 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 1943 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 21: - case 72: - case 104: - case 216: - case 219: -#line 113 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = 1;} -#line 1851 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 60: + case 74: + case 106: + case 224: + case 227: +#line 115 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = 1;} +#line 1953 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 22: - case 71: + case 59: case 73: - case 84: - case 105: - case 106: - case 215: - case 218: -#line 114 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = 0;} -#line 1863 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 75: + case 86: + case 107: + case 108: + case 223: + case 226: +#line 116 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = 0;} +#line 1966 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 23: -#line 115 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 117 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { sqlite3EndTable(pParse,&yymsp[0].minor.yy0,0); } -#line 1870 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 1973 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 24: -#line 118 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 120 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3EndTable(pParse,0,yymsp[0].minor.yy107); - sqlite3SelectDelete(yymsp[0].minor.yy107); + sqlite3EndTable(pParse,0,yymsp[0].minor.yy331); + sqlite3SelectDelete(yymsp[0].minor.yy331); } -#line 1878 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 1981 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 28: -#line 130 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddColumn(pParse,&yymsp[0].minor.yy98);} -#line 1883 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 132 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddColumn(pParse,&yymsp[0].minor.yy406);} +#line 1986 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 29: case 30: @@ -1886,600 +1989,619 @@ static void yy_reduce( case 32: case 33: case 34: - case 253: - case 254: -#line 136 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy98 = yymsp[0].minor.yy0;} -#line 1895 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 263: + case 264: +#line 138 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy406 = yymsp[0].minor.yy0;} +#line 1998 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 36: -#line 185 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy98,&yymsp[0].minor.yy98);} -#line 1900 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 193 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy406,&yymsp[0].minor.yy406);} +#line 2003 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 37: -#line 186 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy98,&yymsp[0].minor.yy0);} -#line 1905 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 194 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy406,&yymsp[0].minor.yy0);} +#line 2008 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 38: -#line 188 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy98,&yymsp[0].minor.yy0);} -#line 1910 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 196 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy406,&yymsp[0].minor.yy0);} +#line 2013 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 39: - case 112: - case 113: - case 124: - case 144: - case 241: + case 114: + case 115: + case 126: + case 146: case 251: - case 252: -#line 190 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy98 = yymsp[0].minor.yy98;} -#line 1922 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 261: + case 262: +#line 198 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy406 = yymsp[0].minor.yy406;} +#line 2025 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 40: -#line 191 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy98.z=yymsp[-1].minor.yy98.z; yygotominor.yy98.n=yymsp[0].minor.yy98.n+(yymsp[0].minor.yy98.z-yymsp[-1].minor.yy98.z);} -#line 1927 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 199 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy406.z=yymsp[-1].minor.yy406.z; yygotominor.yy406.n=yymsp[0].minor.yy406.n+(yymsp[0].minor.yy406.z-yymsp[-1].minor.yy406.z);} +#line 2030 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 41: -#line 193 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = atoi(yymsp[0].minor.yy98.z); } -#line 1932 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 201 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = atoi(yymsp[0].minor.yy406.z); } +#line 2035 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 42: -#line 194 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = -atoi(yymsp[0].minor.yy98.z); } -#line 1937 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 202 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = -atoi(yymsp[0].minor.yy406.z); } +#line 2040 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 47: case 48: -#line 199 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy98,0);} -#line 1943 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 207 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454);} +#line 2046 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 49: -#line 201 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy98,1);} -#line 1948 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 209 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy454, 0, 0); + sqlite3AddDefaultValue(pParse,p); +} +#line 2054 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 50: +#line 213 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy406); + sqlite3AddDefaultValue(pParse,p); +} +#line 2062 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 52: -#line 208 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy284);} -#line 1953 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 222 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy60);} +#line 2067 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 53: -#line 209 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddPrimaryKey(pParse,0,yymsp[0].minor.yy284);} -#line 1958 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 224 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy60,yymsp[0].minor.yy60);} +#line 2072 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 54: -#line 210 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy284,0,0);} -#line 1963 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 225 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy60,0,0);} +#line 2077 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 56: -#line 213 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy98,yymsp[-1].minor.yy210,yymsp[0].minor.yy284);} -#line 1968 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 228 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy406,yymsp[-1].minor.yy266,yymsp[0].minor.yy60);} +#line 2082 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 57: -#line 214 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy284);} -#line 1973 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 229 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy60);} +#line 2087 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 58: -#line 215 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddCollateType(pParse, yymsp[0].minor.yy98.z, yymsp[0].minor.yy98.n);} -#line 1978 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 59: -#line 223 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = OE_Restrict * 0x010101; } -#line 1983 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 60: -#line 224 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = (yymsp[-1].minor.yy284 & yymsp[0].minor.yy47.mask) | yymsp[0].minor.yy47.value; } -#line 1988 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 230 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddCollateType(pParse, yymsp[0].minor.yy406.z, yymsp[0].minor.yy406.n);} +#line 2092 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 61: -#line 226 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = 0; yygotominor.yy47.mask = 0x000000; } -#line 1993 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 243 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = OE_Restrict * 0x010101; } +#line 2097 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 62: -#line 227 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy284; yygotominor.yy47.mask = 0x0000ff; } -#line 1998 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 244 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = (yymsp[-1].minor.yy60 & yymsp[0].minor.yy243.mask) | yymsp[0].minor.yy243.value; } +#line 2102 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 63: -#line 228 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy284<<8; yygotominor.yy47.mask = 0x00ff00; } -#line 2003 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 246 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy243.value = 0; yygotominor.yy243.mask = 0x000000; } +#line 2107 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 64: -#line 229 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy284<<16; yygotominor.yy47.mask = 0xff0000; } -#line 2008 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 247 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy243.value = yymsp[0].minor.yy60; yygotominor.yy243.mask = 0x0000ff; } +#line 2112 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 65: -#line 231 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = OE_SetNull; } -#line 2013 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 248 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy243.value = yymsp[0].minor.yy60<<8; yygotominor.yy243.mask = 0x00ff00; } +#line 2117 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 66: -#line 232 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = OE_SetDflt; } -#line 2018 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 249 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy243.value = yymsp[0].minor.yy60<<16; yygotominor.yy243.mask = 0xff0000; } +#line 2122 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 67: -#line 233 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = OE_Cascade; } -#line 2023 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 251 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = OE_SetNull; } +#line 2127 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 68: -#line 234 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = OE_Restrict; } -#line 2028 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 252 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = OE_SetDflt; } +#line 2132 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 69: +#line 253 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = OE_Cascade; } +#line 2137 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; case 70: - case 85: +#line 254 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = OE_Restrict; } +#line 2142 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 71: + case 72: case 87: case 89: - case 90: - case 161: -#line 236 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = yymsp[0].minor.yy284;} -#line 2039 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 80: -#line 253 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddPrimaryKey(pParse,yymsp[-2].minor.yy210,yymsp[0].minor.yy284);} -#line 2044 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 91: + case 92: + case 163: +#line 256 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = yymsp[0].minor.yy60;} +#line 2153 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 81: -#line 255 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy210,yymsp[0].minor.yy284,0,0);} -#line 2049 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 82: +#line 273 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy266,yymsp[0].minor.yy60,yymsp[-2].minor.yy60);} +#line 2158 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 83: -#line 258 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 275 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy266,yymsp[0].minor.yy60,0,0);} +#line 2163 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 85: +#line 278 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy210, &yymsp[-3].minor.yy98, yymsp[-2].minor.yy210, yymsp[-1].minor.yy284); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy284); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy266, &yymsp[-3].minor.yy406, yymsp[-2].minor.yy266, yymsp[-1].minor.yy60); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy60); } -#line 2057 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2171 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 86: case 88: -#line 272 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = OE_Default;} -#line 2063 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 91: -#line 277 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = OE_Ignore;} -#line 2068 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 92: - case 162: -#line 278 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = OE_Replace;} -#line 2074 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 90: +#line 292 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = OE_Default;} +#line 2177 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 93: -#line 282 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0); -} -#line 2081 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 297 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = OE_Ignore;} +#line 2182 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 94: -#line 288 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy98, &yymsp[-2].minor.yy98, yymsp[0].minor.yy107, yymsp[-5].minor.yy284); -} -#line 2088 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 164: +#line 298 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = OE_Replace;} +#line 2188 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 95: -#line 291 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 302 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1); + sqlite3DropTable(pParse, yymsp[0].minor.yy427, 0); } -#line 2095 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2195 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 96: -#line 297 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 309 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3Select(pParse, yymsp[0].minor.yy107, SRT_Callback, 0, 0, 0, 0, 0); - sqlite3SelectDelete(yymsp[0].minor.yy107); + sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy406, &yymsp[-2].minor.yy406, yymsp[0].minor.yy331, yymsp[-5].minor.yy60); } -#line 2103 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2202 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 97: - case 121: -#line 307 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy107 = yymsp[0].minor.yy107;} -#line 2109 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 312 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy427, 1); +} +#line 2209 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 98: -#line 308 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 319 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - if( yymsp[0].minor.yy107 ){ - yymsp[0].minor.yy107->op = yymsp[-1].minor.yy284; - yymsp[0].minor.yy107->pPrior = yymsp[-2].minor.yy107; - } - yygotominor.yy107 = yymsp[0].minor.yy107; + sqlite3Select(pParse, yymsp[0].minor.yy331, SRT_Callback, 0, 0, 0, 0, 0); + sqlite3SelectDelete(yymsp[0].minor.yy331); } -#line 2120 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2217 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 100: -#line 317 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = TK_ALL;} -#line 2125 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 99: + case 123: +#line 329 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy331 = yymsp[0].minor.yy331;} +#line 2223 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 103: -#line 321 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 100: +#line 331 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy107 = sqlite3SelectNew(yymsp[-6].minor.yy210,yymsp[-5].minor.yy259,yymsp[-4].minor.yy258,yymsp[-3].minor.yy210,yymsp[-2].minor.yy258,yymsp[-1].minor.yy210,yymsp[-7].minor.yy284,yymsp[0].minor.yy404.limit,yymsp[0].minor.yy404.offset); + if( yymsp[0].minor.yy331 ){ + yymsp[0].minor.yy331->op = yymsp[-1].minor.yy60; + yymsp[0].minor.yy331->pPrior = yymsp[-2].minor.yy331; + } + yygotominor.yy331 = yymsp[0].minor.yy331; } -#line 2132 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2234 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 107: - case 238: -#line 342 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210 = yymsp[-1].minor.yy210;} -#line 2138 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 102: +#line 340 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = TK_ALL;} +#line 2239 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 108: - case 135: - case 145: - case 237: -#line 343 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210 = 0;} -#line 2146 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 105: +#line 345 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + yygotominor.yy331 = sqlite3SelectNew(yymsp[-6].minor.yy266,yymsp[-5].minor.yy427,yymsp[-4].minor.yy454,yymsp[-3].minor.yy266,yymsp[-2].minor.yy454,yymsp[-1].minor.yy266,yymsp[-7].minor.yy60,yymsp[0].minor.yy348.pLimit,yymsp[0].minor.yy348.pOffset); +} +#line 2246 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 109: -#line 344 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 248: +#line 366 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy266 = yymsp[-1].minor.yy266;} +#line 2252 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 110: + case 137: + case 147: + case 247: +#line 367 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy266 = 0;} +#line 2260 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 111: +#line 368 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-2].minor.yy210,yymsp[-1].minor.yy258,yymsp[0].minor.yy98.n?&yymsp[0].minor.yy98:0); + yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-2].minor.yy266,yymsp[-1].minor.yy454,yymsp[0].minor.yy406.n?&yymsp[0].minor.yy406:0); } -#line 2153 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2267 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 110: -#line 347 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 112: +#line 371 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-1].minor.yy210, sqlite3Expr(TK_ALL, 0, 0, 0), 0); + yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-1].minor.yy266, sqlite3Expr(TK_ALL, 0, 0, 0), 0); } -#line 2160 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2274 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 111: -#line 350 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 113: +#line 374 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); - Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy98); - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-3].minor.yy210, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); + Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406); + yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-3].minor.yy266, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); } -#line 2169 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 114: -#line 362 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy98.n = 0;} -#line 2174 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 115: -#line 374 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy259 = sqliteMalloc(sizeof(*yygotominor.yy259));} -#line 2179 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2283 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 116: -#line 375 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy259 = yymsp[0].minor.yy259;} -#line 2184 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 386 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy406.n = 0;} +#line 2288 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 117: -#line 380 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy259 = yymsp[-1].minor.yy259; - if( yygotominor.yy259 && yygotominor.yy259->nSrc>0 ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = yymsp[0].minor.yy284; -} -#line 2192 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 398 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy427 = sqliteMalloc(sizeof(*yygotominor.yy427));} +#line 2293 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 118: -#line 384 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy259 = 0;} -#line 2197 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 399 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy427 = yymsp[0].minor.yy427;} +#line 2298 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 119: -#line 385 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 404 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy259 = sqlite3SrcListAppend(yymsp[-5].minor.yy259,&yymsp[-4].minor.yy98,&yymsp[-3].minor.yy98); - if( yymsp[-2].minor.yy98.n ) sqlite3SrcListAddAlias(yygotominor.yy259,&yymsp[-2].minor.yy98); - if( yymsp[-1].minor.yy258 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pOn = yymsp[-1].minor.yy258; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy258); } - } - if( yymsp[0].minor.yy272 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pUsing = yymsp[0].minor.yy272; } - else { sqlite3IdListDelete(yymsp[0].minor.yy272); } - } + yygotominor.yy427 = yymsp[-1].minor.yy427; + if( yygotominor.yy427 && yygotominor.yy427->nSrc>0 ) yygotominor.yy427->a[yygotominor.yy427->nSrc-1].jointype = yymsp[0].minor.yy60; } -#line 2213 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2306 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 120: -#line 398 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 408 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy427 = 0;} +#line 2311 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 121: +#line 409 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy259 = sqlite3SrcListAppend(yymsp[-6].minor.yy259,0,0); - yygotominor.yy259->a[yygotominor.yy259->nSrc-1].pSelect = yymsp[-4].minor.yy107; - if( yymsp[-2].minor.yy98.n ) sqlite3SrcListAddAlias(yygotominor.yy259,&yymsp[-2].minor.yy98); - if( yymsp[-1].minor.yy258 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pOn = yymsp[-1].minor.yy258; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy258); } + yygotominor.yy427 = sqlite3SrcListAppend(yymsp[-5].minor.yy427,&yymsp[-4].minor.yy406,&yymsp[-3].minor.yy406); + if( yymsp[-2].minor.yy406.n ) sqlite3SrcListAddAlias(yygotominor.yy427,&yymsp[-2].minor.yy406); + if( yymsp[-1].minor.yy454 ){ + if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pOn = yymsp[-1].minor.yy454; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy454); } } if( yymsp[0].minor.yy272 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pUsing = yymsp[0].minor.yy272; } + if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pUsing = yymsp[0].minor.yy272; } else { sqlite3IdListDelete(yymsp[0].minor.yy272); } } } -#line 2230 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2327 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 122: -#line 419 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 423 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy107 = sqlite3SelectNew(0,yymsp[0].minor.yy259,0,0,0,0,0,-1,0); -} -#line 2237 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + yygotominor.yy427 = sqlite3SrcListAppend(yymsp[-6].minor.yy427,0,0); + yygotominor.yy427->a[yygotominor.yy427->nSrc-1].pSelect = yymsp[-4].minor.yy331; + if( yymsp[-2].minor.yy406.n ) sqlite3SrcListAddAlias(yygotominor.yy427,&yymsp[-2].minor.yy406); + if( yymsp[-1].minor.yy454 ){ + if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pOn = yymsp[-1].minor.yy454; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy454); } + } + if( yymsp[0].minor.yy272 ){ + if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pUsing = yymsp[0].minor.yy272; } + else { sqlite3IdListDelete(yymsp[0].minor.yy272); } + } + } +#line 2344 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 123: -#line 424 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy98.z=0; yygotominor.yy98.n=0;} -#line 2242 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 124: +#line 444 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + yygotominor.yy331 = sqlite3SelectNew(0,yymsp[0].minor.yy427,0,0,0,0,0,0,0); + } +#line 2351 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 125: -#line 429 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy259 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98);} -#line 2247 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 450 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy406.z=0; yygotominor.yy406.n=0;} +#line 2356 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 126: case 127: -#line 433 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = JT_INNER; } -#line 2253 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 455 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy427 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406);} +#line 2361 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 128: -#line 435 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } -#line 2258 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 129: -#line 436 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy98,0); } -#line 2263 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 459 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = JT_INNER; } +#line 2367 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 130: -#line 438 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy98,&yymsp[-1].minor.yy98); } -#line 2268 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 461 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +#line 2372 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 131: - case 139: - case 148: - case 155: - case 226: - case 228: - case 232: -#line 442 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = yymsp[0].minor.yy258;} -#line 2279 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 462 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy406,0); } +#line 2377 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 132: - case 147: - case 154: - case 227: - case 229: - case 233: -#line 443 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = 0;} -#line 2289 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 464 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy406,&yymsp[-1].minor.yy406); } +#line 2382 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 133: - case 166: -#line 447 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy272 = yymsp[-1].minor.yy272;} -#line 2295 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 141: + case 150: + case 157: + case 171: + case 211: + case 236: + case 238: + case 242: +#line 468 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = yymsp[0].minor.yy454;} +#line 2395 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 134: - case 165: -#line 448 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy272 = 0;} -#line 2301 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 149: + case 156: + case 212: + case 237: + case 239: + case 243: +#line 469 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = 0;} +#line 2406 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 135: + case 168: +#line 473 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy272 = yymsp[-1].minor.yy272;} +#line 2412 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 136: - case 146: -#line 459 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210 = yymsp[0].minor.yy210;} -#line 2307 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 167: +#line 474 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy272 = 0;} +#line 2418 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 137: -#line 460 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 138: + case 148: +#line 485 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy266 = yymsp[0].minor.yy266;} +#line 2424 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 139: +#line 486 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210,yymsp[-2].minor.yy258,yymsp[-1].minor.yy98.n>0?&yymsp[-1].minor.yy98:0); - if( yygotominor.yy210 ) yygotominor.yy210->a[yygotominor.yy210->nExpr-1].sortOrder = yymsp[0].minor.yy284; + yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266,yymsp[-2].minor.yy454,yymsp[-1].minor.yy406.n>0?&yymsp[-1].minor.yy406:0); + if( yygotominor.yy266 ) yygotominor.yy266->a[yygotominor.yy266->nExpr-1].sortOrder = yymsp[0].minor.yy60; } -#line 2315 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2432 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 138: -#line 464 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 140: +#line 490 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy258,yymsp[-1].minor.yy98.n>0?&yymsp[-1].minor.yy98:0); - if( yygotominor.yy210 && yygotominor.yy210->a ) yygotominor.yy210->a[0].sortOrder = yymsp[0].minor.yy284; + yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy454,yymsp[-1].minor.yy406.n>0?&yymsp[-1].minor.yy406:0); + if( yygotominor.yy266 && yygotominor.yy266->a ) yygotominor.yy266->a[0].sortOrder = yymsp[0].minor.yy60; } -#line 2323 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2440 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 140: case 142: -#line 473 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = SQLITE_SO_ASC;} -#line 2329 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 141: -#line 474 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = SQLITE_SO_DESC;} -#line 2334 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 144: +#line 499 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = SQLITE_SO_ASC;} +#line 2446 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 143: -#line 476 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy98.z = 0; yygotominor.yy98.n = 0;} -#line 2339 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; - case 149: -#line 490 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy404.limit = -1; yygotominor.yy404.offset = 0;} -#line 2344 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 500 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = SQLITE_SO_DESC;} +#line 2451 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 150: -#line 491 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy404.limit = yymsp[0].minor.yy284; yygotominor.yy404.offset = 0;} -#line 2349 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 145: +#line 502 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy406.z = 0; yygotominor.yy406.n = 0;} +#line 2456 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 151: -#line 493 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy404.limit = yymsp[-2].minor.yy284; yygotominor.yy404.offset = yymsp[0].minor.yy284;} -#line 2354 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 520 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy348.pLimit = 0; yygotominor.yy348.pOffset = 0;} +#line 2461 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 152: -#line 495 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy404.limit = yymsp[0].minor.yy284; yygotominor.yy404.offset = yymsp[-2].minor.yy284;} -#line 2359 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 521 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy348.pLimit = yymsp[0].minor.yy454; yygotominor.yy348.pOffset = 0;} +#line 2466 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 153: -#line 499 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy259,yymsp[0].minor.yy258);} -#line 2364 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 523 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy348.pLimit = yymsp[-2].minor.yy454; yygotominor.yy348.pOffset = yymsp[0].minor.yy454;} +#line 2471 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 156: -#line 513 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Update(pParse,yymsp[-3].minor.yy259,yymsp[-1].minor.yy210,yymsp[0].minor.yy258,yymsp[-4].minor.yy284);} -#line 2369 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 154: +#line 525 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy348.pOffset = yymsp[-2].minor.yy454; yygotominor.yy348.pLimit = yymsp[0].minor.yy454;} +#line 2476 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 157: -#line 516 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210,yymsp[0].minor.yy258,&yymsp[-2].minor.yy98);} -#line 2374 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 155: +#line 529 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy427,yymsp[0].minor.yy454);} +#line 2481 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 158: -#line 517 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(0,yymsp[0].minor.yy258,&yymsp[-2].minor.yy98);} -#line 2379 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 543 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Update(pParse,yymsp[-3].minor.yy427,yymsp[-1].minor.yy266,yymsp[0].minor.yy454,yymsp[-4].minor.yy60);} +#line 2486 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 159: -#line 523 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Insert(pParse, yymsp[-5].minor.yy259, yymsp[-1].minor.yy210, 0, yymsp[-4].minor.yy272, yymsp[-7].minor.yy284);} -#line 2384 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 546 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266,yymsp[0].minor.yy454,&yymsp[-2].minor.yy406);} +#line 2491 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 160: -#line 525 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy107, yymsp[-1].minor.yy272, yymsp[-4].minor.yy284);} -#line 2389 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 547 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[0].minor.yy454,&yymsp[-2].minor.yy406);} +#line 2496 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 163: - case 230: -#line 535 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-2].minor.yy210,yymsp[0].minor.yy258,0);} -#line 2395 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 161: +#line 553 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Insert(pParse, yymsp[-5].minor.yy427, yymsp[-1].minor.yy266, 0, yymsp[-4].minor.yy272, yymsp[-7].minor.yy60);} +#line 2501 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 164: - case 231: -#line 536 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(0,yymsp[0].minor.yy258,0);} -#line 2401 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 162: +#line 555 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Insert(pParse, yymsp[-2].minor.yy427, 0, yymsp[0].minor.yy331, yymsp[-1].minor.yy272, yymsp[-4].minor.yy60);} +#line 2506 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 167: -#line 545 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy272 = sqlite3IdListAppend(yymsp[-2].minor.yy272,&yymsp[0].minor.yy98);} -#line 2406 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 165: + case 240: +#line 565 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-2].minor.yy266,yymsp[0].minor.yy454,0);} +#line 2512 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 168: -#line 546 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy272 = sqlite3IdListAppend(0,&yymsp[0].minor.yy98);} -#line 2411 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 166: + case 241: +#line 566 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[0].minor.yy454,0);} +#line 2518 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 169: -#line 554 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = yymsp[-1].minor.yy258; sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2416 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 575 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy272 = sqlite3IdListAppend(yymsp[-2].minor.yy272,&yymsp[0].minor.yy406);} +#line 2523 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 170: - case 175: - case 176: - case 177: - case 178: -#line 555 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} -#line 2425 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 576 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy272 = sqlite3IdListAppend(0,&yymsp[0].minor.yy406);} +#line 2528 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 171: case 172: -#line 556 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} -#line 2431 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 587 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = yymsp[-1].minor.yy454; sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } +#line 2533 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 173: -#line 558 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 178: + case 179: + case 180: + case 181: +#line 588 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} +#line 2542 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 174: + case 175: +#line 589 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} +#line 2548 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 176: +#line 591 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy98); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy98); - yygotominor.yy258 = sqlite3Expr(TK_DOT, temp1, temp2, 0); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy406); + yygotominor.yy454 = sqlite3Expr(TK_DOT, temp1, temp2, 0); } -#line 2440 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2557 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 174: -#line 563 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 177: +#line 596 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy98); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy98); - Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy98); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy406); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406); + Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy406); Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); - yygotominor.yy258 = sqlite3Expr(TK_DOT, temp1, temp4, 0); + yygotominor.yy454 = sqlite3Expr(TK_DOT, temp1, temp4, 0); } -#line 2451 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2568 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 179: -#line 574 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 182: +#line 607 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} +#line 2573 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 183: +#line 608 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { Token *pToken = &yymsp[0].minor.yy0; - Expr *pExpr = yygotominor.yy258 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); + Expr *pExpr = yygotominor.yy454 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); sqlite3ExprAssignVarNumber(pParse, pExpr); } -#line 2460 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2582 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 180: -#line 579 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 184: +#line 613 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3ExprFunction(yymsp[-1].minor.yy210, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy454 = sqlite3ExprFunction(yymsp[-1].minor.yy266, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 2468 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2590 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 181: -#line 583 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 185: +#line 617 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy454 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 2476 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2598 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 182: - case 183: - case 184: - case 185: case 186: case 187: case 188: +#line 621 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = sqlite3Expr(yymsp[0].major,0,0,0);} +#line 2605 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; case 189: case 190: case 191: @@ -2491,435 +2613,473 @@ static void yy_reduce( case 197: case 198: case 199: -#line 587 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy258, yymsp[0].minor.yy258, 0);} -#line 2498 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 200: -#line 606 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy342.opcode = TK_LIKE; yygotominor.yy342.not = 0;} -#line 2503 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 201: -#line 607 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy342.opcode = TK_GLOB; yygotominor.yy342.not = 0;} -#line 2508 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 202: -#line 608 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy342.opcode = TK_LIKE; yygotominor.yy342.not = 1;} -#line 2513 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 203: -#line 609 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy342.opcode = TK_GLOB; yygotominor.yy342.not = 1;} -#line 2518 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 204: -#line 610 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - ExprList *pList = sqlite3ExprListAppend(0, yymsp[0].minor.yy258, 0); - pList = sqlite3ExprListAppend(pList, yymsp[-2].minor.yy258, 0); - yygotominor.yy258 = sqlite3ExprFunction(pList, 0); - if( yygotominor.yy258 ) yygotominor.yy258->op = yymsp[-1].minor.yy342.opcode; - if( yymsp[-1].minor.yy342.not ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-2].minor.yy258->span, &yymsp[0].minor.yy258->span); -} -#line 2530 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 205: -#line 618 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2538 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" - break; case 206: -#line 622 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2546 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 624 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy454 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy454, yymsp[0].minor.yy454, 0);} +#line 2627 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 207: -#line 626 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2554 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 643 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy258.opcode = TK_LIKE; yygotominor.yy258.not = 0;} +#line 2632 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 208: -#line 630 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2562 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 644 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy258.opcode = TK_GLOB; yygotominor.yy258.not = 0;} +#line 2637 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 209: -#line 634 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2570 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 645 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy258.opcode = TK_LIKE; yygotominor.yy258.not = 1;} +#line 2642 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 210: - case 211: -#line 638 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 646 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy258.opcode = TK_GLOB; yygotominor.yy258.not = 1;} +#line 2647 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 213: +#line 650 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy258->span); + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy454, 0); + pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy454, 0); + if( yymsp[0].minor.yy454 ){ + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy454, 0); + } + yygotominor.yy454 = sqlite3ExprFunction(pList, 0); + if( yygotominor.yy454 ) yygotominor.yy454->op = yymsp[-2].minor.yy258.opcode; + if( yymsp[-2].minor.yy258.not ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454, &yymsp[-3].minor.yy454->span, &yymsp[-1].minor.yy454->span); } -#line 2579 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2662 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 212: -#line 646 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 214: +#line 662 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy258->span); + yygotominor.yy454 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy454->span,&yymsp[0].minor.yy0); } -#line 2587 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2670 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 213: -#line 650 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 215: +#line 666 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy258->span); + yygotominor.yy454 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy454->span,&yymsp[0].minor.yy0); } -#line 2595 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2678 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 214: -#line 654 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 216: +#line 670 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pSelect = yymsp[-1].minor.yy107; - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy454->span,&yymsp[0].minor.yy0); } -#line 2604 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2686 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 217: -#line 662 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 674 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy454->span,&yymsp[0].minor.yy0); +} +#line 2694 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 218: +#line 678 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy258, 0); - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy258, 0); - yygotominor.yy258 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pList = pList; - if( yymsp[-3].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-4].minor.yy258->span,&yymsp[0].minor.yy258->span); + yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy454->span,&yymsp[0].minor.yy0); } -#line 2616 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2702 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; + case 219: case 220: -#line 673 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 682 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pList = yymsp[-1].minor.yy210; - if( yymsp[-3].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-4].minor.yy258->span,&yymsp[0].minor.yy0); + yygotominor.yy454 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span); } -#line 2626 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2711 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 221: -#line 679 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 690 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pSelect = yymsp[-1].minor.yy107; - if( yymsp[-3].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-4].minor.yy258->span,&yymsp[0].minor.yy0); + yygotominor.yy454 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span); } -#line 2636 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2719 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 222: -#line 685 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 694 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98); - yygotominor.yy258 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0); - if( yymsp[-2].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy258->span,yymsp[0].minor.yy98.z?&yymsp[0].minor.yy98:&yymsp[-1].minor.yy98); + yygotominor.yy454 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span); } -#line 2647 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2727 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 223: -#line 695 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 225: +#line 701 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy258, yymsp[-1].minor.yy258, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pList = yymsp[-2].minor.yy210; - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy454, 0); + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy454, 0); + yygotominor.yy454 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy454, 0, 0); + if( yygotominor.yy454 ) yygotominor.yy454->pList = pList; + if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy454->span); } -#line 2656 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2739 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 224: -#line 702 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 228: +#line 713 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210, yymsp[-2].minor.yy258, 0); - yygotominor.yy210 = sqlite3ExprListAppend(yygotominor.yy210, yymsp[0].minor.yy258, 0); -} -#line 2664 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy454, 0, 0); + if( yygotominor.yy454 ) yygotominor.yy454->pList = yymsp[-1].minor.yy266; + if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy0); + } +#line 2749 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 225: -#line 706 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 229: +#line 719 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + yygotominor.yy454 = sqlite3Expr(TK_SELECT, 0, 0, 0); + if( yygotominor.yy454 ) yygotominor.yy454->pSelect = yymsp[-1].minor.yy331; + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + } +#line 2758 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 230: +#line 724 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy454, 0, 0); + if( yygotominor.yy454 ) yygotominor.yy454->pSelect = yymsp[-1].minor.yy331; + if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy0); + } +#line 2768 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 231: +#line 730 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy258, 0); - yygotominor.yy210 = sqlite3ExprListAppend(yygotominor.yy210, yymsp[0].minor.yy258, 0); + SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406); + yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy454, 0, 0); + if( yygotominor.yy454 ) yygotominor.yy454->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + if( yymsp[-2].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0); + sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy454->span,yymsp[0].minor.yy406.z?&yymsp[0].minor.yy406:&yymsp[-1].minor.yy406); + } +#line 2779 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 232: +#line 737 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + Expr *p = yygotominor.yy454 = sqlite3Expr(TK_EXISTS, 0, 0, 0); + if( p ){ + p->pSelect = yymsp[-1].minor.yy331; + sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + } + } +#line 2790 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 233: +#line 747 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + yygotominor.yy454 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, 0); + if( yygotominor.yy454 ) yygotominor.yy454->pList = yymsp[-2].minor.yy266; + sqlite3ExprSpan(yygotominor.yy454, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); } -#line 2672 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2799 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 234: -#line 731 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 754 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - if( yymsp[-9].minor.yy284!=OE_None ) yymsp[-9].minor.yy284 = yymsp[0].minor.yy284; - if( yymsp[-9].minor.yy284==OE_Default) yymsp[-9].minor.yy284 = OE_Abort; - sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy98, &yymsp[-6].minor.yy98, yymsp[-4].minor.yy259, yymsp[-2].minor.yy210, yymsp[-9].minor.yy284, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); + yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266, yymsp[-2].minor.yy454, 0); + yygotominor.yy266 = sqlite3ExprListAppend(yygotominor.yy266, yymsp[0].minor.yy454, 0); } -#line 2681 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2807 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; case 235: - case 282: -#line 738 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = OE_Abort;} -#line 2687 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 758 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + yygotominor.yy266 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy454, 0); + yygotominor.yy266 = sqlite3ExprListAppend(yygotominor.yy266, yymsp[0].minor.yy454, 0); +} +#line 2815 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 236: -#line 739 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = OE_None;} -#line 2692 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 244: +#line 783 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + if( yymsp[-9].minor.yy60!=OE_None ) yymsp[-9].minor.yy60 = yymsp[0].minor.yy60; + if( yymsp[-9].minor.yy60==OE_Default) yymsp[-9].minor.yy60 = OE_Abort; + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy406, &yymsp[-6].minor.yy406, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy406,0),yymsp[-2].minor.yy266,yymsp[-9].minor.yy60, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); +} +#line 2824 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 239: -#line 749 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 245: + case 292: +#line 790 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = OE_Abort;} +#line 2830 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 246: +#line 791 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = OE_None;} +#line 2835 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 249: +#line 801 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { Expr *p = 0; - if( yymsp[-1].minor.yy98.n>0 ){ + if( yymsp[-1].minor.yy406.n>0 ){ p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy98.z, yymsp[-1].minor.yy98.n); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy406.z, yymsp[-1].minor.yy406.n); } - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210, p, &yymsp[-2].minor.yy98); + yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266, p, &yymsp[-2].minor.yy406); } -#line 2704 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2847 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 240: -#line 757 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 250: +#line 809 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { Expr *p = 0; - if( yymsp[-1].minor.yy98.n>0 ){ + if( yymsp[-1].minor.yy406.n>0 ){ p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy98.z, yymsp[-1].minor.yy98.n); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy406.z, yymsp[-1].minor.yy406.n); } - yygotominor.yy210 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy98); + yygotominor.yy266 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy406); } -#line 2716 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2859 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 242: -#line 770 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DropIndex(pParse, yymsp[0].minor.yy259);} -#line 2721 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 252: +#line 822 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3DropIndex(pParse, yymsp[0].minor.yy427);} +#line 2864 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 243: - case 244: -#line 774 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 253: + case 254: +#line 826 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" {sqlite3Vacuum(pParse,0);} -#line 2727 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2870 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 245: - case 247: -#line 779 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy98,&yymsp[-2].minor.yy98,&yymsp[0].minor.yy98,0);} -#line 2733 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 255: + case 257: +#line 832 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy406,0);} +#line 2876 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 246: -#line 780 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy98,&yymsp[-2].minor.yy98,&yymsp[0].minor.yy0,0);} -#line 2738 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 256: +#line 833 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy0,0);} +#line 2881 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 248: -#line 782 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 258: +#line 835 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3Pragma(pParse,&yymsp[-3].minor.yy98,&yymsp[-2].minor.yy98,&yymsp[0].minor.yy98,1); + sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy406,1); } -#line 2745 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2888 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 249: -#line 785 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy98,&yymsp[-3].minor.yy98,&yymsp[-1].minor.yy98,0);} -#line 2750 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 259: +#line 838 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy406,&yymsp[-3].minor.yy406,&yymsp[-1].minor.yy406,0);} +#line 2893 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 250: -#line 786 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98,0,0);} -#line 2755 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 260: +#line 839 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406,0,0);} +#line 2898 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 257: -#line 796 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 267: +#line 852 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { Token all; - all.z = yymsp[-3].minor.yy98.z; - all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy98.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy91, &all); + all.z = yymsp[-3].minor.yy406.z; + all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy406.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy455, &all); } -#line 2765 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2908 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 258: -#line 805 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 268: +#line 861 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy98, &yymsp[-6].minor.yy98, yymsp[-5].minor.yy284, yymsp[-4].minor.yy146.a, yymsp[-4].minor.yy146.b, yymsp[-2].minor.yy259, yymsp[-1].minor.yy284, yymsp[0].minor.yy258, yymsp[-9].minor.yy284); - yygotominor.yy98 = (yymsp[-6].minor.yy98.n==0?yymsp[-7].minor.yy98:yymsp[-6].minor.yy98); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy406, &yymsp[-6].minor.yy406, yymsp[-5].minor.yy60, yymsp[-4].minor.yy62.a, yymsp[-4].minor.yy62.b, yymsp[-2].minor.yy427, yymsp[-1].minor.yy60, yymsp[0].minor.yy454, yymsp[-9].minor.yy60); + yygotominor.yy406 = (yymsp[-6].minor.yy406.n==0?yymsp[-7].minor.yy406:yymsp[-6].minor.yy406); } -#line 2773 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2916 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 259: - case 262: -#line 811 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = TK_BEFORE; } -#line 2779 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 269: + case 272: +#line 867 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = TK_BEFORE; } +#line 2922 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 260: -#line 812 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = TK_AFTER; } -#line 2784 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 270: +#line 868 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = TK_AFTER; } +#line 2927 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 261: -#line 813 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = TK_INSTEAD;} -#line 2789 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 271: +#line 869 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = TK_INSTEAD;} +#line 2932 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 263: - case 264: - case 265: -#line 818 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy146.a = yymsp[0].major; yygotominor.yy146.b = 0;} -#line 2796 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 273: + case 274: + case 275: +#line 874 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy62.a = yymsp[0].major; yygotominor.yy62.b = 0;} +#line 2939 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 266: -#line 821 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy146.a = TK_UPDATE; yygotominor.yy146.b = yymsp[0].minor.yy272;} -#line 2801 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 276: +#line 877 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy62.a = TK_UPDATE; yygotominor.yy62.b = yymsp[0].minor.yy272;} +#line 2944 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 267: - case 268: -#line 824 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = TK_ROW; } -#line 2807 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 277: + case 278: +#line 880 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = TK_ROW; } +#line 2950 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 269: -#line 826 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy284 = TK_STATEMENT; } -#line 2812 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 279: +#line 882 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy60 = TK_STATEMENT; } +#line 2955 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 270: -#line 829 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy258 = 0; } -#line 2817 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 280: +#line 885 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy454 = 0; } +#line 2960 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 271: -#line 830 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy258 = yymsp[0].minor.yy258; } -#line 2822 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 281: +#line 886 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy454 = yymsp[0].minor.yy454; } +#line 2965 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 272: -#line 834 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 282: +#line 890 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yymsp[-2].minor.yy91->pNext = yymsp[0].minor.yy91; - yygotominor.yy91 = yymsp[-2].minor.yy91; + yymsp[-2].minor.yy455->pNext = yymsp[0].minor.yy455; + yygotominor.yy455 = yymsp[-2].minor.yy455; } -#line 2830 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 2973 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 273: -#line 838 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy91 = 0; } -#line 2835 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 283: +#line 894 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy455 = 0; } +#line 2978 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 274: -#line 844 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy91 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy98, yymsp[-1].minor.yy210, yymsp[0].minor.yy258, yymsp[-4].minor.yy284); } -#line 2840 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 284: +#line 900 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy455 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy406, yymsp[-1].minor.yy266, yymsp[0].minor.yy454, yymsp[-4].minor.yy60); } +#line 2983 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 275: -#line 849 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy91 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy98, yymsp[-4].minor.yy272, yymsp[-1].minor.yy210, 0, yymsp[-7].minor.yy284);} -#line 2845 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 285: +#line 905 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy455 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy406, yymsp[-4].minor.yy272, yymsp[-1].minor.yy266, 0, yymsp[-7].minor.yy60);} +#line 2988 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 276: -#line 852 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy91 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy98, yymsp[-1].minor.yy272, 0, yymsp[0].minor.yy107, yymsp[-4].minor.yy284);} -#line 2850 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 286: +#line 908 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy455 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy406, yymsp[-1].minor.yy272, 0, yymsp[0].minor.yy331, yymsp[-4].minor.yy60);} +#line 2993 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 277: -#line 856 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy91 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy98, yymsp[0].minor.yy258);} -#line 2855 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 287: +#line 912 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy455 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy406, yymsp[0].minor.yy454);} +#line 2998 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 278: -#line 859 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy91 = sqlite3TriggerSelectStep(yymsp[0].minor.yy107); } -#line 2860 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 288: +#line 915 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy455 = sqlite3TriggerSelectStep(yymsp[0].minor.yy331); } +#line 3003 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 279: -#line 862 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 289: +#line 918 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_RAISE, 0, 0, 0); - yygotominor.yy258->iColumn = OE_Ignore; - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy454 = sqlite3Expr(TK_RAISE, 0, 0, 0); + yygotominor.yy454->iColumn = OE_Ignore; + sqlite3ExprSpan(yygotominor.yy454, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); } -#line 2869 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 3012 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 280: -#line 867 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 290: +#line 923 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy98); - yygotominor.yy258->iColumn = yymsp[-3].minor.yy284; - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy454 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy406); + yygotominor.yy454->iColumn = yymsp[-3].minor.yy60; + sqlite3ExprSpan(yygotominor.yy454, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); } -#line 2878 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 3021 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 281: -#line 873 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = OE_Rollback;} -#line 2883 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 291: +#line 931 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = OE_Rollback;} +#line 3026 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 283: -#line 875 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy284 = OE_Fail;} -#line 2888 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 293: +#line 933 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{yygotominor.yy60 = OE_Fail;} +#line 3031 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 284: -#line 879 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 294: +#line 938 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy259); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy427); } -#line 2895 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 3038 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 285: -#line 884 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 295: +#line 944 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3Attach(pParse, &yymsp[-3].minor.yy98, &yymsp[-1].minor.yy98, yymsp[0].minor.yy292.type, &yymsp[0].minor.yy292.key); + sqlite3Attach(pParse, &yymsp[-3].minor.yy406, &yymsp[-1].minor.yy406, yymsp[0].minor.yy40.type, &yymsp[0].minor.yy40.key); } -#line 2902 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 3045 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 286: -#line 888 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy292.type = 0; } -#line 2907 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 296: +#line 948 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy40.type = 0; } +#line 3050 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 287: -#line 889 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy292.type=1; yygotominor.yy292.key = yymsp[0].minor.yy98; } -#line 2912 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 297: +#line 949 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy40.type=1; yygotominor.yy40.key = yymsp[0].minor.yy406; } +#line 3055 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 288: -#line 890 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy292.type=2; yygotominor.yy292.key = yymsp[0].minor.yy0; } -#line 2917 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" + case 298: +#line 950 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ yygotominor.yy40.type=2; yygotominor.yy40.key = yymsp[0].minor.yy0; } +#line 3060 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; - case 291: -#line 896 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" + case 301: +#line 956 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{ + sqlite3Detach(pParse, &yymsp[0].minor.yy406); +} +#line 3067 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 302: +#line 962 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Reindex(pParse, 0, 0);} +#line 3072 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 303: +#line 963 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy406, &yymsp[0].minor.yy406);} +#line 3077 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" + break; + case 304: +#line 968 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" { - sqlite3Detach(pParse, &yymsp[0].minor.yy98); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy427,&yymsp[0].minor.yy406); } -#line 2924 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 3084 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -2961,7 +3121,7 @@ static void yy_syntax_error( ){ sqlite3ParserARG_FETCH; #define TOKEN (yyminor.yy0) -#line 23 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.y" +#line 23 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.y" if( pParse->zErrMsg==0 ){ if( TOKEN.z[0] ){ @@ -2970,7 +3130,7 @@ static void yy_syntax_error( sqlite3ErrorMsg(pParse, "incomplete SQL statement"); } } -#line 2976 "/home/wez/play/php/pecl/pdo_sqlite/sqlite/src/parse.c" +#line 3136 "/home/wez/php5-HEAD/ext/pdo_sqlite/sqlite/src/parse.c" sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } diff --git a/ext/pdo_sqlite/sqlite/src/parse.h b/ext/pdo_sqlite/sqlite/src/parse.h index 547319ed70..e50789a834 100644 --- a/ext/pdo_sqlite/sqlite/src/parse.h +++ b/ext/pdo_sqlite/sqlite/src/parse.h @@ -55,75 +55,86 @@ #define TK_TRIGGER 55 #define TK_VACUUM 56 #define TK_VIEW 57 -#define TK_OR 58 -#define TK_AND 59 -#define TK_NOT 60 -#define TK_IS 61 -#define TK_BETWEEN 62 -#define TK_IN 63 -#define TK_ISNULL 64 -#define TK_NOTNULL 65 -#define TK_NE 66 -#define TK_EQ 67 -#define TK_GT 68 -#define TK_LE 69 -#define TK_LT 70 -#define TK_GE 71 -#define TK_BITAND 72 -#define TK_BITOR 73 -#define TK_LSHIFT 74 -#define TK_RSHIFT 75 -#define TK_PLUS 76 -#define TK_MINUS 77 -#define TK_STAR 78 -#define TK_SLASH 79 -#define TK_REM 80 -#define TK_CONCAT 81 -#define TK_UMINUS 82 -#define TK_UPLUS 83 -#define TK_BITNOT 84 -#define TK_STRING 85 -#define TK_JOIN_KW 86 -#define TK_CONSTRAINT 87 -#define TK_DEFAULT 88 -#define TK_NULL 89 -#define TK_PRIMARY 90 -#define TK_UNIQUE 91 -#define TK_CHECK 92 -#define TK_REFERENCES 93 -#define TK_COLLATE 94 -#define TK_ON 95 -#define TK_DELETE 96 -#define TK_UPDATE 97 -#define TK_INSERT 98 -#define TK_SET 99 -#define TK_DEFERRABLE 100 -#define TK_FOREIGN 101 -#define TK_DROP 102 -#define TK_UNION 103 -#define TK_ALL 104 -#define TK_INTERSECT 105 -#define TK_EXCEPT 106 -#define TK_SELECT 107 -#define TK_DISTINCT 108 -#define TK_DOT 109 -#define TK_FROM 110 -#define TK_JOIN 111 -#define TK_USING 112 -#define TK_ORDER 113 -#define TK_BY 114 -#define TK_GROUP 115 -#define TK_HAVING 116 -#define TK_LIMIT 117 -#define TK_WHERE 118 -#define TK_INTO 119 -#define TK_VALUES 120 -#define TK_INTEGER 121 -#define TK_FLOAT 122 -#define TK_BLOB 123 -#define TK_VARIABLE 124 -#define TK_CASE 125 -#define TK_WHEN 126 -#define TK_THEN 127 -#define TK_ELSE 128 -#define TK_INDEX 129 +#define TK_REINDEX 58 +#define TK_RENAME 59 +#define TK_CDATE 60 +#define TK_CTIME 61 +#define TK_CTIMESTAMP 62 +#define TK_ALTER 63 +#define TK_OR 64 +#define TK_AND 65 +#define TK_NOT 66 +#define TK_IS 67 +#define TK_BETWEEN 68 +#define TK_IN 69 +#define TK_ISNULL 70 +#define TK_NOTNULL 71 +#define TK_NE 72 +#define TK_EQ 73 +#define TK_GT 74 +#define TK_LE 75 +#define TK_LT 76 +#define TK_GE 77 +#define TK_ESCAPE 78 +#define TK_BITAND 79 +#define TK_BITOR 80 +#define TK_LSHIFT 81 +#define TK_RSHIFT 82 +#define TK_PLUS 83 +#define TK_MINUS 84 +#define TK_STAR 85 +#define TK_SLASH 86 +#define TK_REM 87 +#define TK_CONCAT 88 +#define TK_UMINUS 89 +#define TK_UPLUS 90 +#define TK_BITNOT 91 +#define TK_STRING 92 +#define TK_JOIN_KW 93 +#define TK_CONSTRAINT 94 +#define TK_DEFAULT 95 +#define TK_NULL 96 +#define TK_PRIMARY 97 +#define TK_UNIQUE 98 +#define TK_CHECK 99 +#define TK_REFERENCES 100 +#define TK_COLLATE 101 +#define TK_AUTOINCR 102 +#define TK_ON 103 +#define TK_DELETE 104 +#define TK_UPDATE 105 +#define TK_INSERT 106 +#define TK_SET 107 +#define TK_DEFERRABLE 108 +#define TK_FOREIGN 109 +#define TK_DROP 110 +#define TK_UNION 111 +#define TK_ALL 112 +#define TK_INTERSECT 113 +#define TK_EXCEPT 114 +#define TK_SELECT 115 +#define TK_DISTINCT 116 +#define TK_DOT 117 +#define TK_FROM 118 +#define TK_JOIN 119 +#define TK_USING 120 +#define TK_ORDER 121 +#define TK_BY 122 +#define TK_GROUP 123 +#define TK_HAVING 124 +#define TK_LIMIT 125 +#define TK_WHERE 126 +#define TK_INTO 127 +#define TK_VALUES 128 +#define TK_INTEGER 129 +#define TK_FLOAT 130 +#define TK_BLOB 131 +#define TK_REGISTER 132 +#define TK_VARIABLE 133 +#define TK_EXISTS 134 +#define TK_CASE 135 +#define TK_WHEN 136 +#define TK_THEN 137 +#define TK_ELSE 138 +#define TK_INDEX 139 +#define TK_TO 140 diff --git a/ext/pdo_sqlite/sqlite/src/parse.y b/ext/pdo_sqlite/sqlite/src/parse.y index 59dd563a6c..66398ac4f1 100644 --- a/ext/pdo_sqlite/sqlite/src/parse.y +++ b/ext/pdo_sqlite/sqlite/src/parse.y @@ -39,8 +39,8 @@ ** LIMIT clause of a SELECT statement. */ struct LimitVal { - int limit; /* The LIMIT value. -1 if there is no limit */ - int offset; /* The OFFSET. 0 if there is none */ + Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ + Expr *pOffset; /* The OFFSET expression. NULL if there is none */ }; /* @@ -81,11 +81,13 @@ struct AttachKey { int type; Token key; }; input ::= cmdlist. cmdlist ::= cmdlist ecmd. cmdlist ::= ecmd. -ecmd ::= explain cmdx SEMI. -ecmd ::= SEMI. cmdx ::= cmd. { sqlite3FinishCoding(pParse); } -explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } +ecmd ::= SEMI. +ecmd ::= explain cmdx SEMI. explain ::= . { sqlite3BeginParse(pParse, 0); } +%ifndef SQLITE_OMIT_EXPLAIN +explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } +%endif ///////////////////// Begin and end transactions. //////////////////////////// // @@ -144,7 +146,12 @@ id(A) ::= ID(X). {A = X;} DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT - TEMP TRIGGER VACUUM VIEW. + TEMP TRIGGER VACUUM VIEW +%ifdef SQLITE_OMIT_COMPOUND_SELECT + EXCEPT INTERSECT UNION +%endif + REINDEX RENAME CDATE CTIME CTIMESTAMP ALTER + . // Define operator precedence early so that this is the first occurance // of the operator tokens in the grammer. Keeping the operators together @@ -162,6 +169,7 @@ id(A) ::= ID(X). {A = X;} %right NOT. %left IS LIKE GLOB BETWEEN IN ISNULL NOTNULL NE EQ. %left GT LE LT GE. +%right ESCAPE. %left BITAND BITOR LSHIFT RSHIFT. %left PLUS MINUS. %left STAR SLASH REM. @@ -196,17 +204,24 @@ carglist ::= carglist carg. carglist ::= . carg ::= CONSTRAINT nm ccons. carg ::= ccons. -carg ::= DEFAULT ids(X). {sqlite3AddDefaultValue(pParse,&X,0);} -carg ::= DEFAULT plus_num(X). {sqlite3AddDefaultValue(pParse,&X,0);} -carg ::= DEFAULT minus_num(X). {sqlite3AddDefaultValue(pParse,&X,1);} -carg ::= DEFAULT NULL. +carg ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,X);} +carg ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,X);} +carg ::= DEFAULT MINUS term(X). { + Expr *p = sqlite3Expr(TK_UMINUS, X, 0, 0); + sqlite3AddDefaultValue(pParse,p); +} +carg ::= DEFAULT id(X). { + Expr *p = sqlite3Expr(TK_STRING, 0, 0, &X); + sqlite3AddDefaultValue(pParse,p); +} // In addition to the type name, we also care about the primary key and // UNIQUE constraints. // ccons ::= NULL onconf. ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);} -ccons ::= PRIMARY KEY sortorder onconf(R). {sqlite3AddPrimaryKey(pParse,0,R);} +ccons ::= PRIMARY KEY sortorder onconf(R) autoinc(I). + {sqlite3AddPrimaryKey(pParse,0,R,I);} ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0);} ccons ::= CHECK LP expr RP onconf. ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). @@ -214,6 +229,11 @@ ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);} ccons ::= COLLATE id(C). {sqlite3AddCollateType(pParse, C.z, C.n);} +// The optional AUTOINCREMENT keyword +%type autoinc {int} +autoinc(X) ::= . {X = 0;} +autoinc(X) ::= AUTOINCR. {X = 1;} + // The next group of rules parses the arguments to a REFERENCES clause // that determine if the referential integrity checking is deferred or // or immediate and which determine what action to take if a ref-integ @@ -249,8 +269,8 @@ conslist ::= conslist COMMA tcons. conslist ::= conslist tcons. conslist ::= tcons. tcons ::= CONSTRAINT nm. -tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R). - {sqlite3AddPrimaryKey(pParse,X,R);} +tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). + {sqlite3AddPrimaryKey(pParse,X,R,I);} tcons ::= UNIQUE LP idxlist(X) RP onconf(R). {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0);} tcons ::= CHECK expr onconf. @@ -285,12 +305,14 @@ cmd ::= DROP TABLE fullname(X). { ///////////////////// The CREATE VIEW statement ///////////////////////////// // +%ifndef SQLITE_OMIT_VIEW cmd ::= CREATE(X) temp(T) VIEW nm(Y) dbnm(Z) AS select(S). { sqlite3CreateView(pParse, &X, &Y, &Z, S, T); } cmd ::= DROP VIEW fullname(X). { sqlite3DropTable(pParse, X, 1); } +%endif // SQLITE_OMIT_VIEW //////////////////////// The SELECT statement ///////////////////////////////// // @@ -305,6 +327,7 @@ cmd ::= select(X). { %destructor oneselect {sqlite3SelectDelete($$);} select(A) ::= oneselect(X). {A = X;} +%ifndef SQLITE_OMIT_COMPOUND_SELECT select(A) ::= select(X) multiselect_op(Y) oneselect(Z). { if( Z ){ Z->op = Y; @@ -317,9 +340,10 @@ multiselect_op(A) ::= UNION(OP). {A = @OP;} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= INTERSECT(OP). {A = @OP;} multiselect_op(A) ::= EXCEPT(OP). {A = @OP;} +%endif // SQLITE_OMIT_COMPOUND_SELECT oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { - A = sqlite3SelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset); + A = sqlite3SelectNew(W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); } // The "distinct" nonterminal is true (1) if the DISTINCT keyword is @@ -394,31 +418,33 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). { else { sqlite3IdListDelete(U); } } } -seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP - as(Z) on_opt(N) using_opt(U). { - A = sqlite3SrcListAppend(X,0,0); - A->a[A->nSrc-1].pSelect = S; - if( Z.n ) sqlite3SrcListAddAlias(A,&Z); - if( N ){ - if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; } - else { sqlite3ExprDelete(N); } +%ifndef SQLITE_OMIT_SUBQUERY + seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP + as(Z) on_opt(N) using_opt(U). { + A = sqlite3SrcListAppend(X,0,0); + A->a[A->nSrc-1].pSelect = S; + if( Z.n ) sqlite3SrcListAddAlias(A,&Z); + if( N ){ + if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; } + else { sqlite3ExprDelete(N); } + } + if( U ){ + if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; } + else { sqlite3IdListDelete(U); } + } } - if( U ){ - if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; } - else { sqlite3IdListDelete(U); } + + // A seltablist_paren nonterminal represents anything in a FROM that + // is contained inside parentheses. This can be either a subquery or + // a grouping of table and subqueries. + // + %type seltablist_paren {Select*} + %destructor seltablist_paren {sqlite3SelectDelete($$);} + seltablist_paren(A) ::= select(S). {A = S;} + seltablist_paren(A) ::= seltablist(F). { + A = sqlite3SelectNew(0,F,0,0,0,0,0,0,0); } -} - -// A seltablist_paren nonterminal represents anything in a FROM that -// is contained inside parentheses. This can be either a subquery or -// a grouping of table and subqueries. -// -%type seltablist_paren {Select*} -%destructor seltablist_paren {sqlite3SelectDelete($$);} -seltablist_paren(A) ::= select(S). {A = S;} -seltablist_paren(A) ::= seltablist(F). { - A = sqlite3SelectNew(0,F,0,0,0,0,0,-1,0); -} +%endif // SQLITE_OMIT_SUBQUERY %type dbnm {Token} dbnm(A) ::= . {A.z=0; A.n=0;} @@ -487,12 +513,16 @@ having_opt(A) ::= . {A = 0;} having_opt(A) ::= HAVING expr(X). {A = X;} %type limit_opt {struct LimitVal} -limit_opt(A) ::= . {A.limit = -1; A.offset = 0;} -limit_opt(A) ::= LIMIT signed(X). {A.limit = X; A.offset = 0;} -limit_opt(A) ::= LIMIT signed(X) OFFSET signed(Y). - {A.limit = X; A.offset = Y;} -limit_opt(A) ::= LIMIT signed(X) COMMA signed(Y). - {A.limit = Y; A.offset = X;} +%destructor limit_opt { + sqlite3ExprDelete($$.pLimit); + sqlite3ExprDelete($$.pOffset); +} +limit_opt(A) ::= . {A.pLimit = 0; A.pOffset = 0;} +limit_opt(A) ::= LIMIT expr(X). {A.pLimit = X; A.pOffset = 0;} +limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). + {A.pLimit = X; A.pOffset = Y;} +limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). + {A.pOffset = X; A.pLimit = Y;} /////////////////////////// The DELETE statement ///////////////////////////// // @@ -550,9 +580,12 @@ inscollist(A) ::= nm(Y). {A = sqlite3IdListAppend(0,&Y);} %type expr {Expr*} %destructor expr {sqlite3ExprDelete($$);} +%type term {Expr*} +%destructor term {sqlite3ExprDelete($$);} +expr(A) ::= term(X). {A = X;} expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqlite3ExprSpan(A,&B,&E); } -expr(A) ::= NULL(X). {A = sqlite3Expr(@X, 0, 0, &X);} +term(A) ::= NULL(X). {A = sqlite3Expr(@X, 0, 0, &X);} expr(A) ::= ID(X). {A = sqlite3Expr(TK_ID, 0, 0, &X);} expr(A) ::= JOIN_KW(X). {A = sqlite3Expr(TK_ID, 0, 0, &X);} expr(A) ::= nm(X) DOT nm(Y). { @@ -567,10 +600,11 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); A = sqlite3Expr(TK_DOT, temp1, temp4, 0); } -expr(A) ::= INTEGER(X). {A = sqlite3Expr(@X, 0, 0, &X);} -expr(A) ::= FLOAT(X). {A = sqlite3Expr(@X, 0, 0, &X);} -expr(A) ::= STRING(X). {A = sqlite3Expr(@X, 0, 0, &X);} +term(A) ::= INTEGER(X). {A = sqlite3Expr(@X, 0, 0, &X);} +term(A) ::= FLOAT(X). {A = sqlite3Expr(@X, 0, 0, &X);} +term(A) ::= STRING(X). {A = sqlite3Expr(@X, 0, 0, &X);} expr(A) ::= BLOB(X). {A = sqlite3Expr(@X, 0, 0, &X);} +expr(A) ::= REGISTER(X). {A = sqlite3RegisterExpr(pParse, &X);} expr(A) ::= VARIABLE(X). { Token *pToken = &X; Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); @@ -584,6 +618,9 @@ expr(A) ::= ID(X) LP STAR RP(E). { A = sqlite3ExprFunction(0, &X); sqlite3ExprSpan(A,&X,&E); } +term(A) ::= CTIME(OP). {A = sqlite3Expr(@OP,0,0,0);} +term(A) ::= CDATE(OP). {A = sqlite3Expr(@OP,0,0,0);} +term(A) ::= CTIMESTAMP(OP). {A = sqlite3Expr(@OP,0,0,0);} expr(A) ::= expr(X) AND(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) OR(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) LT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} @@ -607,14 +644,21 @@ likeop(A) ::= LIKE. {A.opcode = TK_LIKE; A.not = 0;} likeop(A) ::= GLOB. {A.opcode = TK_GLOB; A.not = 0;} likeop(A) ::= NOT LIKE. {A.opcode = TK_LIKE; A.not = 1;} likeop(A) ::= NOT GLOB. {A.opcode = TK_GLOB; A.not = 1;} -expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE] { +%type escape {Expr*} +escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;} +escape(X) ::= . [ESCAPE] {X = 0;} +expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE] { ExprList *pList = sqlite3ExprListAppend(0, Y, 0); pList = sqlite3ExprListAppend(pList, X, 0); + if( E ){ + pList = sqlite3ExprListAppend(pList, E, 0); + } A = sqlite3ExprFunction(pList, 0); if( A ) A->op = OP.opcode; if( OP.not ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A, &X->span, &Y->span); } + expr(A) ::= expr(X) ISNULL(E). { A = sqlite3Expr(TK_ISNULL, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); @@ -651,11 +695,6 @@ expr(A) ::= PLUS(B) expr(X). [UPLUS] { A = sqlite3Expr(TK_UPLUS, X, 0, 0); sqlite3ExprSpan(A,&B,&X->span); } -expr(A) ::= LP(B) select(X) RP(E). { - A = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( A ) A->pSelect = X; - sqlite3ExprSpan(A,&B,&E); -} %type between_op {int} between_op(A) ::= BETWEEN. {A = 0;} between_op(A) ::= NOT BETWEEN. {A = 1;} @@ -667,29 +706,42 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&W->span,&Y->span); } -%type in_op {int} -in_op(A) ::= IN. {A = 0;} -in_op(A) ::= NOT IN. {A = 1;} -expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { - A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pList = Y; - if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); -} -expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] { - A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pSelect = Y; - if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); -} -expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { - SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z); - A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0); - if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y); -} - +%ifndef SQLITE_OMIT_SUBQUERY + %type in_op {int} + in_op(A) ::= IN. {A = 0;} + in_op(A) ::= NOT IN. {A = 1;} + expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { + A = sqlite3Expr(TK_IN, X, 0, 0); + if( A ) A->pList = Y; + if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); + sqlite3ExprSpan(A,&X->span,&E); + } + expr(A) ::= LP(B) select(X) RP(E). { + A = sqlite3Expr(TK_SELECT, 0, 0, 0); + if( A ) A->pSelect = X; + sqlite3ExprSpan(A,&B,&E); + } + expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] { + A = sqlite3Expr(TK_IN, X, 0, 0); + if( A ) A->pSelect = Y; + if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); + sqlite3ExprSpan(A,&X->span,&E); + } + expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { + SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z); + A = sqlite3Expr(TK_IN, X, 0, 0); + if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); + sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y); + } + expr(A) ::= EXISTS(B) LP select(Y) RP(E). { + Expr *p = A = sqlite3Expr(TK_EXISTS, 0, 0, 0); + if( p ){ + p->pSelect = Y; + sqlite3ExprSpan(p,&B,&E); + } + } +%endif // SQLITE_OMIT_SUBQUERY /* CASE expressions */ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { @@ -728,10 +780,10 @@ expritem(A) ::= . {A = 0;} ///////////////////////////// The CREATE INDEX command /////////////////////// // cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X) dbnm(D) - ON fullname(Y) LP idxlist(Z) RP(E) onconf(R). { + ON nm(Y) LP idxlist(Z) RP(E) onconf(R). { if( U!=OE_None ) U = R; if( U==OE_Default) U = OE_Abort; - sqlite3CreateIndex(pParse, &X, &D, Y, Z, U, &S, &E); + sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(0,&Y,0),Z,U, &S, &E); } %type uniqueflag {int} @@ -776,6 +828,7 @@ cmd ::= VACUUM nm. {sqlite3Vacuum(pParse,0);} ///////////////////////////// The PRAGMA command ///////////////////////////// // +%ifndef SQLITE_OMIT_PRAGMA cmd ::= PRAGMA nm(X) dbnm(Z) EQ nm(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);} cmd ::= PRAGMA nm(X) dbnm(Z) EQ ON(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);} cmd ::= PRAGMA nm(X) dbnm(Z) EQ plus_num(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);} @@ -784,6 +837,7 @@ cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). { } cmd ::= PRAGMA nm(X) dbnm(Z) LP nm(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);} cmd ::= PRAGMA nm(X) dbnm(Z). {sqlite3Pragma(pParse,&X,&Z,0,0);} +%endif // SQLITE_OMIT_PRAGMA plus_num(A) ::= plus_opt number(X). {A = X;} minus_num(A) ::= MINUS number(X). {A = X;} number(A) ::= INTEGER(X). {A = X;} @@ -793,6 +847,8 @@ plus_opt ::= . //////////////////////////// The CREATE TRIGGER command ///////////////////// +%ifndef SQLITE_OMIT_TRIGGER + cmd ::= CREATE trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). { Token all; all.z = A.z; @@ -869,6 +925,8 @@ expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). { A->iColumn = T; sqlite3ExprSpan(A, &X, &Y); } +%endif // !SQLITE_OMIT_TRIGGER + %type raisetype {int} raisetype(A) ::= ROLLBACK. {A = OE_Rollback;} raisetype(A) ::= ABORT. {A = OE_Abort;} @@ -876,9 +934,11 @@ raisetype(A) ::= FAIL. {A = OE_Fail;} //////////////////////// DROP TRIGGER statement ////////////////////////////// +%ifndef SQLITE_OMIT_TRIGGER cmd ::= DROP TRIGGER fullname(X). { sqlite3DropTrigger(pParse,X); } +%endif // !SQLITE_OMIT_TRIGGER //////////////////////// ATTACH DATABASE file AS name ///////////////////////// cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). { @@ -896,3 +956,16 @@ database_kw_opt ::= . cmd ::= DETACH database_kw_opt nm(D). { sqlite3Detach(pParse, &D); } + +////////////////////////// REINDEX collation ////////////////////////////////// +%ifndef SQLITE_OMIT_REINDEX +cmd ::= REINDEX. {sqlite3Reindex(pParse, 0, 0);} +cmd ::= REINDEX nm(X) dbnm(Y). {sqlite3Reindex(pParse, &X, &Y);} +%endif + +//////////////////////// ALTER TABLE table ... //////////////////////////////// +%ifndef SQLITE_OMIT_ALTERTABLE +cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). { + sqlite3AlterRenameTable(pParse,X,&Z); +} +%endif diff --git a/ext/pdo_sqlite/sqlite/src/pragma.c b/ext/pdo_sqlite/sqlite/src/pragma.c index 94a218632a..3c09a4b196 100644 --- a/ext/pdo_sqlite/sqlite/src/pragma.c +++ b/ext/pdo_sqlite/sqlite/src/pragma.c @@ -14,29 +14,18 @@ ** $Id$ */ #include "sqliteInt.h" +#include "os.h" #include +/* Ignore this whole file if pragmas are disabled +*/ +#ifndef SQLITE_OMIT_PRAGMA + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) # include "pager.h" # include "btree.h" #endif -/* -** Interpret the given string as a boolean value. -*/ -static int getBoolean(const u8 *z){ - static const u8 *azTrue[] = { "yes", "on", "true" }; - int i; - if( z[0]==0 ) return 0; - if( sqlite3IsNumber(z, 0, SQLITE_UTF8) ){ - return atoi(z); - } - for(i=0; idb; - if( db->temp_store==ts ) return SQLITE_OK; if( db->aDb[1].pBt!=0 ){ if( db->flags & SQLITE_InTrans ){ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " @@ -107,9 +96,25 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){ db->aDb[1].pBt = 0; sqlite3ResetInternalSchema(db, 0); } + return SQLITE_OK; +} + +/* +** If the TEMP database is open, close it and mark the database schema +** as needing reloading. This must be done when using the TEMP_STORE +** or DEFAULT_TEMP_STORE pragmas. +*/ +static int changeTempStorage(Parse *pParse, const char *zStorageType){ + int ts = getTempStore(zStorageType); + sqlite3 *db = pParse->db; + if( db->temp_store==ts ) return SQLITE_OK; + if( invalidateTempStorage( pParse ) != SQLITE_OK ){ + return SQLITE_ERROR; + } db->temp_store = ts; return SQLITE_OK; } +#endif /* ** Generate code to return a single integer value. @@ -130,35 +135,42 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, int value){ ** Also, implement the pragma. */ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ - static const struct { + static const struct sPragmaType { const char *zName; /* Name of the pragma */ int mask; /* Mask for the db->flags value */ } aPragma[] = { { "vdbe_trace", SQLITE_VdbeTrace }, { "sql_trace", SQLITE_SqlTrace }, { "vdbe_listing", SQLITE_VdbeListing }, -#if 1 /* FIX ME: Remove the following pragmas */ { "full_column_names", SQLITE_FullColNames }, { "short_column_names", SQLITE_ShortColNames }, { "count_changes", SQLITE_CountRows }, { "empty_result_callbacks", SQLITE_NullCallback }, -#endif + /* The following is VERY experimental */ + { "writable_schema", SQLITE_WriteSchema }, + { "omit_readlock", SQLITE_NoReadlock }, }; int i; - for(i=0; izName)==0 ){ sqlite3 *db = pParse->db; Vdbe *v; - if( zRight==0 ){ - v = sqlite3GetVdbe(pParse); - if( v ){ - returnSingleInt(pParse, - aPragma[i].zName, (db->flags&aPragma[i].mask)!=0); + v = sqlite3GetVdbe(pParse); + if( v ){ + if( zRight==0 ){ + returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); + }else{ + if( getBoolean(zRight) ){ + db->flags |= p->mask; + }else{ + db->flags &= ~p->mask; + } } - }else if( getBoolean(zRight) ){ - db->flags |= aPragma[i].mask; - }else{ - db->flags &= ~aPragma[i].mask; + /* If one of these pragmas is executed, any prepared statements + ** need to be recompiled. + */ + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); } return 1; } @@ -217,6 +229,7 @@ void sqlite3Pragma( goto pragma_out; } +#ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N @@ -281,10 +294,31 @@ void sqlite3Pragma( int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0; returnSingleInt(pParse, "page_size", size); }else{ - sqlite3BtreeSetPageSize(pBt, atoi(zRight), sqlite3BtreeGetReserve(pBt)); + sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1); } }else +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + /* + ** PRAGMA [database.]auto_vacuum + ** PRAGMA [database.]auto_vacuum=N + ** + ** Get or set the (boolean) value of the database 'auto-vacuum' parameter. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ + Btree *pBt = pDb->pBt; + if( !zRight ){ + int auto_vacuum = + pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM; + returnSingleInt(pParse, "auto_vacuum", auto_vacuum); + }else{ + sqlite3BtreeSetAutoVacuum(pBt, getBoolean(zRight)); + } + }else +#endif + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]cache_size ** PRAGMA [database.]cache_size=N @@ -330,6 +364,45 @@ void sqlite3Pragma( } }else + /* + ** PRAGMA temp_store_directory + ** PRAGMA temp_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the temp_store_directory flag. Changing + ** the value sets a specific directory to be used for temporary files. + ** Setting to a null string reverts to the default temporary directory search. + ** If temporary directory is changed, then invalidateTempStorage. + ** + */ + if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ + if( !zRight ){ + if( sqlite3_temp_directory ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC); + sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0); + sqlite3VdbeAddOp(v, OP_Callback, 1, 0); + } + }else{ + if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + goto pragma_out; + } + if( TEMP_STORE==0 + || (TEMP_STORE==1 && db->temp_store<=1) + || (TEMP_STORE==2 && db->temp_store==1) + ){ + invalidateTempStorage(pParse); + } + sqliteFree(sqlite3_temp_directory); + if( zRight[0] ){ + sqlite3_temp_directory = zRight; + zRight = 0; + }else{ + sqlite3_temp_directory = 0; + } + } + }else + /* ** PRAGMA [database.]synchronous ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL @@ -353,22 +426,14 @@ void sqlite3Pragma( } } }else - -#if 0 /* Used once during development. No longer needed */ - if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){ - if( getBoolean(zRight) ){ - sqlite3_always_code_trigger_setup = 1; - }else{ - sqlite3_always_code_trigger_setup = 0; - } - }else -#endif +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ if( flagPragma(pParse, zLeft, zRight) ){ /* The flagPragma() subroutine also generates any necessary code ** there is nothing more to do here */ }else +#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS /* ** PRAGMA table_info() ** @@ -401,8 +466,7 @@ void sqlite3Pragma( sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0); sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0); sqlite3VdbeAddOp(v, OP_Callback, 6, 0); } @@ -458,6 +522,40 @@ void sqlite3Pragma( } }else + if( sqlite3StrICmp(zLeft, "database_list")==0 ){ + int i; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeSetNumCols(v, 3); + sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); + sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); + sqlite3VdbeSetColName(v, 2, "file", P3_STATIC); + for(i=0; inDb; i++){ + if( db->aDb[i].pBt==0 ) continue; + assert( db->aDb[i].zName!=0 ); + sqlite3VdbeAddOp(v, OP_Integer, i, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, + sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); + sqlite3VdbeAddOp(v, OP_Callback, 3, 0); + } + }else + + if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ + int i = 0; + HashElem *p; + sqlite3VdbeSetNumCols(v, 2); + sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); + sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); + for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(p); + sqlite3VdbeAddOp(v, OP_Integer, i++, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0); + sqlite3VdbeAddOp(v, OP_Callback, 2, 0); + } + }else +#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ FKey *pFK; Table *pTab; @@ -491,24 +589,7 @@ void sqlite3Pragma( } } }else - - if( sqlite3StrICmp(zLeft, "database_list")==0 ){ - int i; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - sqlite3VdbeSetNumCols(v, 3); - sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); - sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); - sqlite3VdbeSetColName(v, 2, "file", P3_STATIC); - for(i=0; inDb; i++){ - if( db->aDb[i].pBt==0 ) continue; - assert( db->aDb[i].zName!=0 ); - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); - sqlite3VdbeAddOp(v, OP_Callback, 3, 0); - } - }else +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ @@ -521,6 +602,7 @@ void sqlite3Pragma( }else #endif +#ifndef SQLITE_OMIT_INTEGRITY_CHECK if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ int i, j, addr; @@ -645,6 +727,9 @@ void sqlite3Pragma( addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode)); }else +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_UTF16 /* ** PRAGMA encoding ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" @@ -715,6 +800,69 @@ void sqlite3Pragma( } } }else +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + /* + ** PRAGMA [database.]schema_version + ** PRAGMA [database.]schema_version = + ** + ** PRAGMA [database.]user_version + ** PRAGMA [database.]user_version = + ** + ** The pragma's schema_version and user_version are used to set or get + ** the value of the schema-version and user-version, respectively. Both + ** the schema-version and the user-version are 32-bit signed integers + ** stored in the database header. + ** + ** The schema-cookie is usually only manipulated internally by SQLite. It + ** is incremented by SQLite whenever the database schema is modified (by + ** creating or dropping a table or index). The schema version is used by + ** SQLite each time a query is executed to ensure that the internal cache + ** of the schema used when compiling the SQL query matches the schema of + ** the database against which the compiled query is actually executed. + ** Subverting this mechanism by using "PRAGMA schema_version" to modify + ** the schema-version is potentially dangerous and may lead to program + ** crashes or database corruption. Use with caution! + ** + ** The user-version is not used internally by SQLite. It may be used by + ** applications for any purpose. + */ + if( sqlite3StrICmp(zLeft, "schema_version")==0 || + sqlite3StrICmp(zLeft, "user_version")==0 ){ + + int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */ + if( zLeft[0]=='s' || zLeft[0]=='S' ){ + iCookie = 0; + }else{ + iCookie = 5; + } + + if( zRight ){ + /* Write the specified cookie value */ + static const VdbeOpList setCookie[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_Integer, 0, 0, 0}, /* 1 */ + { OP_SetCookie, 0, 0, 0}, /* 2 */ + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, atoi(zRight)); + sqlite3VdbeChangeP1(v, addr+2, iDb); + sqlite3VdbeChangeP2(v, addr+2, iCookie); + }else{ + /* Read the specified cookie value */ + static const VdbeOpList readCookie[] = { + { OP_ReadCookie, 0, 0, 0}, /* 0 */ + { OP_Callback, 1, 0, 0} + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP2(v, addr, iCookie); + sqlite3VdbeSetNumCols(v, 1); + } + } +#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* @@ -748,7 +896,17 @@ void sqlite3Pragma( #endif {} + + if( v ){ + /* Code an OP_Expire at the end of each PRAGMA program to cause + ** the VDBE implementing the pragma to expire. Most (all?) pragmas + ** are only valid for a single execution. + */ + sqlite3VdbeAddOp(v, OP_Expire, 1, 0); + } pragma_out: sqliteFree(zLeft); sqliteFree(zRight); } + +#endif /* SQLITE_OMIT_PRAGMA */ diff --git a/ext/pdo_sqlite/sqlite/src/printf.c b/ext/pdo_sqlite/sqlite/src/printf.c index 43e1286372..6e700771b4 100644 --- a/ext/pdo_sqlite/sqlite/src/printf.c +++ b/ext/pdo_sqlite/sqlite/src/printf.c @@ -99,6 +99,7 @@ typedef struct et_info { /* Information about each format field */ */ #define FLAG_SIGNED 1 /* True if the value to convert is signed */ #define FLAG_INTERN 2 /* True if for internal use only */ +#define FLAG_STRING 4 /* Allow infinity precision */ /* @@ -109,10 +110,10 @@ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etRADIX, 0, 0 }, - { 's', 0, 0, etSTRING, 0, 0 }, - { 'z', 0, 2, etDYNSTRING, 0, 0 }, - { 'q', 0, 0, etSQLESCAPE, 0, 0 }, - { 'Q', 0, 0, etSQLESCAPE2, 0, 0 }, + { 's', 0, 4, etSTRING, 0, 0 }, + { 'z', 0, 6, etDYNSTRING, 0, 0 }, + { 'q', 0, 4, etSQLESCAPE, 0, 0 }, + { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, { 'u', 10, 0, etRADIX, 0, 0 }, @@ -296,8 +297,6 @@ static int vxprintf( c = *++fmt; } } - /* Limit the precision to prevent overflowing buf[] during conversion */ - if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40; }else{ precision = -1; } @@ -328,6 +327,11 @@ static int vxprintf( } zExtra = 0; + /* Limit the precision to prevent overflowing buf[] during conversion */ + if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){ + precision = etBUFSIZE-40; + } + /* ** At this point, variables are initialized as follows: ** @@ -563,13 +567,15 @@ static int vxprintf( case etSQLESCAPE2: { int i, j, n, c, isnull; + int needQuote; char *arg = va_arg(ap,char*); isnull = arg==0; if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); for(i=n=0; (c=arg[i])!=0; i++){ if( c=='\'' ) n++; } - n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0); + needQuote = !isnull && xtype==etSQLESCAPE2; + n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ bufpt = zExtra = sqliteMalloc( n ); if( bufpt==0 ) return -1; @@ -577,12 +583,12 @@ static int vxprintf( bufpt = buf; } j = 0; - if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; + if( needQuote ) bufpt[j++] = '\''; for(i=0; (c=arg[i])!=0; i++){ bufpt[j++] = c; if( c=='\'' ) bufpt[j++] = c; } - if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; + if( needQuote ) bufpt[j++] = '\''; bufpt[j] = 0; length = j; if( precision>=0 && precisionpOrderBy = pOrderBy; pNew->isDistinct = isDistinct; pNew->op = TK_SELECT; - pNew->nLimit = nLimit; - pNew->nOffset = nOffset; + pNew->pLimit = pLimit; + pNew->pOffset = pOffset; pNew->iLimit = -1; pNew->iOffset = -1; } @@ -160,7 +163,9 @@ static void setToken(Token *p, const char *z){ static void addWhereTerm( const char *zCol, /* Name of the column */ const Table *pTab1, /* First table */ + const char *zAlias1, /* Alias for first table. May be NULL */ const Table *pTab2, /* Second table */ + const char *zAlias2, /* Alias for second table. May be NULL */ Expr **ppExpr /* Add the equality term to this expression */ ){ Token dummy; @@ -171,9 +176,15 @@ static void addWhereTerm( setToken(&dummy, zCol); pE1a = sqlite3Expr(TK_ID, 0, 0, &dummy); pE2a = sqlite3Expr(TK_ID, 0, 0, &dummy); - setToken(&dummy, pTab1->zName); + if( zAlias1==0 ){ + zAlias1 = pTab1->zName; + } + setToken(&dummy, zAlias1); pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy); - setToken(&dummy, pTab2->zName); + if( zAlias2==0 ){ + zAlias2 = pTab2->zName; + } + setToken(&dummy, zAlias2); pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy); pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0); pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0); @@ -241,7 +252,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ for(j=0; jnCol; j++){ char *zName = pLeftTab->aCol[j].zName; if( columnIndex(pRightTab, zName)>=0 ){ - addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere); + addWhereTerm(zName, pLeftTab, pLeft->zAlias, + pRightTab, pRight->zAlias, &p->pWhere); } } } @@ -279,7 +291,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ "not present in both tables", zName); return 1; } - addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere); + addWhereTerm(zName, pLeftTab, pLeft->zAlias, + pRightTab, pRight->zAlias, &p->pWhere); } } } @@ -298,20 +311,11 @@ void sqlite3SelectDelete(Select *p){ sqlite3ExprDelete(p->pHaving); sqlite3ExprListDelete(p->pOrderBy); sqlite3SelectDelete(p->pPrior); - sqliteFree(p->zSelect); + sqlite3ExprDelete(p->pLimit); + sqlite3ExprDelete(p->pOffset); sqliteFree(p); } -/* -** Delete the aggregate information from the parse structure. -*/ -static void sqliteAggregateInfoReset(Parse *pParse){ - sqliteFree(pParse->aAgg); - pParse->aAgg = 0; - pParse->nAgg = 0; - pParse->useAgg = 0; -} - /* ** Insert code into "v" that will push the record on the top of the ** stack into the sorter. @@ -336,9 +340,10 @@ static void codeLimiter( int nPop /* Number of times to pop stack when jumping */ ){ if( p->iOffset>=0 ){ - int addr = sqlite3VdbeCurrentAddr(v) + 2; + int addr = sqlite3VdbeCurrentAddr(v) + 3; if( nPop>0 ) addr++; - sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, addr); + sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, 0); + sqlite3VdbeAddOp(v, OP_IfMemPos, p->iOffset, addr); if( nPop>0 ){ sqlite3VdbeAddOp(v, OP_Pop, nPop, 0); } @@ -425,6 +430,7 @@ static int selectInnerLoop( } switch( eDest ){ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* In this mode, write each query result to the key of the temporary ** table iParm. */ @@ -436,6 +442,20 @@ static int selectInnerLoop( break; } + /* Construct a record from the query result, but instead of + ** saving that record, use it as a key to delete elements from + ** the temporary table iParm. + */ + case SRT_Except: { + int addr; + addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT); + sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); + sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3); + sqlite3VdbeAddOp(v, OP_Delete, iParm, 0); + break; + } +#endif + /* Store the result as data using a unique key. */ case SRT_Table: @@ -451,19 +471,7 @@ static int selectInnerLoop( break; } - /* Construct a record from the query result, but instead of - ** saving that record, use it as a key to delete elements from - ** the temporary table iParm. - */ - case SRT_Except: { - int addr; - addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT); - sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); - sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3); - sqlite3VdbeAddOp(v, OP_Delete, iParm, 0); - break; - } - +#ifndef SQLITE_OMIT_SUBQUERY /* If we are creating a set for an "expr IN (SELECT ...)" construct, ** then there should be a single item on the stack. Write this ** item into the set table with bogus data. @@ -493,6 +501,7 @@ static int selectInnerLoop( ** store the results in the appropriate memory cell and break out ** of the scan loop. */ + case SRT_Exists: case SRT_Mem: { assert( nColumn==1 ); if( pOrderBy ){ @@ -503,6 +512,7 @@ static int selectInnerLoop( } break; } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ /* Send the data to the callback function. */ @@ -531,6 +541,7 @@ static int selectInnerLoop( break; } +#if !defined(SQLITE_OMIT_TRIGGER) /* Discard the results. This is used for SELECT statements inside ** the body of a TRIGGER. The purpose of such selects is to call ** user-defined functions that have side effects. We do not care @@ -541,6 +552,7 @@ static int selectInnerLoop( sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); break; } +#endif } return 0; } @@ -596,6 +608,7 @@ static void generateSortTail( sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0); break; } +#ifndef SQLITE_OMIT_SUBQUERY case SRT_Set: { assert( nColumn==1 ); sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); @@ -606,12 +619,14 @@ static void generateSortTail( sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); break; } + case SRT_Exists: case SRT_Mem: { assert( nColumn==1 ); sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); sqlite3VdbeAddOp(v, OP_Goto, 0, end1); break; } +#endif case SRT_Callback: case SRT_Subroutine: { int i; @@ -650,18 +665,31 @@ static void generateSortTail( ** The declaration type for an expression is either TEXT, NUMERIC or ANY. ** The declaration type for a ROWID field is INTEGER. */ -static const char *columnType(Parse *pParse, SrcList *pTabList, Expr *pExpr){ +static const char *columnType(NameContext *pNC, Expr *pExpr){ char const *zType; int j; - if( pExpr==0 || pTabList==0 ) return 0; + if( pExpr==0 || pNC->pSrcList==0 ) return 0; + + /* The TK_AS operator can only occur in ORDER BY, GROUP BY, HAVING, + ** and LIMIT clauses. But pExpr originates in the result set of a + ** SELECT. So pExpr can never contain an AS operator. + */ + assert( pExpr->op!=TK_AS ); switch( pExpr->op ){ case TK_COLUMN: { - Table *pTab; + Table *pTab = 0; int iCol = pExpr->iColumn; - for(j=0; jnSrc && pTabList->a[j].iCursor!=pExpr->iTable; j++){} - assert( jnSrc ); - pTab = pTabList->a[j].pTab; + while( pNC && !pTab ){ + SrcList *pTabList = pNC->pSrcList; + for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); + if( jnSrc ){ + pTab = pTabList->a[j].pTab; + }else{ + pNC = pNC->pNext; + } + } + assert( pTab ); if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); if( iCol<0 ){ @@ -671,14 +699,16 @@ static const char *columnType(Parse *pParse, SrcList *pTabList, Expr *pExpr){ } break; } - case TK_AS: - zType = columnType(pParse, pTabList, pExpr->pLeft); - break; +#ifndef SQLITE_OMIT_SUBQUERY case TK_SELECT: { + NameContext sNC; Select *pS = pExpr->pSelect; - zType = columnType(pParse, pS->pSrc, pS->pEList->a[0].pExpr); + sNC.pSrcList = pExpr->pSelect->pSrc; + sNC.pNext = pNC; + zType = columnType(&sNC, pS->pEList->a[0].pExpr); break; } +#endif default: zType = 0; } @@ -697,9 +727,11 @@ static void generateColumnTypes( ){ Vdbe *v = pParse->pVdbe; int i; + NameContext sNC; + sNC.pSrcList = pTabList; for(i=0; inExpr; i++){ Expr *p = pEList->a[i].pExpr; - const char *zType = columnType(pParse, pTabList, p); + const char *zType = columnType(&sNC, p); if( zType==0 ) continue; /* The vdbe must make it's own copy of the column-type, in case the ** schema is reset before this virtual machine is deleted. @@ -723,10 +755,12 @@ static void generateColumnNames( sqlite3 *db = pParse->db; int fullNames, shortNames; +#ifndef SQLITE_OMIT_EXPLAIN /* If this is an EXPLAIN, skip this step */ if( pParse->explain ){ return; } +#endif assert( v!=0 ); if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return; @@ -753,7 +787,7 @@ static void generateColumnNames( if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); if( iCol<0 ){ - zCol = "_ROWID_"; + zCol = "rowid"; }else{ zCol = pTab->aCol[iCol].zName; } @@ -768,7 +802,7 @@ static void generateColumnNames( sqlite3SetString(&zName, zTab, ".", zCol, 0); sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC); }else{ - sqlite3VdbeSetColName(v, i, zCol, 0); + sqlite3VdbeSetColName(v, i, zCol, strlen(zCol)); } }else if( p->span.z && p->span.z[0] ){ sqlite3VdbeSetColName(v, i, p->span.z, p->span.n); @@ -783,6 +817,7 @@ static void generateColumnNames( generateColumnTypes(pParse, pTabList, pEList); } +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Name of the connection operator, used for error messages. */ @@ -796,11 +831,12 @@ static const char *selectOpName(int id){ } return z; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ /* ** Forward declaration */ -static int fillInColumnList(Parse*, Select*); +static int prepSelectStmt(Parse*, Select*); /* ** Given a SELECT statement, generate a Table structure that describes @@ -812,7 +848,10 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ ExprList *pEList; Column *aCol, *pCol; - if( fillInColumnList(pParse, pSelect) ){ + if( prepSelectStmt(pParse, pSelect) ){ + return 0; + } + if( sqlite3SelectResolve(pParse, pSelect, 0) ){ return 0; } pTab = sqliteMalloc( sizeof(Table) ); @@ -825,38 +864,55 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ assert( pTab->nCol>0 ); pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); for(i=0, pCol=aCol; inCol; i++, pCol++){ - Expr *pR; + Expr *p, *pR; char *zType; char *zName; - Expr *p = pEList->a[i].pExpr; + char *zBasename; + int cnt; + NameContext sNC; + + /* Get an appropriate name for the column + */ + p = pEList->a[i].pExpr; assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); if( (zName = pEList->a[i].zName)!=0 ){ + /* If the column contains an "AS " phrase, use as the name */ zName = sqliteStrDup(zName); }else if( p->op==TK_DOT - && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ - int cnt; + && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ + /* For columns of the from A.B use B as the name */ zName = sqlite3MPrintf("%T", &pR->token); - for(j=cnt=0; jtoken, ++cnt); - j = -1; - } - } }else if( p->span.z && p->span.z[0] ){ + /* Use the original text of the column expression as its name */ zName = sqlite3MPrintf("%T", &p->span); }else{ + /* If all else fails, make up a name */ zName = sqlite3MPrintf("column%d", i+1); } sqlite3Dequote(zName); + + /* Make sure the column name is unique. If the name is not unique, + ** append a integer to the name so that it becomes unique. + */ + zBasename = zName; + for(j=cnt=0; jzName = zName; - zType = sqliteStrDup(columnType(pParse, pSelect->pSrc ,p)); + /* Get the typename, type affinity, and collating sequence for the + ** column. + */ + sNC.pSrcList = pSelect->pSrc; + zType = sqliteStrDup(columnType(&sNC, p)); pCol->zType = zType; - pCol->affinity = SQLITE_AFF_NUMERIC; - if( zType ){ - pCol->affinity = sqlite3AffinityType(zType, strlen(zType)); - } + pCol->affinity = sqlite3ExprAffinity(p); pCol->pColl = sqlite3ExprCollSeq(pParse, p); if( !pCol->pColl ){ pCol->pColl = pParse->db->pDfltColl; @@ -867,20 +923,24 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ } /* -** For the given SELECT statement, do three things. +** Prepare a SELECT statement for processing by doing the following +** things: +** +** (1) Make sure VDBE cursor numbers have been assigned to every +** element of the FROM clause. ** -** (1) Fill in the pTabList->a[].pTab fields in the SrcList that -** defines the set of tables that should be scanned. For views, +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** defines FROM clause. When views appear in the FROM clause, ** fill pTabList->a[].pSelect with a copy of the SELECT statement ** that implements the view. A copy is made of the view's SELECT ** statement so that we can freely modify or delete that statement ** without worrying about messing up the presistent representation ** of the view. ** -** (2) Add terms to the WHERE clause to accomodate the NATURAL keyword +** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword ** on joins and the ON and USING clause of joins. ** -** (3) Scan the list of columns in the result set (pEList) looking +** (4) Scan the list of columns in the result set (pEList) looking ** for instances of the "*" operator or the TABLE.* operator. ** If found, expand each "*" to be every column in every table ** and TABLE.* to be every column in TABLE. @@ -888,7 +948,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ ** Return 0 on success. If there are problems, leave an error message ** in pParse and return non-zero. */ -static int fillInColumnList(Parse *pParse, Select *p){ +static int prepSelectStmt(Parse *pParse, Select *p){ int i, j, k, rc; SrcList *pTabList; ExprList *pEList; @@ -899,14 +959,24 @@ static int fillInColumnList(Parse *pParse, Select *p){ pTabList = p->pSrc; pEList = p->pEList; - /* Look up every table in the table list. + /* Make sure cursor numbers have been assigned to all entries in + ** the FROM clause of the SELECT statement. + */ + sqlite3SrcListAssignCursors(pParse, p->pSrc); + + /* Look up every table named in the FROM clause of the select. If + ** an entry of the FROM clause is a subquery instead of a table or view, + ** then create a transient table structure to describe the subquery. */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - if( pFrom->pTab ){ - /* This routine has run before! No need to continue */ + if( pFrom->pTab!=0 ){ + /* This statement has already been prepared. There is no need + ** to go further. */ + assert( i==0 ); return 0; } if( pFrom->zName==0 ){ +#ifndef SQLITE_OMIT_SUBQUERY /* A sub-query in the FROM clause of a SELECT */ assert( pFrom->pSelect!=0 ); if( pFrom->zAlias==0 ){ @@ -923,6 +993,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ ** pTab is not pointing to a persistent table structure that defines ** part of the schema. */ pTab->isTransient = 1; +#endif }else{ /* An ordinary table or view name in the FROM clause */ pFrom->pTab = pTab = @@ -930,6 +1001,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ if( pTab==0 ){ return 1; } +#ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ /* We reach here if the named table is a really a view */ if( sqlite3ViewGetColumnNames(pParse, pTab) ){ @@ -944,6 +1016,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ pFrom->pSelect = sqlite3SelectDup(pTab->pSelect); } } +#endif } } @@ -1042,7 +1115,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ pExpr = pRight; pExpr->span = pExpr->token; } - pNew = sqlite3ExprListAppend(pNew, pExpr, 0); + pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token); } } if( !tableSeen ){ @@ -1075,6 +1148,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ ** will be left pointing to a deallocated Table structure after the ** DROP and a coredump will occur the next time the VIEW is used. */ +#if 0 void sqlite3SelectUnbind(Select *p){ int i; SrcList *pSrc = p->pSrc; @@ -1093,7 +1167,9 @@ void sqlite3SelectUnbind(Select *p){ } } } +#endif +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** This routine associates entries in an ORDER BY expression list with ** columns in a result. For each ORDER BY expression, the opcode of @@ -1122,7 +1198,7 @@ static int matchOrderbyToColumn( if( mustComplete ){ for(i=0; inExpr; i++){ pOrderBy->a[i].done = 0; } } - if( fillInColumnList(pParse, pSelect) ){ + if( prepSelectStmt(pParse, pSelect) ){ return 1; } if( pSelect->pPrior ){ @@ -1165,6 +1241,7 @@ static int matchOrderbyToColumn( pE->op = TK_COLUMN; pE->iColumn = iCol; pE->iTable = iTable; + pE->iAgg = -1; pOrderBy->a[i].done = 1; } if( iCol<0 && mustComplete ){ @@ -1176,6 +1253,7 @@ static int matchOrderbyToColumn( } return nErr; } +#endif /* #ifndef SQLITE_OMIT_COMPOUND_SELECT */ /* ** Get a VDBE for the given parser context. Create a new one if necessary. @@ -1191,12 +1269,12 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ /* ** Compute the iLimit and iOffset fields of the SELECT based on the -** nLimit and nOffset fields. nLimit and nOffset hold the integers +** pLimit and pOffset expressions. nLimit and nOffset hold the expressions ** that appear in the original SQL statement after the LIMIT and OFFSET -** keywords. Or that hold -1 and 0 if those keywords are omitted. -** iLimit and iOffset are the integer memory register numbers for -** counters used to compute the limit and offset. If there is no -** limit and/or offset, then iLimit and iOffset are negative. +** keywords. Or NULL if those keywords are omitted. iLimit and iOffset +** are the integer memory register numbers for counters used to compute +** the limit and offset. If there is no limit and/or offset, then +** iLimit and iOffset are negative. ** ** This routine changes the values if iLimit and iOffset only if ** a limit or offset is defined by nLimit and nOffset. iLimit and @@ -1209,28 +1287,29 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ */ static void computeLimitRegisters(Parse *pParse, Select *p){ /* - ** If the comparison is p->nLimit>0 then "LIMIT 0" shows - ** all rows. It is the same as no limit. If the comparision is - ** p->nLimit>=0 then "LIMIT 0" show no rows at all. ** "LIMIT -1" always shows all rows. There is some ** contraversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ - if( p->nLimit>=0 ){ + if( p->pLimit ){ int iMem = pParse->nMem++; Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; - sqlite3VdbeAddOp(v, OP_Integer, -p->nLimit, 0); + sqlite3ExprCode(pParse, p->pLimit); + sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); + sqlite3VdbeAddOp(v, OP_Negative, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1); VdbeComment((v, "# LIMIT counter")); p->iLimit = iMem; } - if( p->nOffset>0 ){ + if( p->pOffset ){ int iMem = pParse->nMem++; Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; - sqlite3VdbeAddOp(v, OP_Integer, -p->nOffset, 0); + sqlite3ExprCode(pParse, p->pOffset); + sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); + sqlite3VdbeAddOp(v, OP_Negative, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1); VdbeComment((v, "# OFFSET counter")); p->iOffset = iMem; @@ -1260,7 +1339,7 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){ Vdbe *v = pParse->pVdbe; int addr; - if( fillInColumnList(pParse, p) ){ + if( prepSelectStmt(pParse, p) ){ return 0; } nColumn = p->pEList->nExpr; @@ -1282,6 +1361,7 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){ return addr; } +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Add the address "addr" to the set of all OpenTemp opcode addresses ** that are being accumulated in p->ppOpenTemp. @@ -1294,7 +1374,9 @@ static int multiSelectOpenTempAddr(Select *p, int addr){ pList->a[pList->nId-1].idx = addr; return SQLITE_OK; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Return the appropriate collating sequence for the iCol-th column of ** the result set for the compound-select statement "p". Return NULL if @@ -1315,7 +1397,9 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ } return pRet; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** This routine is called to process a query that is really the union ** or intersection of two or more separate queries. @@ -1375,7 +1459,7 @@ static int multiSelect( rc = 1; goto multi_select_end; } - if( pPrior->nLimit>=0 || pPrior->nOffset>0 ){ + if( pPrior->pLimit ){ sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", selectOpName(p->op)); rc = 1; @@ -1416,8 +1500,9 @@ static int multiSelect( switch( p->op ){ case TK_ALL: { if( p->pOrderBy==0 ){ - pPrior->nLimit = p->nLimit; - pPrior->nOffset = p->nOffset; + assert( !pPrior->pLimit ); + pPrior->pLimit = p->pLimit; + pPrior->pOffset = p->pOffset; rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff); if( rc ){ goto multi_select_end; @@ -1425,8 +1510,8 @@ static int multiSelect( p->pPrior = 0; p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; - p->nLimit = -1; - p->nOffset = 0; + p->pLimit = 0; + p->pOffset = 0; rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff); p->pPrior = pPrior; if( rc ){ @@ -1441,12 +1526,12 @@ static int multiSelect( int unionTab; /* Cursor number of the temporary table holding result */ int op = 0; /* One of the SRT_ operations to apply to self */ int priorOp; /* The SRT_ operation to apply to prior selects */ - int nLimit, nOffset; /* Saved values of p->nLimit and p->nOffset */ - ExprList *pOrderBy; /* The ORDER BY clause for the right SELECT */ + Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ + ExprList *pOrderBy; /* The ORDER BY clause for the right SELECT */ int addr; priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union; - if( eDest==priorOp && p->pOrderBy==0 && p->nLimit<0 && p->nOffset==0 ){ + if( eDest==priorOp && p->pOrderBy==0 && !p->pLimit && !p->pOffset ){ /* We can reuse a temporary table generated by a SELECT to our ** right. */ @@ -1476,6 +1561,7 @@ static int multiSelect( /* Code the SELECT statements to our left */ + assert( !pPrior->pOrderBy ); rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff); if( rc ){ goto multi_select_end; @@ -1491,15 +1577,18 @@ static int multiSelect( p->pPrior = 0; pOrderBy = p->pOrderBy; p->pOrderBy = 0; - nLimit = p->nLimit; - p->nLimit = -1; - nOffset = p->nOffset; - p->nOffset = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff); p->pPrior = pPrior; p->pOrderBy = pOrderBy; - p->nLimit = nLimit; - p->nOffset = nOffset; + sqlite3ExprDelete(p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; + p->iLimit = -1; + p->iOffset = -1; if( rc ){ goto multi_select_end; } @@ -1536,7 +1625,7 @@ static int multiSelect( case TK_INTERSECT: { int tab1, tab2; int iCont, iBreak, iStart; - int nLimit, nOffset; + Expr *pLimit, *pOffset; int addr; /* INTERSECT is different from the others since it requires @@ -1578,14 +1667,15 @@ static int multiSelect( assert( nAddrpPrior = 0; - nLimit = p->nLimit; - p->nLimit = -1; - nOffset = p->nOffset; - p->nOffset = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff); p->pPrior = pPrior; - p->nLimit = nLimit; - p->nOffset = nOffset; + sqlite3ExprDelete(p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; if( rc ){ goto multi_select_end; } @@ -1681,7 +1771,7 @@ static int multiSelect( Expr *pExpr = pOrderByTerm->pExpr; char *zName = pOrderByTerm->zName; assert( pExpr->op==TK_COLUMN && pExpr->iColumnpColl ); + /* assert( !pExpr->pColl ); */ if( zName ){ pExpr->pColl = sqlite3LocateCollSeq(pParse, zName, -1); }else{ @@ -1704,7 +1794,9 @@ multi_select_end: p->ppOpenTemp = 0; return rc; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_VIEW /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th @@ -1719,6 +1811,7 @@ multi_select_end: ** of the subquery rather the result set of the subquery. */ static void substExprList(ExprList*,int,ExprList*); /* Forward Decl */ +static void substSelect(Select *, int, ExprList *); /* Forward Decl */ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){ if( pExpr==0 ) return; if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ @@ -1742,22 +1835,34 @@ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){ pExpr->iAgg = pNew->iAgg; sqlite3TokenCopy(&pExpr->token, &pNew->token); sqlite3TokenCopy(&pExpr->span, &pNew->span); + pExpr->pSelect = sqlite3SelectDup(pNew->pSelect); + pExpr->flags = pNew->flags; } }else{ substExpr(pExpr->pLeft, iTable, pEList); substExpr(pExpr->pRight, iTable, pEList); + substSelect(pExpr->pSelect, iTable, pEList); substExprList(pExpr->pList, iTable, pEList); } } -static void -substExprList(ExprList *pList, int iTable, ExprList *pEList){ +static void substExprList(ExprList *pList, int iTable, ExprList *pEList){ int i; if( pList==0 ) return; for(i=0; inExpr; i++){ substExpr(pList->a[i].pExpr, iTable, pEList); } } +static void substSelect(Select *p, int iTable, ExprList *pEList){ + if( !p ) return; + substExprList(p->pEList, iTable, pEList); + substExprList(p->pGroupBy, iTable, pEList); + substExprList(p->pOrderBy, iTable, pEList); + substExpr(p->pHaving, iTable, pEList); + substExpr(p->pWhere, iTable, pEList); +} +#endif /* !defined(SQLITE_OMIT_VIEW) */ +#ifndef SQLITE_OMIT_VIEW /* ** This routine attempts to flatten subqueries in order to speed ** execution. It returns 1 if it makes changes and 0 if no flattening @@ -1855,11 +1960,13 @@ static int flattenSubquery( if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; pSubSrc = pSub->pSrc; assert( pSubSrc ); + if( (pSub->pLimit && p->pLimit) || pSub->pOffset || + (pSub->pLimit && isAgg) ) return 0; if( pSubSrc->nSrc==0 ) return 0; - if( (pSub->isDistinct || pSub->nLimit>=0) && (pSrc->nSrc>1 || isAgg) ){ + if( pSub->isDistinct && (pSrc->nSrc>1 || isAgg) ){ return 0; } - if( (p->isDistinct || p->nLimit>=0) && subqueryIsAgg ) return 0; + if( p->isDistinct && subqueryIsAgg ) return 0; if( p->pOrderBy && pSub->pOrderBy ) return 0; /* Restriction 3: If the subquery is a join, make sure the subquery is @@ -1991,17 +2098,13 @@ static int flattenSubquery( */ p->isDistinct = p->isDistinct || pSub->isDistinct; - /* Transfer the limit expression from the subquery to the outer - ** query. + /* + ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; */ - if( pSub->nLimit>=0 ){ - if( p->nLimit<0 ){ - p->nLimit = pSub->nLimit; - }else if( p->nLimit+p->nOffset > pSub->nLimit+pSub->nOffset ){ - p->nLimit = pSub->nLimit + pSub->nOffset - p->nOffset; - } + if( pSub->pLimit ){ + p->pLimit = pSub->pLimit; + pSub->pLimit = 0; } - p->nOffset += pSub->nOffset; /* Finially, delete what is left of the subquery and return ** success. @@ -2009,6 +2112,7 @@ static int flattenSubquery( sqlite3SelectDelete(pSub); return 1; } +#endif /* SQLITE_OMIT_VIEW */ /* ** Analyze the SELECT statement passed in as an argument to see if it @@ -2042,7 +2146,6 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ ExprList *pEList, *pList, eList; struct ExprList_item eListItem; SrcList *pSrc; - /* Check to see if this query is a simple min() or max() query. Return ** zero if it is not. @@ -2115,17 +2218,25 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ if( pIdx==0 ){ sqlite3VdbeAddOp(v, seekOp, base, 0); }else{ + /* Even though the cursor used to open the index here is closed + ** as soon as a single value has been read from it, allocate it + ** using (pParse->nTab++) to prevent the cursor id from being + ** reused. This is important for statements of the form + ** "INSERT INTO x SELECT max() FROM x". + */ + int iIdx; + iIdx = pParse->nTab++; sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0); - sqlite3VdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, + sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, (char*)&pIdx->keyInfo, P3_KEYINFO); if( seekOp==OP_Rewind ){ sqlite3VdbeAddOp(v, OP_String, 0, 0); sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0); seekOp = OP_MoveGt; } - sqlite3VdbeAddOp(v, seekOp, base+1, 0); - sqlite3VdbeAddOp(v, OP_IdxRecno, base+1, 0); - sqlite3VdbeAddOp(v, OP_Close, base+1, 0); + sqlite3VdbeAddOp(v, seekOp, iIdx, 0); + sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0); + sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } eList.nExpr = 1; @@ -2148,41 +2259,193 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ ** corresponding entry in the result set. */ static int processOrderGroupBy( - Parse *pParse, /* Parsing context */ + NameContext *pNC, /* Name context of the SELECT statement. */ ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ - SrcList *pTabList, /* The FROM clause */ - ExprList *pEList, /* The result set */ - int isAgg, /* True if aggregate functions are involved */ const char *zType /* Either "ORDER" or "GROUP", as appropriate */ ){ int i; + ExprList *pEList = pNC->pEList; /* The result set of the SELECT */ + Parse *pParse = pNC->pParse; /* The result set of the SELECT */ + assert( pEList ); + if( pOrderBy==0 ) return 0; for(i=0; inExpr; i++){ int iCol; Expr *pE = pOrderBy->a[i].pExpr; - if( sqlite3ExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){ - sqlite3ExprDelete(pE); - pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); - } - if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList, pE, isAgg, 0) ){ - return 1; - } - if( sqlite3ExprIsConstant(pE) ){ - if( sqlite3ExprIsInteger(pE, &iCol)==0 ){ - sqlite3ErrorMsg(pParse, - "%s BY terms must not be non-integer constants", zType); - return 1; - }else if( iCol<=0 || iCol>pEList->nExpr ){ + if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( iCol>0 && iCol<=pEList->nExpr ){ + sqlite3ExprDelete(pE); + pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); + }else{ sqlite3ErrorMsg(pParse, "%s BY column number %d out of range - should be " "between 1 and %d", zType, iCol, pEList->nExpr); return 1; } } + if( sqlite3ExprResolveNames(pNC, pE) ){ + return 1; + } + if( sqlite3ExprIsConstant(pE) ){ + sqlite3ErrorMsg(pParse, + "%s BY terms must not be non-integer constants", zType); + return 1; + } } return 0; } +/* +** This routine resolves any names used in the result set of the +** supplied SELECT statement. If the SELECT statement being resolved +** is a sub-select, then pOuterNC is a pointer to the NameContext +** of the parent SELECT. +*/ +int sqlite3SelectResolve( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* The outer name context. May be NULL. */ +){ + ExprList *pEList; /* Result set. */ + int i; /* For-loop variable used in multiple places */ + NameContext sNC; /* Local name-context */ + + /* If this routine has run before, return immediately. */ + if( p->isResolved ){ + assert( !pOuterNC ); + return SQLITE_OK; + } + p->isResolved = 1; + + /* If there have already been errors, do nothing. */ + if( pParse->nErr>0 ){ + return SQLITE_ERROR; + } + + /* Prepare the select statement. This call will allocate all cursors + ** required to handle the tables and subqueries in the FROM clause. + */ + if( prepSelectStmt(pParse, p) ){ + return SQLITE_ERROR; + } + + /* Resolve the expressions in the LIMIT and OFFSET clauses. These + ** are not allowed to refer to any names, so pass an empty NameContext. + */ + sNC.pParse = pParse; + sNC.hasAgg = 0; + sNC.nErr = 0; + sNC.nRef = 0; + sNC.pEList = 0; + sNC.allowAgg = 0; + sNC.pSrcList = 0; + sNC.pNext = 0; + if( sqlite3ExprResolveNames(&sNC, p->pLimit) || + sqlite3ExprResolveNames(&sNC, p->pOffset) ){ + return SQLITE_ERROR; + } + + /* Set up the local name-context to pass to ExprResolveNames() to + ** resolve the expression-list. + */ + sNC.allowAgg = 1; + sNC.pSrcList = p->pSrc; + sNC.pNext = pOuterNC; + + /* NameContext.nDepth stores the depth of recursion for this query. For + ** an outer query (e.g. SELECT * FROM sqlite_master) this is 1. For + ** a subquery it is 2. For a subquery of a subquery, 3. And so on. + ** Parse.nMaxDepth is the maximum depth for any subquery resolved so + ** far. This is used to determine the number of aggregate contexts + ** required at runtime. + */ + sNC.nDepth = (pOuterNC?pOuterNC->nDepth+1:1); + if( sNC.nDepth>pParse->nMaxDepth ){ + pParse->nMaxDepth = sNC.nDepth; + } + + /* Resolve names in the result set. */ + pEList = p->pEList; + if( !pEList ) return SQLITE_ERROR; + for(i=0; inExpr; i++){ + Expr *pX = pEList->a[i].pExpr; + if( sqlite3ExprResolveNames(&sNC, pX) ){ + return SQLITE_ERROR; + } + } + + /* If there are no aggregate functions in the result-set, and no GROUP BY + ** expression, do not allow aggregates in any of the other expressions. + */ + assert( !p->isAgg ); + if( p->pGroupBy || sNC.hasAgg ){ + p->isAgg = 1; + }else{ + sNC.allowAgg = 0; + } + + /* If a HAVING clause is present, then there must be a GROUP BY clause. + */ + if( p->pHaving && !p->pGroupBy ){ + sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); + return SQLITE_ERROR; + } + + /* Add the expression list to the name-context before parsing the + ** other expressions in the SELECT statement. This is so that + ** expressions in the WHERE clause (etc.) can refer to expressions by + ** aliases in the result set. + ** + ** Minor point: If this is the case, then the expression will be + ** re-evaluated for each reference to it. + */ + sNC.pEList = p->pEList; + if( sqlite3ExprResolveNames(&sNC, p->pWhere) || + sqlite3ExprResolveNames(&sNC, p->pHaving) || + processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") || + processOrderGroupBy(&sNC, p->pGroupBy, "GROUP") + ){ + return SQLITE_ERROR; + } + + return SQLITE_OK; +} + +/* +** An instance of the following struct is used by sqlite3Select() +** to save aggregate related information from the Parse object +** at the start of each call and to restore it at the end. See +** saveAggregateInfo() and restoreAggregateInfo(). +*/ +struct AggregateInfo { + int nAgg; + AggExpr *aAgg; +}; +typedef struct AggregateInfo AggregateInfo; + +/* +** Copy aggregate related information from the Parse structure +** into the AggregateInfo structure. Zero the aggregate related +** values in the Parse struct. +*/ +static void saveAggregateInfo(Parse *pParse, AggregateInfo *pInfo){ + pInfo->aAgg = pParse->aAgg; + pInfo->nAgg = pParse->nAgg; + pParse->aAgg = 0; + pParse->nAgg = 0; +} + +/* +** Copy aggregate related information from the AggregateInfo struct +** back into the Parse structure. The aggregate related information +** currently stored in the Parse structure is deleted. +*/ +static void restoreAggregateInfo(Parse *pParse, AggregateInfo *pInfo){ + sqliteFree(pParse->aAgg); + pParse->aAgg = pInfo->aAgg; + pParse->nAgg = pInfo->nAgg; +} + /* ** Generate code for the given SELECT statement. ** @@ -2248,7 +2511,7 @@ int sqlite3Select( int i; WhereInfo *pWInfo; Vdbe *v; - int isAgg = 0; /* True for select lists like "count(*)" */ + int isAgg; /* True for select lists like "count(*)" */ ExprList *pEList; /* List of columns to extract. */ SrcList *pTabList; /* List of tables to select from */ Expr *pWhere; /* The WHERE clause. May be NULL */ @@ -2258,28 +2521,39 @@ int sqlite3Select( int isDistinct; /* True if the DISTINCT keyword is present */ int distinct; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ + AggregateInfo sAggInfo; if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1; if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* If there is are a sequence of queries, do the earlier ones first. */ if( p->pPrior ){ return multiSelect(pParse, p, eDest, iParm, aff); } +#endif + + saveAggregateInfo(pParse, &sAggInfo); + pOrderBy = p->pOrderBy; + if( eDest==SRT_Union || eDest==SRT_Except || eDest==SRT_Discard ){ + p->pOrderBy = 0; + } + if( sqlite3SelectResolve(pParse, p, 0) ){ + goto select_end; + } + p->pOrderBy = pOrderBy; /* Make local copies of the parameters for this query. */ pTabList = p->pSrc; pWhere = p->pWhere; - pOrderBy = p->pOrderBy; pGroupBy = p->pGroupBy; pHaving = p->pHaving; + isAgg = p->isAgg; isDistinct = p->isDistinct; - - /* Allocate VDBE cursors for each table in the FROM clause - */ - sqlite3SrcListAssignCursors(pParse, pTabList); + pEList = p->pEList; + if( pEList==0 ) goto select_end; /* ** Do not even attempt to generate any code if we have already seen @@ -2287,25 +2561,17 @@ int sqlite3Select( */ if( pParse->nErr>0 ) goto select_end; - /* Expand any "*" terms in the result set. (For example the "*" in - ** "SELECT * FROM t1") The fillInColumnlist() routine also does some - ** other housekeeping - see the header comment for details. - */ - if( fillInColumnList(pParse, p) ){ - goto select_end; - } - pWhere = p->pWhere; - pEList = p->pEList; - if( pEList==0 ) goto select_end; - /* If writing to memory or generating a set ** only a single column may be output. */ + assert( eDest!=SRT_Exists || pEList->nExpr==1 ); +#ifndef SQLITE_OMIT_SUBQUERY if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){ sqlite3ErrorMsg(pParse, "only a single result allowed for " "a SELECT that is part of an expression"); goto select_end; } +#endif /* ORDER BY is ignored for some destinations. */ @@ -2319,35 +2585,6 @@ int sqlite3Select( break; } - /* At this point, we should have allocated all the cursors that we - ** need to handle subquerys and temporary tables. - ** - ** Resolve the column names and do a semantics check on all the expressions. - */ - for(i=0; inExpr; i++){ - if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0, pEList->a[i].pExpr, - 1, &isAgg) ){ - goto select_end; - } - } - if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList, pWhere, 0, 0) ){ - goto select_end; - } - if( pHaving ){ - if( pGroupBy==0 ){ - sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); - goto select_end; - } - if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList,pHaving,1,&isAgg) ){ - goto select_end; - } - } - if( processOrderGroupBy(pParse, pOrderBy, pTabList, pEList, isAgg, "ORDER") - || processOrderGroupBy(pParse, pGroupBy, pTabList, pEList, isAgg, "GROUP") - ){ - goto select_end; - } - /* Begin generating code. */ v = sqlite3GetVdbe(pParse); @@ -2362,6 +2599,7 @@ int sqlite3Select( /* Generate code for all sub-queries in the FROM clause */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; inSrc; i++){ const char *zSavedAuthContext = 0; int needRestoreContext; @@ -2388,6 +2626,7 @@ int sqlite3Select( pHaving = p->pHaving; isDistinct = p->isDistinct; } +#endif /* Check for the special case of a min() or max() function by itself ** in the result set. @@ -2400,11 +2639,13 @@ int sqlite3Select( /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ +#ifndef SQLITE_OMIT_VIEW if( pParent && pParentAgg && flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; - return rc; + goto select_end; } +#endif /* If there is an ORDER BY clause, resolve any collation sequences ** names that have been explicitly specified. @@ -2434,28 +2675,32 @@ int sqlite3Select( /* Do an analysis of aggregate expressions. */ - sqliteAggregateInfoReset(pParse); if( isAgg || pGroupBy ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + assert( pParse->nAgg==0 ); isAgg = 1; for(i=0; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(pParse, pEList->a[i].pExpr) ){ + if( sqlite3ExprAnalyzeAggregates(&sNC, pEList->a[i].pExpr) ){ goto select_end; } } if( pGroupBy ){ for(i=0; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(pParse, pGroupBy->a[i].pExpr) ){ + if( sqlite3ExprAnalyzeAggregates(&sNC, pGroupBy->a[i].pExpr) ){ goto select_end; } } } - if( pHaving && sqlite3ExprAnalyzeAggregates(pParse, pHaving) ){ + if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){ goto select_end; } if( pOrderBy ){ for(i=0; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(pParse, pOrderBy->a[i].pExpr) ){ + if( sqlite3ExprAnalyzeAggregates(&sNC, pOrderBy->a[i].pExpr) ){ goto select_end; } } @@ -2490,10 +2735,10 @@ int sqlite3Select( } } - /* Initialize the memory cell to NULL + /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists */ - if( eDest==SRT_Mem ){ - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + if( eDest==SRT_Mem || eDest==SRT_Exists ){ + sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); } @@ -2508,8 +2753,8 @@ int sqlite3Select( /* Begin the database scan */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, - pGroupBy ? 0 : &pOrderBy); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, + pGroupBy ? 0 : &pOrderBy, p->pFetch); if( pWInfo==0 ) goto select_end; /* Use the standard inner loop if we are not dealing with @@ -2527,8 +2772,9 @@ int sqlite3Select( */ else{ AggExpr *pAgg; + int lbl1 = 0; + pParse->fillAgg = 1; if( pGroupBy ){ - int lbl1; for(i=0; inExpr; i++){ sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr); } @@ -2537,11 +2783,14 @@ int sqlite3Select( sqlite3VdbeAddOp(v, OP_MakeRecord, pGroupBy->nExpr, 0); lbl1 = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_AggFocus, 0, lbl1); - for(i=0, pAgg=pParse->aAgg; inAgg; i++, pAgg++){ - if( pAgg->isAgg ) continue; - sqlite3ExprCode(pParse, pAgg->pExpr); - sqlite3VdbeAddOp(v, OP_AggSet, 0, i); - } + } + for(i=0, pAgg=pParse->aAgg; inAgg; i++, pAgg++){ + if( pAgg->isAgg ) continue; + sqlite3ExprCode(pParse, pAgg->pExpr); + sqlite3VdbeAddOp(v, OP_AggSet, 0, i); + } + pParse->fillAgg = 0; + if( lbl1<0 ){ sqlite3VdbeResolveLabel(v, lbl1); } for(i=0, pAgg=pParse->aAgg; inAgg; i++, pAgg++){ @@ -2581,7 +2830,6 @@ int sqlite3Select( int endagg = sqlite3VdbeMakeLabel(v); int startagg; startagg = sqlite3VdbeAddOp(v, OP_AggNext, 0, endagg); - pParse->useAgg = 1; if( pHaving ){ sqlite3ExprIfFalse(pParse, pHaving, startagg, 1); } @@ -2592,7 +2840,6 @@ int sqlite3Select( sqlite3VdbeAddOp(v, OP_Goto, 0, startagg); sqlite3VdbeResolveLabel(v, endagg); sqlite3VdbeAddOp(v, OP_Noop, 0, 0); - pParse->useAgg = 0; } /* If there is an ORDER BY clause, then we need to sort the results @@ -2602,6 +2849,7 @@ int sqlite3Select( generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm); } +#ifndef SQLITE_OMIT_SUBQUERY /* If this was a subquery, we have now converted the subquery into a ** temporary table. So delete the subquery structure from the parent ** to prevent this subquery from being evaluated again and to force the @@ -2613,6 +2861,7 @@ int sqlite3Select( sqlite3SelectDelete(p); pParent->pSrc->a[parentTab].pSelect = 0; } +#endif /* The SELECT was successfully coded. Set the return code to 0 ** to indicate no errors. @@ -2623,6 +2872,6 @@ int sqlite3Select( ** successful coding of the SELECT. */ select_end: - sqliteAggregateInfoReset(pParse); + restoreAggregateInfo(pParse, &sAggInfo); return rc; } diff --git a/ext/pdo_sqlite/sqlite/src/shell.c b/ext/pdo_sqlite/sqlite/src/shell.c index bdd13cc931..2b369a210e 100644 --- a/ext/pdo_sqlite/sqlite/src/shell.c +++ b/ext/pdo_sqlite/sqlite/src/shell.c @@ -196,7 +196,9 @@ static char *one_input_line(const char *zPrior, FILE *in){ zPrompt = mainPrompt; } zResult = readline(zPrompt); +#if defined(HAVE_READLINE) && HAVE_READLINE==1 if( zResult ) add_history(zResult); +#endif return zResult; } @@ -360,6 +362,7 @@ static void output_csv(struct callback_data *p, const char *z, int bSep){ } } +#ifdef SIGINT /* ** This routine runs when the user presses Ctrl-C */ @@ -367,6 +370,7 @@ static void interrupt_handler(int NotUsed){ seenInterrupt = 1; if( db ) sqlite3_interrupt(db); } +#endif /* ** This is the callback routine that the SQLite library @@ -652,7 +656,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ zType = azArg[1]; zSql = azArg[2]; - fprintf(p->out, "%s;\n", zSql); + if( strcasecmp(zTable,"sqlite_sequence")!=0 ){ + fprintf(p->out, "%s;\n", zSql); + }else{ + fprintf(p->out, "DELETE FROM sqlite_sequence;\n"); + } if( strcmp(zType, "table")==0 ){ sqlite3_stmt *pTableInfo = 0; @@ -746,7 +754,7 @@ static char zHelp[] = ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" ".indices TABLE Show names of all indices on TABLE\n" - ".mode MODE ?TABLE? Set output mode where MODE is on of:\n" + ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " csv Comma-separated values\n" " column Left-aligned columns. (See .width)\n" " html HTML
code\n" @@ -882,6 +890,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ data.colWidth[0] = 3; data.colWidth[1] = 15; data.colWidth[2] = 58; + data.cnt = 0; sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); @@ -1677,7 +1686,11 @@ int main(int argc, char **argv){ if( i", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The trailing string is often "alpha" or "beta". +** For example "3.1.1beta". +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*100000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +*/ +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif +#define SQLITE_VERSION_NUMBER --VERSION-NUMBER-- /* ** The version string is also compiled into the library so that a program @@ -44,6 +60,12 @@ extern "C" { extern const char sqlite3_version[]; const char *sqlite3_libversion(void); +/* +** Return the value of the SQLITE_VERSION_NUMBER macro when the +** library was compiled. +*/ +int sqlite3_libversion_number(void); + /* ** Each open sqlite database is represented by an instance of the ** following opaque structure. @@ -309,7 +331,7 @@ int sqlite3_busy_timeout(sqlite3*, int ms); ** pass the result data pointer to sqlite3_free_table() in order to ** release the memory that was malloc-ed. Because of the way the ** malloc() happens, the calling function must not try to call -** malloc() directly. Only sqlite3_free_table() is able to release +** free() directly. Only sqlite3_free_table() is able to release ** the memory properly and safely. ** ** The return value of this routine is the same as from sqlite3_exec(). @@ -428,6 +450,8 @@ int sqlite3_set_authorizer( #define SQLITE_UPDATE 23 /* Table Name Column Name */ #define SQLITE_ATTACH 24 /* Filename NULL */ #define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ /* @@ -448,8 +472,8 @@ void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); /* ** This routine configures a callback function - the progress callback - that ** is invoked periodically during long running calls to sqlite3_exec(), -** sqlite3_step() and sqlite3_get_table(). An example use for this API is to keep -** a GUI updated during a large query. +** sqlite3_step() and sqlite3_get_table(). An example use for this API is to +** keep a GUI updated during a large query. ** ** The progress callback is invoked once for every N virtual machine opcodes, ** where N is the second argument to this function. The progress callback @@ -606,14 +630,19 @@ typedef struct Mem sqlite3_value; /* ** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(), -** one or more literals can be replace by a wildcard "?" or ":N:" where -** N is an integer. These value of these wildcard literals can be set -** using the routines listed below. +** one or more literals can be replace by parameters "?" or ":AAA" or +** "$VVV" where AAA is an identifer and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The value of these parameters (also called "host parameter names") can +** be set using the routines listed below. ** ** In every case, the first parameter is a pointer to the sqlite3_stmt ** structure returned from sqlite3_prepare(). The second parameter is the -** index of the wildcard. The first "?" has an index of 1. ":N:" wildcards -** use the index N. +** index of the parameter. The first parameter as an index of 1. For +** named parameters (":AAA" or "$VVV") you can use +** sqlite3_bind_parameter_index() to get the correct index value given +** the parameters name. If the same named parameter occurs more than +** once, it is assigned the same index each time. ** ** The fifth parameter to sqlite3_bind_blob(), sqlite3_bind_text(), and ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or @@ -624,8 +653,8 @@ typedef struct Mem sqlite3_value; ** own private copy of the data. ** ** The sqlite3_bind_* routine must be called before sqlite3_step() after -** an sqlite3_prepare() or sqlite3_reset(). Unbound wildcards are interpreted -** as NULL. +** an sqlite3_prepare() or sqlite3_reset(). Unbound parameterss are +** interpreted as NULL. */ int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); @@ -637,16 +666,16 @@ int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); /* -** Return the number of wildcards in a compiled SQL statement. This +** Return the number of parameters in a compiled SQL statement. This ** routine was added to support DBD::SQLite. */ int sqlite3_bind_parameter_count(sqlite3_stmt*); /* -** Return the name of the i-th parameter. Ordinary wildcards "?" are -** nameless and a NULL is returned. For wildcards of the form :N or -** $vvvv the complete text of the wildcard is returned. -** NULL is returned if the index is out of range. +** Return the name of the i-th parameter. Ordinary parameters "?" are +** nameless and a NULL is returned. For parameters of the form :AAA or +** $VVV the complete text of the parameter name is returned, including +** the initial ":" or "$". NULL is returned if the index is out of range. */ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); @@ -657,6 +686,13 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); */ int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); +/* +** Set all the parameters in the compiled SQL statement to NULL. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + /* ** Return the number of columns in the result set returned by the compiled ** SQL statement. This routine returns 0 if pStmt is an SQL statement @@ -1148,17 +1184,41 @@ int sqlite3_rekey( ); /* -** If the following global variable is made to point to a constant +** Sleep for a little while. The second parameter is the number of +** miliseconds to sleep for. +** +** If the operating system does not support sleep requests with +** milisecond time resolution, then the time will be rounded up to +** the nearest second. The number of miliseconds of sleep actually +** requested from the operating system is returned. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_sleep(int); + +/* +** Return TRUE (non-zero) of the statement supplied as an argument needs +** to be recompiled. A statement needs to be recompiled whenever the +** execution environment changes in a way that would alter the program +** that sqlite3_prepare() generates. For example, if new functions or +** collating sequences are registered or if an authorizer function is +** added or changed. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_expired(sqlite3_stmt*); + +/* +** If the following global variable is made to point to a ** string which is the name of a directory, then all temporary files ** created by SQLite will be placed in that directory. If this variable ** is NULL pointer, then SQLite does a search for an appropriate temporary ** file directory. ** -** This variable should only be changed when there are no open databases. -** Once sqlite3_open() has been called, this variable should not be changed -** until all database connections are closed. +** Once sqlite3_open() has been called, changing this variable will invalidate the +** current temporary database, if any. */ -extern const char *sqlite3_temp_directory; +extern char *sqlite3_temp_directory; #ifdef __cplusplus } /* End of the 'extern "C"' block */ diff --git a/ext/pdo_sqlite/sqlite/src/sqliteInt.h b/ext/pdo_sqlite/sqlite/src/sqliteInt.h index b4fa474ba9..a9dde13186 100644 --- a/ext/pdo_sqlite/sqlite/src/sqliteInt.h +++ b/ext/pdo_sqlite/sqlite/src/sqliteInt.h @@ -47,13 +47,25 @@ #include #include #include +#include /* ** The maximum number of in-memory pages to use for the main database -** table and for temporary tables. +** table and for temporary tables. Internally, the MAX_PAGES and +** TEMP_PAGES macros are used. To override the default values at +** compilation time, the SQLITE_DEFAULT_CACHE_SIZE and +** SQLITE_DEFAULT_TEMP_CACHE_SIZE macros should be set. */ -#define MAX_PAGES 2000 -#define TEMP_PAGES 500 +#ifdef SQLITE_DEFAULT_CACHE_SIZE +# define MAX_PAGES SQLITE_DEFAULT_CACHE_SIZE +#else +# define MAX_PAGES 2000 +#endif +#ifdef SQLITE_DEFAULT_TEMP_CACHE_SIZE +# define TEMP_PAGES SQLITE_DEFAULT_TEMP_CACHE_SIZE +#else +# define TEMP_PAGES 500 +#endif /* ** If the following macro is set to 1, then NULL values are considered @@ -102,10 +114,28 @@ ** a minimum. */ /* #define SQLITE_OMIT_AUTHORIZATION 1 */ -/* #define SQLITE_OMIT_INMEMORYDB 1 */ +/* #define SQLITE_OMIT_MEMORYDB 1 */ /* #define SQLITE_OMIT_VACUUM 1 */ /* #define SQLITE_OMIT_DATETIME_FUNCS 1 */ /* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */ +/* #define SQLITE_OMIT_AUTOVACUUM */ +/* #define SQLITE_OMIT_ALTERTABLE */ + +/* +** Provide a default value for TEMP_STORE in case it is not specified +** on the command-line +*/ +#ifndef TEMP_STORE +# define TEMP_STORE 1 +#endif + +/* +** GCC does not define the offsetof() macro so we'll have to do it +** ourselves. +*/ +#ifndef offsetof +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) +#endif /* ** Integers of known sizes. These typedefs might change for architectures @@ -213,7 +243,7 @@ struct BusyHandler { ** each malloc() and free(). This output can be analyzed ** by an AWK script to determine if there are any leaks. */ -#ifdef SQLITE_DEBUG +#ifdef SQLITE_MEMDEBUG # define sqliteMalloc(X) sqlite3Malloc_(X,1,__FILE__,__LINE__) # define sqliteMallocRaw(X) sqlite3Malloc_(X,0,__FILE__,__LINE__) # define sqliteFree(X) sqlite3Free_(X,__FILE__,__LINE__) @@ -239,10 +269,11 @@ extern int sqlite3_malloc_failed; ** The following global variables are used for testing and debugging ** only. They only work if SQLITE_DEBUG is defined. */ -#ifdef SQLITE_DEBUG -extern int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ -extern int sqlite3_nFree; /* Number of sqliteFree() calls */ -extern int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */ +#ifdef SQLITE_MEMDEBUG +extern int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ +extern int sqlite3_nFree; /* Number of sqliteFree() calls */ +extern int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */ +extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */ #endif /* @@ -296,6 +327,8 @@ typedef struct AuthContext AuthContext; typedef struct KeyClass KeyClass; typedef struct CollSeq CollSeq; typedef struct KeyInfo KeyInfo; +typedef struct NameContext NameContext; +typedef struct Fetch Fetch; /* ** Each database file to be accessed by the system is an instance @@ -316,7 +349,8 @@ struct Db { u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ u8 safety_level; /* How aggressive at synching data to disk */ int cache_size; /* Number of pages to use in the cache */ - void *pAux; /* Auxiliary data. Usually NULL */ + Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ + void *pAux; /* Auxiliary data. Usually NULL */ void (*xFreeAux)(void*); /* Routine to free pAux */ }; @@ -408,7 +442,6 @@ struct sqlite3 { void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif - int errCode; /* Most recent error code (SQLITE_*) */ u8 enc; /* Text encoding for this database. */ u8 autoCommit; /* The auto-commit flag. */ @@ -417,9 +450,8 @@ struct sqlite3 { void *pCollNeededArg; sqlite3_value *pValue; /* Value used for transient conversions */ sqlite3_value *pErr; /* Most recent error message */ - char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ - char *zErrMsg16; /* Most recent error message (UTF-8 encoded) */ + char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ }; /* @@ -443,6 +475,9 @@ struct sqlite3 { /* result set is empty */ #define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ +#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ +#define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when + ** accessing read-only databases */ /* ** Possible values for the sqlite.magic field. @@ -478,7 +513,7 @@ struct FuncDef { */ struct Column { char *zName; /* Name of this column */ - char *zDflt; /* Default value of this column */ + Expr *pDflt; /* Default value of this column */ char *zType; /* Data type for this column */ CollSeq *pColl; /* Collating sequence. If NULL, use the default */ u8 notNull; /* True if there is a NOT NULL constraint */ @@ -572,6 +607,7 @@ struct Table { u8 isTransient; /* True if automatically deleted when VDBE finishes */ u8 hasPrimKey; /* True if there exists a primary key */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ + u8 autoInc; /* True if the integer primary key is autoincrement */ Trigger *pTrigger; /* List of SQL triggers on this table */ FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ @@ -759,6 +795,12 @@ struct Token { ** marker (a question mark character '?' in the original SQL) then the ** Expr.iTable holds the index number for that variable. ** +** If the expression is a subquery then Expr.iColumn holds an integer +** register number containing the result of the subquery. If the +** subquery gives a constant result, then iTable is -1. If the subquery +** gives a different answer at different times during statement processing +** then iTable is the address of a subroutine that computes the subquery. +** ** The Expr.pSelect field points to a SELECT statement. The SELECT might ** be the right operand of an IN operator. Or, if a scalar SELECT appears ** in an expression the opcode is TK_SELECT and Expr.pSelect is the only @@ -777,8 +819,9 @@ struct Expr { Token span; /* Complete text of the expression */ int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the ** iColumn-th field of the iTable-th table. */ - int iAgg; /* When op==TK_COLUMN and pParse->useAgg==TRUE, pull + int iAgg; /* When op==TK_COLUMN and pParse->fillAgg==FALSE, pull ** result from the iAgg-th element of the aggregator */ + int iAggCtx; /* The value to pass as P1 of OP_AggGet. */ Select *pSelect; /* When the expression is a sub-select. Also the ** right side of " IN (