From: Ilia Alshanetsky Date: Sun, 28 Aug 2005 16:53:27 +0000 (+0000) Subject: Upgraded bundled SQLite library for PDO:SQLite to 3.2.5 (step 1) X-Git-Tag: php-5.1.0RC2_PRE~60 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6aae12cc16e79cbeb51032f5b2822d29410c142;p=php Upgraded bundled SQLite library for PDO:SQLite to 3.2.5 (step 1) --- diff --git a/ext/pdo_sqlite/config.m4 b/ext/pdo_sqlite/config.m4 index 20d8c57d0c..4c781fcac3 100644 --- a/ext/pdo_sqlite/config.m4 +++ b/ext/pdo_sqlite/config.m4 @@ -75,11 +75,11 @@ if test "$PHP_PDO_SQLITE" != "no"; then sqlite/src/main.c sqlite/src/os_mac.c sqlite/src/os_unix.c sqlite/src/os_win.c \ sqlite/src/pager.c sqlite/src/pragma.c sqlite/src/prepare.c \ sqlite/src/printf.c sqlite/src/random.c sqlite/src/select.c \ - sqlite/src/table.c sqlite/src/tokenize.c \ + sqlite/src/table.c sqlite/src/tokenize.c sqlite/src/analyze.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/alter.c sqlite/src/experimental.c" + sqlite/src/alter.c sqlite/src/vdbefifo.c sqlite/src/experimental.c" PHP_NEW_EXTENSION(pdo_sqlite, $php_pdo_sqlite_sources_core $pdo_sqlite_sources, diff --git a/ext/pdo_sqlite/config.w32 b/ext/pdo_sqlite/config.w32 index 297423f045..fed572403a 100644 --- a/ext/pdo_sqlite/config.w32 +++ b/ext/pdo_sqlite/config.w32 @@ -23,8 +23,8 @@ if (PHP_PDO_SQLITE != "no") { ADD_SOURCES(configure_module_dirname + "/sqlite/src", "attach.c auth.c btree.c build.c callback.c date.c delete.c expr.c func.c hash.c insert.c \ legacy.c main.c os_mac.c os_unix.c os_win.c pager.c pragma.c prepare.c printf.c random.c \ - select.c table.c tokenize.c trigger.c update.c utf.c util.c vacuum.c vdbeapi.c \ - vdbeaux.c vdbe.c vdbemem.c where.c parse.c opcodes.c alter.c experimental.c", "pdo_sqlite"); + select.c table.c tokenize.c trigger.c update.c utf.c util.c vacuum.c vdbeapi.c analyze.c \ + vdbeaux.c vdbe.c vdbemem.c vdbefifo.c where.c parse.c opcodes.c alter.c experimental.c", "pdo_sqlite"); ADD_EXTENSION_DEP('pdo_sqlite', 'pdo'); } diff --git a/ext/pdo_sqlite/sqlite/Makefile.in b/ext/pdo_sqlite/sqlite/Makefile.in index 462772a967..db47144225 100644 --- a/ext/pdo_sqlite/sqlite/Makefile.in +++ b/ext/pdo_sqlite/sqlite/Makefile.in @@ -52,7 +52,7 @@ LIBREADLINE = @TARGET_READLINE_LIBS@ # Should the database engine be compiled threadsafe # -THREADSAFE = -DTHREADSAFE=@THREADSAFE@ +TCC += -DTHREADSAFE=@THREADSAFE@ # The pthreads library if needed # @@ -112,24 +112,28 @@ TCC += -DSQLITE_OMIT_CURSOR # Object files for the SQLite library. # -LIBOBJ = alter.lo attach.lo auth.lo btree.lo build.lo callback.lo date.lo \ +LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btree.lo build.lo \ + callback.lo complete.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 prepare.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 \ + util.lo vacuum.lo \ + vdbe.lo vdbeapi.lo vdbeaux.lo vdbefifo.lo vdbemem.lo \ where.lo utf.lo legacy.lo # All of the source code files. # SRC = \ $(TOP)/src/alter.c \ + $(TOP)/src/analyze.c \ $(TOP)/src/attach.c \ $(TOP)/src/auth.c \ $(TOP)/src/btree.c \ $(TOP)/src/btree.h \ $(TOP)/src/build.c \ $(TOP)/src/callback.c \ + $(TOP)/src/complete.c \ $(TOP)/src/date.c \ $(TOP)/src/delete.c \ $(TOP)/src/expr.c \ @@ -164,6 +168,7 @@ SRC = \ $(TOP)/src/vdbe.h \ $(TOP)/src/vdbeapi.c \ $(TOP)/src/vdbeaux.c \ + $(TOP)/src/vdbefifo.c \ $(TOP)/src/vdbemem.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/where.c @@ -187,14 +192,14 @@ TESTSRC = \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ - $(TOP)/src/md5.c + $(TOP)/src/md5.c \ + $(TOP)/src/where.c # Header files used by all library source files. # HDR = \ sqlite3.h \ $(TOP)/src/btree.h \ - config.h \ $(TOP)/src/hash.h \ opcodes.h \ $(TOP)/src/os.h \ @@ -266,6 +271,9 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c alter.lo: $(TOP)/src/alter.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/alter.c +analyze.lo: $(TOP)/src/analyze.c $(HDR) + $(LTCOMPILE) -c $(TOP)/src/analyze.c + attach.lo: $(TOP)/src/attach.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/attach.c @@ -278,21 +286,11 @@ btree.lo: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h build.lo: $(TOP)/src/build.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/build.c -# The config.h file will contain a single #define that tells us how -# many bytes are in a pointer. This only works if a pointer is the -# same size on the host as it is on the target. If you are cross-compiling -# to a target with a different pointer size, you'll need to manually -# configure the config.h file. -# -config.h: - echo '#include ' >temp.c - echo 'int main(){printf(' >>temp.c - echo '"#define SQLITE_PTR_SZ %d",sizeof(char*));' >>temp.c - echo 'exit(0);}' >>temp.c - $(BCC) -o temp temp.c - ./temp >config.h - echo >>config.h - rm -f temp.c temp +callback.lo: $(TOP)/src/callback.c $(HDR) + $(LTCOMPILE) -c $(TOP)/src/callback.c + +complete.lo: $(TOP)/src/complete.c $(HDR) + $(LTCOMPILE) -c $(TOP)/src/complete.c date.lo: $(TOP)/src/date.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/date.c @@ -331,10 +329,10 @@ 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_unix.lo: $(TOP)/src/os_unix.c $(HDR) - $(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_unix.c + $(LTCOMPILE) -c $(TOP)/src/os_unix.c os_win.lo: $(TOP)/src/os_win.c $(HDR) - $(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_win.c + $(LTCOMPILE) -c $(TOP)/src/os_win.c parse.lo: parse.c $(HDR) $(LTCOMPILE) -c parse.c @@ -348,8 +346,8 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) pragma.lo: $(TOP)/src/pragma.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/pragma.c -prepare.lo: $(TOP)/src/prepare.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/prepare.c +prepare.lo: $(TOP)/src/prepare.c $(HDR) + $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c printf.lo: $(TOP)/src/printf.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/printf.c @@ -401,6 +399,9 @@ vdbeapi.lo: $(TOP)/src/vdbeapi.c $(VDBEHDR) vdbeaux.lo: $(TOP)/src/vdbeaux.c $(VDBEHDR) $(LTCOMPILE) -c $(TOP)/src/vdbeaux.c +vdbefifo.lo: $(TOP)/src/vdbefifo.c $(VDBEHDR) + $(LTCOMPILE) -c $(TOP)/src/vdbefifo.c + vdbemem.lo: $(TOP)/src/vdbemem.c $(VDBEHDR) $(LTCOMPILE) -c $(TOP)/src/vdbemem.c @@ -417,17 +418,16 @@ tclsqlite3: tclsqlite-shell.lo libsqlite3.la $(LTLINK) -o tclsqlite3 tclsqlite-shell.lo \ libsqlite3.la $(LIBTCL) -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 $(LIBTCL) +testfixture$(TEXE): $(TOP)/src/tclsqlite.c libsqlite3.la $(TESTSRC) + $(LTLINK) -DTCLSH=1 -DSQLITE_TEST=1 $(TEMP_STORE) \ + -o testfixture $(TESTSRC) $(TOP)/src/tclsqlite.c \ + libsqlite3.la $(LIBTCL) 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) + libsqlite3.la $(LIBTCL) @@ -446,8 +446,7 @@ sqlite3_analyzer$(TEXE): $(TOP)/src/tclsqlite.c libtclsqlite3.la \ -e 's,^,",' \ -e 's,$$,\\n",' \ $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h - $(LTLINK) -DTCLSH=2 -DSQLITE_TEST=1\ - $(THREADSAFE) $(TEMP_STORE)\ + $(LTLINK) -DTCLSH=2 -DSQLITE_TEST=1 $(TEMP_STORE)\ -o sqlite3_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \ libtclsqlite3.la $(LIBTCL) @@ -570,7 +569,7 @@ version3.html: $(TOP)/www/version3.tcl # DOC = \ arch.html \ - arch.png \ + arch2.gif \ autoinc.html \ c_interface.html \ capi3.html \ @@ -653,7 +652,8 @@ implib: sqlite3.lib #make Borland C++ and/or Microsoft VC import library for the dll # ignore any errors (usually due to missing programs) sqlite3.lib: sqlite3.dll - -implib -a sqlite3.lib sqlite3.dll + -impdef -a sqlite3.def sqlite3.dll + -implib sqlite3.lib sqlite3.def -lib /machine:i386 /def:$(TOP)/sqlite3.def distclean: clean diff --git a/ext/pdo_sqlite/sqlite/Makefile.linux-gcc b/ext/pdo_sqlite/sqlite/Makefile.linux-gcc index aa5ced6ab5..202f4a1ee2 100644 --- a/ext/pdo_sqlite/sqlite/Makefile.linux-gcc +++ b/ext/pdo_sqlite/sqlite/Makefile.linux-gcc @@ -94,13 +94,13 @@ LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl #### Compiler options needed for programs that use the readline() library. # -#READLINE_FLAGS = -READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline +READLINE_FLAGS = +#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline #### Linker options needed by programs using readline() must link against. # -#LIBREADLINE = -LIBREADLINE = -static -lreadline -ltermcap +LIBREADLINE = +#LIBREADLINE = -static -lreadline -ltermcap #### Should the database engine assume text is coded as UTF-8 or iso8859? # diff --git a/ext/pdo_sqlite/sqlite/README b/ext/pdo_sqlite/sqlite/README index be1fa31568..6e4f392054 100644 --- a/ext/pdo_sqlite/sqlite/README +++ b/ext/pdo_sqlite/sqlite/README @@ -15,6 +15,7 @@ For example: cd bld ;# Change to the build directory ../sqlite/configure ;# Run the configure script make ;# Run the makefile. + make install ;# (Optional) Install the build products The configure script uses autoconf 2.50 and libtool. If the configure script does not work out for you, there is a generic makefile named diff --git a/ext/pdo_sqlite/sqlite/VERSION b/ext/pdo_sqlite/sqlite/VERSION index be94e6f53d..5ae69bd5f0 100644 --- a/ext/pdo_sqlite/sqlite/VERSION +++ b/ext/pdo_sqlite/sqlite/VERSION @@ -1 +1 @@ -3.2.2 +3.2.5 diff --git a/ext/pdo_sqlite/sqlite/configure b/ext/pdo_sqlite/sqlite/configure index 779a859463..11e3c9c51b 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 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_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 RELEASE VERSION_NUMBER 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. @@ -18430,11 +18430,11 @@ RELEASE=`cat $srcdir/VERSION` echo "Release set to $RELEASE" VERSION_NUMBER=`cat $srcdir/VERSION \ - | sed 's/[^0-9]/ /g' \ + | sed 's/[^0-9]/ /g' \ | awk '{printf "%d%03d%03d",$1,$2,$3}'` - echo "Version number set to $VERSION_NUMBER" + ######### # Check to see if the --with-hints=FILE option is used. If there is none, # then check for a files named "$host.hints" and ../$hosts.hints where @@ -21018,8 +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,@VERSION_NUMBER@,$VERSION_NUMBER,;t t s,@BUILD_CC@,$BUILD_CC,;t t s,@BUILD_CFLAGS@,$BUILD_CFLAGS,;t t s,@BUILD_LIBS@,$BUILD_LIBS,;t t diff --git a/ext/pdo_sqlite/sqlite/configure.ac b/ext/pdo_sqlite/sqlite/configure.ac index 6137f39d20..3682bf8210 100644 --- a/ext/pdo_sqlite/sqlite/configure.ac +++ b/ext/pdo_sqlite/sqlite/configure.ac @@ -138,9 +138,9 @@ AC_SUBST(VERSION) RELEASE=`cat $srcdir/VERSION` echo "Release set to $RELEASE" AC_SUBST(RELEASE) -VERSION_NUMBER=`cat $srcdir/VERSION \ +VERSION_NUMBER=[`cat $srcdir/VERSION \ | sed 's/[^0-9]/ /g' \ - | awk '{printf "%d%03d%03d",$1,$2,$3}'` + | awk '{printf "%d%03d%03d",$1,$2,$3}'`] echo "Version number set to $VERSION_NUMBER" AC_SUBST(VERSION_NUMBER) diff --git a/ext/pdo_sqlite/sqlite/main.mk b/ext/pdo_sqlite/sqlite/main.mk index f6fc40c136..d931e281ae 100644 --- a/ext/pdo_sqlite/sqlite/main.mk +++ b/ext/pdo_sqlite/sqlite/main.mk @@ -54,24 +54,28 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src # Object files for the SQLite library. # -LIBOBJ+= alter.o attach.o auth.o btree.o build.o date.o delete.o \ +LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \ + callback.o complete.o date.o delete.o \ expr.o func.o hash.o insert.o \ main.o opcodes.o os_unix.o os_win.o \ - pager.o parse.o pragma.o printf.o random.o \ + pager.o parse.o pragma.o prepare.o printf.o random.o \ select.o table.o tclsqlite.o tokenize.o trigger.o \ update.o util.o vacuum.o \ - vdbe.o vdbeapi.o vdbeaux.o vdbemem.o \ + vdbe.o vdbeapi.o vdbeaux.o vdbefifo.o vdbemem.o \ where.o utf.o legacy.o # All of the source code files. # SRC = \ $(TOP)/src/alter.c \ + $(TOP)/src/analyze.c \ $(TOP)/src/attach.c \ $(TOP)/src/auth.c \ $(TOP)/src/btree.c \ $(TOP)/src/btree.h \ $(TOP)/src/build.c \ + $(TOP)/src/callback.c \ + $(TOP)/src/complete.c \ $(TOP)/src/date.c \ $(TOP)/src/delete.c \ $(TOP)/src/expr.c \ @@ -87,6 +91,7 @@ SRC = \ $(TOP)/src/pager.h \ $(TOP)/src/parse.y \ $(TOP)/src/pragma.c \ + $(TOP)/src/prepare.c \ $(TOP)/src/printf.c \ $(TOP)/src/random.c \ $(TOP)/src/select.c \ @@ -105,6 +110,7 @@ SRC = \ $(TOP)/src/vdbe.h \ $(TOP)/src/vdbeapi.c \ $(TOP)/src/vdbeaux.c \ + $(TOP)/src/vdbefifo.c \ $(TOP)/src/vdbemem.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/where.c @@ -128,14 +134,14 @@ TESTSRC = \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ - $(TOP)/src/md5.c + $(TOP)/src/md5.c \ + $(TOP)/src/where.c # Header files used by all library source files. # HDR = \ sqlite3.h \ $(TOP)/src/btree.h \ - config.h \ $(TOP)/src/hash.h \ opcodes.h \ $(TOP)/src/os.h \ @@ -155,7 +161,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 config.h libsqlite3.a sqlite3$(EXE) +all: sqlite3.h libsqlite3.a sqlite3$(EXE) # Generate the file "last_change" which contains the date of change # of the most recently modified source code file @@ -199,6 +205,9 @@ lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c alter.o: $(TOP)/src/alter.c $(HDR) $(TCCX) -c $(TOP)/src/alter.c +analyze.o: $(TOP)/src/analyze.c $(HDR) + $(TCCX) -c $(TOP)/src/analyze.c + attach.o: $(TOP)/src/attach.c $(HDR) $(TCCX) -c $(TOP)/src/attach.c @@ -211,21 +220,11 @@ btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h build.o: $(TOP)/src/build.c $(HDR) $(TCCX) -c $(TOP)/src/build.c -# The config.h file will contain a single #define that tells us how -# many bytes are in a pointer. This only works if a pointer is the -# same size on the host as it is on the target. If you are cross-compiling -# to a target with a different pointer size, you'll need to manually -# configure the config.h file. -# -config.h: - echo '#include ' >temp.c - echo 'int main(){printf(' >>temp.c - echo '"#define SQLITE_PTR_SZ %d",sizeof(char*));' >>temp.c - echo 'exit(0);}' >>temp.c - $(BCC) -o temp temp.c - ./temp >config.h - echo >>config.h - rm -f temp.c temp +callback.o: $(TOP)/src/callback.c $(HDR) + $(TCCX) -c $(TOP)/src/callback.c + +complete.o: $(TOP)/src/complete.c $(HDR) + $(TCCX) -c $(TOP)/src/complete.c date.o: $(TOP)/src/date.c $(HDR) $(TCCX) -c $(TOP)/src/date.c @@ -281,6 +280,9 @@ parse.c: $(TOP)/src/parse.y lemon pragma.o: $(TOP)/src/pragma.c $(HDR) $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/pragma.c +prepare.o: $(TOP)/src/prepare.c $(HDR) + $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/prepare.c + printf.o: $(TOP)/src/printf.c $(HDR) $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/printf.c @@ -332,6 +334,9 @@ vdbeapi.o: $(TOP)/src/vdbeapi.c $(VDBEHDR) vdbeaux.o: $(TOP)/src/vdbeaux.c $(VDBEHDR) $(TCCX) -c $(TOP)/src/vdbeaux.c +vdbefifo.o: $(TOP)/src/vdbefifo.c $(VDBEHDR) + $(TCCX) -c $(TOP)/src/vdbefifo.c + vdbemem.o: $(TOP)/src/vdbemem.c $(VDBEHDR) $(TCCX) -c $(TOP)/src/vdbemem.c @@ -382,6 +387,9 @@ arch.html: $(TOP)/www/arch.tcl arch.png: $(TOP)/www/arch.png cp $(TOP)/www/arch.png . +arch2.gif: $(TOP)/www/arch2.gif + cp $(TOP)/www/arch2.gif . + autoinc.html: $(TOP)/www/autoinc.tcl tclsh $(TOP)/www/autoinc.tcl >autoinc.html @@ -421,6 +429,9 @@ datatypes.html: $(TOP)/www/datatypes.tcl datatype3.html: $(TOP)/www/datatype3.tcl tclsh $(TOP)/www/datatype3.tcl >datatype3.html +different.html: $(TOP)/www/different.tcl + tclsh $(TOP)/www/different.tcl >different.html + docs.html: $(TOP)/www/docs.tcl tclsh $(TOP)/www/docs.tcl >docs.html @@ -497,6 +508,7 @@ whentouse.html: $(TOP)/www/whentouse.tcl DOC = \ arch.html \ arch.png \ + arch2.gif \ autoinc.html \ c_interface.html \ capi3.html \ @@ -509,6 +521,7 @@ DOC = \ conflict.html \ datatypes.html \ datatype3.html \ + different.html \ docs.html \ download.html \ faq.html \ @@ -545,7 +558,7 @@ install: sqlite3 libsqlite3.a sqlite3.h mv sqlite3.h /usr/include clean: - rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* + rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* crashtest rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out diff --git a/ext/pdo_sqlite/sqlite/mkdll.sh b/ext/pdo_sqlite/sqlite/mkdll.sh index bad8619f3e..1ad5f83326 100644 --- a/ext/pdo_sqlite/sqlite/mkdll.sh +++ b/ext/pdo_sqlite/sqlite/mkdll.sh @@ -21,7 +21,9 @@ for i in *.c; do done echo 'EXPORTS' >tclsqlite3.def echo 'Tclsqlite3_Init' >>tclsqlite3.def +echo 'Tclsqlite_Init' >>tclsqlite3.def echo 'Sqlite3_Init' >>tclsqlite3.def +echo 'Sqlite_Init' >>tclsqlite3.def i386-mingw32msvc-dllwrap \ --def tclsqlite3.def -v --export-all \ --driver-name i386-mingw32msvc-gcc \ diff --git a/ext/pdo_sqlite/sqlite/mkopcodeh.awk b/ext/pdo_sqlite/sqlite/mkopcodeh.awk index 641b987a81..a258194ca8 100644 --- a/ext/pdo_sqlite/sqlite/mkopcodeh.awk +++ b/ext/pdo_sqlite/sqlite/mkopcodeh.awk @@ -24,6 +24,7 @@ # the total library smaller. # + # Remember the TK_ values from the parse.h file /^#define TK_/ { tk[$2] = $3 @@ -35,11 +36,16 @@ gsub(/:/,"",name) gsub("\r","",name) op[name] = -1 - for(i=3; inSrc==1 ); pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); @@ -500,8 +501,10 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ int i; int nAlloc; + /* Look up the table being altered. */ - assert( !pParse->pNewTable ); + assert( pParse->pNewTable==0 ); + if( sqlite3_malloc_failed ) goto exit_begin_add_column; pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) goto exit_begin_add_column; @@ -520,6 +523,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew = (Table *)sqliteMalloc(sizeof(Table)); if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; + pNew->nRef = 1; pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; diff --git a/ext/pdo_sqlite/sqlite/src/analyze.c b/ext/pdo_sqlite/sqlite/src/analyze.c new file mode 100644 index 0000000000..7f0f00a349 --- /dev/null +++ b/ext/pdo_sqlite/sqlite/src/analyze.c @@ -0,0 +1,388 @@ +/* +** 2005 July 8 +** +** 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 code associated with the ANALYZE command. +** +** @(#) $Id$ +*/ +#ifndef SQLITE_OMIT_ANALYZE +#include "sqliteInt.h" + +/* +** This routine generates code that opens the sqlite_stat1 table on cursor +** iStatCur. +** +** If the sqlite_stat1 tables does not previously exist, it is created. +** If it does previously exist, all entires associated with table zWhere +** are removed. If zWhere==0 then all entries are removed. +*/ +static void openStatTable( + Parse *pParse, /* Parsing context */ + int iDb, /* The database we are looking in */ + int iStatCur, /* Open the sqlite_stat1 table on this cursor */ + const char *zWhere /* Delete entries associated with this table */ +){ + sqlite3 *db = pParse->db; + Db *pDb; + int iRootPage; + Table *pStat; + Vdbe *v = sqlite3GetVdbe(pParse); + + pDb = &db->aDb[iDb]; + if( (pStat = sqlite3FindTable(db, "sqlite_stat1", pDb->zName))==0 ){ + /* The sqlite_stat1 tables does not exist. Create it. + ** Note that a side-effect of the CREATE TABLE statement is to leave + ** the rootpage of the new table on the top of the stack. This is + ** important because the OpenWrite opcode below will be needing it. */ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.sqlite_stat1(tbl,idx,stat)", + pDb->zName + ); + iRootPage = 0; /* Cause rootpage to be taken from top of stack */ + }else if( zWhere ){ + /* The sqlite_stat1 table exists. Delete all entries associated with + ** the table zWhere. */ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q", + pDb->zName, zWhere + ); + iRootPage = pStat->tnum; + }else{ + /* The sqlite_stat1 table already exists. Delete all rows. */ + iRootPage = pStat->tnum; + sqlite3VdbeAddOp(v, OP_Clear, pStat->tnum, iDb); + } + + /* Open the sqlite_stat1 table for writing. + */ + sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3); +} + +/* +** Generate code to do an analysis of all indices associated with +** a single table. +*/ +static void analyzeOneTable( + Parse *pParse, /* Parser context */ + Table *pTab, /* Table whose indices are to be analyzed */ + int iStatCur, /* Cursor that writes to the sqlite_stat1 table */ + int iMem /* Available memory locations begin here */ +){ + Index *pIdx; /* An index to being analyzed */ + int iIdxCur; /* Cursor number for index being analyzed */ + int nCol; /* Number of columns in the index */ + Vdbe *v; /* The virtual machine being built up */ + int i; /* Loop counter */ + int topOfLoop; /* The top of the loop */ + int endOfLoop; /* The end of the loop */ + int addr; /* The address of an instruction */ + + v = sqlite3GetVdbe(pParse); + if( pTab==0 || pTab->pIndex==0 || pTab->pIndex->pNext==0 ){ + /* Do no analysis for tables with fewer than 2 indices */ + return; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, + pParse->db->aDb[pTab->iDb].zName ) ){ + return; + } +#endif + + iIdxCur = pParse->nTab; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + /* Open a cursor to the index to be analyzed + */ + sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0); + VdbeComment((v, "# %s", pIdx->zName)); + sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, + (char*)&pIdx->keyInfo, P3_KEYINFO); + nCol = pIdx->nColumn; + if( iMem+nCol*2>=pParse->nMem ){ + pParse->nMem = iMem+nCol*2+1; + } + sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, nCol+1); + + /* Memory cells are used as follows: + ** + ** mem[iMem]: The total number of rows in the table. + ** mem[iMem+1]: Number of distinct values in column 1 + ** ... + ** mem[iMem+nCol]: Number of distinct values in column N + ** mem[iMem+nCol+1] Last observed value of column 1 + ** ... + ** mem[iMem+nCol+nCol]: Last observed value of column N + ** + ** Cells iMem through iMem+nCol are initialized to 0. The others + ** are initialized to NULL. + */ + sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + for(i=0; i<=nCol; i++){ + sqlite3VdbeAddOp(v, OP_MemStore, iMem+i, i==nCol); + } + sqlite3VdbeAddOp(v, OP_Null, 0, 0); + for(i=0; i0 then it is always the case the D>0 so division by zero + ** is never possible. + */ + sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0); + addr = sqlite3VdbeAddOp(v, OP_IfNot, 0, 0); + sqlite3VdbeAddOp(v, OP_NewRowid, iStatCur, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0); + sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, " ", 0); + for(i=0; idb; + HashElem *k; + int iStatCur; + int iMem; + + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab++; + openStatTable(pParse, iDb, iStatCur, 0); + iMem = pParse->nMem; + for(k=sqliteHashFirst(&db->aDb[iDb].tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + analyzeOneTable(pParse, pTab, iStatCur, iMem); + } + loadAnalysis(pParse, iDb); +} + +/* +** Generate code that will do an analysis of a single table in +** a database. +*/ +static void analyzeTable(Parse *pParse, Table *pTab){ + int iDb; + int iStatCur; + + assert( pTab!=0 ); + iDb = pTab->iDb; + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab++; + openStatTable(pParse, iDb, iStatCur, pTab->zName); + analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem); + loadAnalysis(pParse, iDb); +} + +/* +** Generate code for the ANALYZE command. The parser calls this routine +** when it recognizes an ANALYZE command. +** +** ANALYZE -- 1 +** ANALYZE -- 2 +** ANALYZE ?.? -- 3 +** +** Form 1 causes all indices in all attached databases to be analyzed. +** Form 2 analyzes all indices the single database named. +** Form 3 analyzes all indices associated with the named table. +*/ +void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ + sqlite3 *db = pParse->db; + int iDb; + int i; + char *z, *zDb; + Table *pTab; + Token *pTableName; + + /* 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 ){ + /* Form 1: Analyze everything */ + for(i=0; inDb; i++){ + if( i==1 ) continue; /* Do not analyze the TEMP database */ + analyzeDatabase(pParse, i); + } + }else if( pName2==0 || pName2->n==0 ){ + /* Form 2: Analyze the database or table named */ + iDb = sqlite3FindDb(db, pName1); + if( iDb>=0 ){ + analyzeDatabase(pParse, iDb); + }else{ + z = sqlite3NameFromToken(pName1); + pTab = sqlite3LocateTable(pParse, z, 0); + sqliteFree(z); + if( pTab ){ + analyzeTable(pParse, pTab); + } + } + }else{ + /* Form 3: Analyze the fully qualified table name */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); + if( iDb>=0 ){ + zDb = db->aDb[iDb].zName; + z = sqlite3NameFromToken(pTableName); + pTab = sqlite3LocateTable(pParse, z, zDb); + sqliteFree(z); + if( pTab ){ + analyzeTable(pParse, pTab); + } + } + } +} + +/* +** Used to pass information from the analyzer reader through to the +** callback routine. +*/ +typedef struct analysisInfo analysisInfo; +struct analysisInfo { + sqlite3 *db; + const char *zDatabase; +}; + +/* +** This callback is invoked once for each index when reading the +** sqlite_stat1 table. +** +** argv[0] = name of the index +** argv[1] = results of analysis - on integer for each column +*/ +static int analysisLoader(void *pData, int argc, char **argv, char **azNotUsed){ + analysisInfo *pInfo = (analysisInfo*)pData; + Index *pIndex; + int i, c; + unsigned int v; + const char *z; + + assert( argc==2 ); + if( argv[0]==0 || argv[1]==0 ){ + return 0; + } + pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase); + if( pIndex==0 ){ + return 0; + } + z = argv[1]; + for(i=0; *z && i<=pIndex->nColumn; i++){ + v = 0; + while( (c=z[0])>='0' && c<='9' ){ + v = v*10 + c - '0'; + z++; + } + pIndex->aiRowEst[i] = v; + if( *z==' ' ) z++; + } + return 0; +} + +/* +** Load the content of the sqlite_stat1 table into the index hash tables. +*/ +void sqlite3AnalysisLoad(sqlite3 *db, int iDb){ + analysisInfo sInfo; + HashElem *i; + char *zSql; + + /* Clear any prior statistics */ + for(i=sqliteHashFirst(&db->aDb[iDb].idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + sqlite3DefaultRowEst(pIdx); + } + + /* Check to make sure the sqlite_stat1 table existss */ + sInfo.db = db; + sInfo.zDatabase = db->aDb[iDb].zName; + if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ + return; + } + + + /* Load new statistics out of the sqlite_stat1 table */ + zSql = sqlite3MPrintf("SELECT idx, stat FROM %Q.sqlite_stat1", + sInfo.zDatabase); + sqlite3SafetyOff(db); + sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3SafetyOn(db); + sqliteFree(zSql); +} + + +#endif /* SQLITE_OMIT_ANALYZE */ diff --git a/ext/pdo_sqlite/sqlite/src/attach.c b/ext/pdo_sqlite/sqlite/src/attach.c index 5c8953467c..46b653e975 100644 --- a/ext/pdo_sqlite/sqlite/src/attach.c +++ b/ext/pdo_sqlite/sqlite/src/attach.c @@ -146,8 +146,8 @@ void sqlite3Attach( db->aDb[i].pBt = 0; } sqlite3ResetInternalSchema(db, 0); - if( 0==pParse->nErr ){ - pParse->nErr++; + assert( pParse->nErr>0 ); /* Always set by sqlite3ReadSchema() */ + if( pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; } } diff --git a/ext/pdo_sqlite/sqlite/src/btree.c b/ext/pdo_sqlite/sqlite/src/btree.c index 5cfc118d44..3f1dfa92c7 100644 --- a/ext/pdo_sqlite/sqlite/src/btree.c +++ b/ext/pdo_sqlite/sqlite/src/btree.c @@ -234,8 +234,19 @@ typedef struct MemPage MemPage; /* ** This is a magic string that appears at the beginning of every ** SQLite database in order to identify the file as a real database. -** 123456789 123456 */ -static const char zMagicHeader[] = "SQLite format 3"; +** +** You can change this value at compile-time by specifying a +** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The +** header must be exactly 16 bytes including the zero-terminator so +** the string itself should be 15 characters long. If you change +** the header, then your custom library will not be able to read +** databases generated by the standard tools and the standard tools +** will not be able to read databases created by your custom library. +*/ +#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */ +# define SQLITE_FILE_HEADER "SQLite format 3" +#endif +static const char zMagicHeader[] = SQLITE_FILE_HEADER; /* ** Page type flags. An ORed combination of these flags appear as the @@ -1334,6 +1345,15 @@ int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){ } #endif +/* +** Return TRUE if the given btree is set to safety level 1. In other +** words, return TRUE if no sync() occurs on the disk files. +*/ +int sqlite3BtreeSyncDisabled(Btree *pBt){ + assert( pBt && pBt->pPager ); + return sqlite3pager_nosync(pBt->pPager); +} + #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Change the default pages size and the number of reserved bytes per page. @@ -1595,8 +1615,6 @@ static int newDatabase(Btree *pBt){ */ int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){ int rc = SQLITE_OK; - int busy = 0; - BusyHandler *pH; /* If the btree is already in a write-transaction, or it ** is already in a read-transaction and a read-transaction @@ -1630,9 +1648,7 @@ int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){ unlockBtreeIfUnused(pBt); } }while( rc==SQLITE_BUSY && pBt->inTrans==TRANS_NONE && - (pH = pBt->pBusyHandler)!=0 && - pH->xFunc && pH->xFunc(pH->pArg, busy++) - ); + sqlite3InvokeBusyHandler(pBt->pBusyHandler) ); return rc; } @@ -3595,17 +3611,19 @@ static void assemblePage( data = pPage->aData; hdr = pPage->hdrOffset; put2byte(&data[hdr+3], nCell); - cellbody = allocateSpace(pPage, totalSize); - assert( cellbody>0 ); - assert( pPage->nFree >= 2*nCell ); - pPage->nFree -= 2*nCell; - for(i=0; i0 ); + assert( pPage->nFree >= 2*nCell ); + pPage->nFree -= 2*nCell; + for(i=0; ipBt->usableSize ); } - assert( cellbody==pPage->pBt->usableSize ); pPage->nCell = nCell; } @@ -3809,7 +3827,7 @@ static int balance_nonroot(MemPage *pPage){ /* ** 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 + ** and 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. @@ -4082,7 +4100,12 @@ static int balance_nonroot(MemPage *pPage){ szNew[i] = szRight; szNew[i-1] = szLeft; } - assert( cntNew[0]>0 ); + + /* Either we found one or more cells (cntnew[0])>0) or we are the + ** a virtual root page. A virtual root page is when the real root + ** page is page 1 and we are the only child of that page. + */ + assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); /* ** Allocate k new pages. Reuse old pages where possible. @@ -4171,7 +4194,7 @@ static int balance_nonroot(MemPage *pPage){ assert( jpgno==pgnoNew[i] ); assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]); - assert( pNew->nCell>0 ); + assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) ); assert( pNew->nOverflow==0 ); #ifndef SQLITE_OMIT_AUTOVACUUM diff --git a/ext/pdo_sqlite/sqlite/src/btree.h b/ext/pdo_sqlite/sqlite/src/btree.h index bd09b46423..9d4401ac81 100644 --- a/ext/pdo_sqlite/sqlite/src/btree.h +++ b/ext/pdo_sqlite/sqlite/src/btree.h @@ -58,6 +58,7 @@ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*); int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetSafetyLevel(Btree*,int); +int sqlite3BtreeSyncDisabled(Btree*); int sqlite3BtreeSetPageSize(Btree*,int,int); int sqlite3BtreeGetPageSize(Btree*); int sqlite3BtreeGetReserve(Btree*); diff --git a/ext/pdo_sqlite/sqlite/src/build.c b/ext/pdo_sqlite/sqlite/src/build.c index 450316e5a4..67e83e970b 100644 --- a/ext/pdo_sqlite/sqlite/src/build.c +++ b/ext/pdo_sqlite/sqlite/src/build.c @@ -200,9 +200,6 @@ Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){ if( p==0 ){ if( zDbase ){ sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName); - }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){ - sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"", - zName, zDbase); }else{ sqlite3ErrorMsg(pParse, "no such table: %s", zName); } @@ -258,10 +255,7 @@ static void sqliteDeleteIndex(sqlite3 *db, Index *p){ assert( db!=0 && p->zName!=0 ); pOld = sqlite3HashInsert(&db->aDb[p->iDb].idxHash, p->zName, strlen(p->zName)+1, 0); - if( pOld!=0 && pOld!=p ){ - sqlite3HashInsert(&db->aDb[p->iDb].idxHash, pOld->zName, - strlen(pOld->zName)+1, pOld); - } + assert( pOld==0 || pOld==p ); freeIndex(p); } @@ -535,7 +529,7 @@ void sqlite3OpenMasterTable(Vdbe *v, int iDb){ ** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ -static int findDb(sqlite3 *db, Token *pName){ +int sqlite3FindDb(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 */ @@ -583,7 +577,7 @@ int sqlite3TwoPartName( if( pName2 && pName2->n>0 ){ assert( !db->init.busy ); *pUnqual = pName2; - iDb = findDb(db, pName1); + iDb = sqlite3FindDb(db, pName1); if( iDb<0 ){ sqlite3ErrorMsg(pParse, "unknown database %T", pName1); pParse->nErr++; @@ -745,7 +739,7 @@ void sqlite3StartTable( ** so that INSERT can find the table easily. */ #ifndef SQLITE_OMIT_AUTOINCREMENT - if( strcmp(zName, "sqlite_sequence")==0 ){ + if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){ db->aDb[iDb].pSeqTab = pTable; } #endif @@ -902,11 +896,11 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ ** If none of the substrings in the above table are found, ** SQLITE_AFF_NUMERIC is returned. */ -static char sqlite3AffinityType(const char *zType, int nType){ +char sqlite3AffinityType(const Token *pType){ u32 h = 0; char aff = SQLITE_AFF_NUMERIC; - const unsigned char *zIn = zType; - const unsigned char *zEnd = (zIn+nType); + const unsigned char *zIn = pType->z; + const unsigned char *zEnd = &pType->z[pType->n]; while( zIn!=zEnd ){ h = (h<<8) + sqlite3UpperToLower[*zIn]; @@ -938,30 +932,18 @@ static char sqlite3AffinityType(const char *zType, int nType){ ** that contains the typename of the column and store that string ** in zType. */ -void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){ +void sqlite3AddColumnType(Parse *pParse, Token *pType){ Table *p; - int i, j; - int n; - char *z; - const unsigned char *zIn; - + int i; Column *pCol; + if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; if( i<0 ) return; pCol = &p->aCol[i]; - zIn = pFirst->z; - n = pLast->n + (pLast->z - zIn); assert( pCol->zType==0 ); - z = pCol->zType = sqliteMallocRaw(n+1); - if( z==0 ) return; - for(i=j=0; iaffinity = sqlite3AffinityType(z, n); + pCol->zType = sqlite3NameFromToken(pType); + pCol->affinity = sqlite3AffinityType(pType); } /* @@ -977,14 +959,15 @@ void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){ Table *p; Column *pCol; - if( (p = pParse->pNewTable)==0 ) return; - 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); + if( (p = pParse->pNewTable)!=0 ){ + pCol = &(p->aCol[p->nCol-1]); + if( !sqlite3ExprIsConstantOrFunction(pExpr) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + pCol->zName); + }else{ + sqlite3ExprDelete(pCol->pDflt); + pCol->pDflt = sqlite3ExprDup(pExpr); + } } sqlite3ExprDelete(pExpr); } @@ -1317,13 +1300,11 @@ void sqlite3EndTable( */ if( p->pSelect==0 ){ /* A regular table */ - /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */ zType = "table"; zType2 = "TABLE"; #ifndef SQLITE_OMIT_VIEW }else{ /* A view */ - /* sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */ zType = "view"; zType2 = "VIEW"; #endif @@ -1535,10 +1516,13 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** Actually, this error is caught previously and so the following test ** should always fail. But we will leave it in place just to be safe. */ +#if 0 if( pTable->nCol<0 ){ sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); return 1; } +#endif + assert( pTable->nCol>=0 ); /* If we get this far, it means we need to compute the table names. ** Note that the call to sqlite3ResultSetOfSelect() will expand any @@ -1973,7 +1957,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ 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, @@ -2002,16 +1985,21 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ 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); + sqlite3OpenTableForReading(v, iTab, pTab); addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); sqlite3GenerateIndexKey(v, pIndex, iTab); - isUnique = pIndex->onError!=OE_None; - sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, isUnique); - if( isUnique ){ - sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC); - } + if( pIndex->onError!=OE_None ){ + int curaddr = sqlite3VdbeCurrentAddr(v); + int addr2 = curaddr+4; + sqlite3VdbeChangeP2(v, curaddr-1, addr2); + sqlite3VdbeAddOp(v, OP_Rowid, iTab, 0); + sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); + sqlite3VdbeAddOp(v, OP_IsUnique, iIdx, addr2); + sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, + "indexed columns are not unique", P3_STATIC); + assert( addr2==sqlite3VdbeCurrentAddr(v) ); + } + sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, 0); sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1); sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp(v, OP_Close, iTab, 0); @@ -2079,7 +2067,9 @@ void sqlite3CreateIndex( if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) && sqlite3FixSrcList(&sFix, pTblName) ){ - goto exit_create_index; + /* Because the parser constructs pTblName from a single identifier, + ** sqlite3FixSrcList can never fail. */ + assert(0); } pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName, pTblName->a[0].zDatabase); @@ -2177,11 +2167,12 @@ void sqlite3CreateIndex( /* ** Allocate the index structure. */ - pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + - (sizeof(int) + sizeof(CollSeq*))*pList->nExpr ); + pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + sizeof(int) + + (sizeof(int)*2 + sizeof(CollSeq*))*pList->nExpr ); if( sqlite3_malloc_failed ) goto exit_create_index; pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr]; - pIndex->zName = (char*)&pIndex->aiColumn[pList->nExpr]; + pIndex->aiRowEst = &pIndex->aiColumn[pList->nExpr]; + pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1]; strcpy(pIndex->zName, zName); pIndex->pTable = pTab; pIndex->nColumn = pList->nExpr; @@ -2217,6 +2208,7 @@ void sqlite3CreateIndex( } } pIndex->keyInfo.nField = pList->nExpr; + sqlite3DefaultRowEst(pIndex); if( pTab==pParse->pNewTable ){ /* This routine has been called to create an automatic index as a @@ -2383,6 +2375,37 @@ exit_create_index: return; } +/* +** Fill the Index.aiRowEst[] array with default information - information +** to be used when we have not run the ANALYZE command. +** +** aiRowEst[0] is suppose to contain the number of elements in the index. +** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the +** number of rows in the table that match any particular value of the +** first column of the index. aiRowEst[2] is an estimate of the number +** of rows that match any particular combiniation of the first 2 columns +** of the index. And so forth. It must always be the case that +* +** aiRowEst[N]<=aiRowEst[N-1] +** aiRowEst[N]>=1 +** +** Apart from that, we have little to go on besides intuition as to +** how aiRowEst[] should be initialized. The numbers generated here +** are based on typical values found in actual indices. +*/ +void sqlite3DefaultRowEst(Index *pIdx){ + int *a = pIdx->aiRowEst; + int i; + assert( a!=0 ); + a[0] = 1000000; + for(i=pIdx->nColumn; i>=1; i--){ + a[i] = 10; + } + if( pIdx->onError!=OE_None ){ + a[pIdx->nColumn] = 1; + } +} + /* ** This routine will drop an existing named index. This routine ** implements the DROP INDEX statement. @@ -2472,6 +2495,32 @@ IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){ return pList; } +/* +** Delete an IdList. +*/ +void sqlite3IdListDelete(IdList *pList){ + int i; + if( pList==0 ) return; + for(i=0; inId; i++){ + sqliteFree(pList->a[i].zName); + } + sqliteFree(pList->a); + sqliteFree(pList); +} + +/* +** Return the index in pList of the identifier named zId. Return -1 +** if not found. +*/ +int sqlite3IdListIndex(IdList *pList, const char *zName){ + int i; + if( pList==0 ) return -1; + for(i=0; inId; i++){ + if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; + } + return -1; +} + /* ** Append a new table name to the given SrcList. Create a new SrcList if ** need be. A new entry is created in the SrcList even if pToken is NULL. @@ -2556,32 +2605,6 @@ void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){ } } -/* -** Delete an IdList. -*/ -void sqlite3IdListDelete(IdList *pList){ - int i; - if( pList==0 ) return; - for(i=0; inId; i++){ - sqliteFree(pList->a[i].zName); - } - sqliteFree(pList->a); - sqliteFree(pList); -} - -/* -** Return the index in pList of the identifier named zId. Return -1 -** if not found. -*/ -int sqlite3IdListIndex(IdList *pList, const char *zName){ - int i; - if( pList==0 ) return -1; - for(i=0; inId; i++){ - if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; - } - return -1; -} - /* ** Delete an entire SrcList including all its substructure. */ @@ -2784,7 +2807,7 @@ static int collationMatch(CollSeq *pColl, Index *pIndex){ ** If pColl==0 then recompute all indices of pTab. */ #ifndef SQLITE_OMIT_REINDEX -void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){ +static void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){ Index *pIndex; /* An index associated with pTab */ for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ @@ -2802,7 +2825,7 @@ void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){ ** all indices everywhere. */ #ifndef SQLITE_OMIT_REINDEX -void reindexDatabases(Parse *pParse, CollSeq *pColl){ +static void reindexDatabases(Parse *pParse, CollSeq *pColl){ Db *pDb; /* A single database */ int iDb; /* The database index number */ sqlite3 *db = pParse->db; /* The database connection */ @@ -2811,7 +2834,7 @@ void reindexDatabases(Parse *pParse, CollSeq *pColl){ for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ if( pDb==0 ) continue; - for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){ + for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){ pTab = (Table*)sqliteHashData(k); reindexTable(pParse, pTab, pColl); } diff --git a/ext/pdo_sqlite/sqlite/src/callback.c b/ext/pdo_sqlite/sqlite/src/callback.c index 9fa621752f..2103c3f711 100644 --- a/ext/pdo_sqlite/sqlite/src/callback.c +++ b/ext/pdo_sqlite/sqlite/src/callback.c @@ -147,7 +147,7 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ ** the collation sequence name. A pointer to this string is stored in ** each collation sequence structure. */ -static CollSeq * findCollSeqEntry( +static CollSeq *findCollSeqEntry( sqlite3 *db, const char *zName, int nName, @@ -286,10 +286,9 @@ FuncDef *sqlite3FindFunction( ** new entry to the hash table and return it. */ if( createFlag && bestmatch<6 && - (pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){ + (pBest = sqliteMalloc(sizeof(*pBest)+nName)) ){ pBest->nArg = nArg; pBest->pNext = pFirst; - pBest->zName = (char*)&pBest[1]; pBest->iPrefEnc = enc; memcpy(pBest->zName, zName, nName); pBest->zName[nName] = 0; diff --git a/ext/pdo_sqlite/sqlite/src/date.c b/ext/pdo_sqlite/sqlite/src/date.c index c6872831b9..7d398df489 100644 --- a/ext/pdo_sqlite/sqlite/src/date.c +++ b/ext/pdo_sqlite/sqlite/src/date.c @@ -124,11 +124,7 @@ static int getDigits(const char *zDate, ...){ ** Read text from z[] and convert into a floating point number. Return ** the number of digits converted. */ -static int getValue(const char *z, double *pR){ - const char *zEnd; - *pR = sqlite3AtoF(z, &zEnd); - return zEnd - z; -} +#define getValue sqlite3AtoF /* ** Parse a timezone extension on the end of a date-time. @@ -320,7 +316,7 @@ static int parseDateOrTime(const char *zDate, DateTime *p){ p->validJD = 1; return 0; }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){ - p->rJD = sqlite3AtoF(zDate, 0); + getValue(zDate, &p->rJD); p->validJD = 1; return 0; } diff --git a/ext/pdo_sqlite/sqlite/src/delete.c b/ext/pdo_sqlite/sqlite/src/delete.c index 15eb8f4e8d..f9bb49e577 100644 --- a/ext/pdo_sqlite/sqlite/src/delete.c +++ b/ext/pdo_sqlite/sqlite/src/delete.c @@ -65,8 +65,8 @@ void sqlite3OpenTableForReading( Table *pTab /* The table to be opened */ ){ sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); VdbeComment((v, "# %s", pTab->zName)); + sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); } @@ -240,7 +240,7 @@ void sqlite3DeleteFrom( /* Remember the rowid of every item to be deleted. */ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); - sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); + sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); } @@ -260,14 +260,13 @@ void sqlite3DeleteFrom( ** database scan. We have to delete items after the scan is complete ** because deleting an item can change the scan order. */ - sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0); end = sqlite3VdbeMakeLabel(v); /* This is the beginning of the delete loop when there are ** row triggers. */ if( triggers_exist ){ - addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); + addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end); if( !isView ){ sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3OpenTableForReading(v, iCur, pTab); @@ -288,7 +287,7 @@ void sqlite3DeleteFrom( if( !isView ){ /* Open cursors for the table we are deleting from and all its ** indices. If there are row triggers, this happens inside the - ** OP_ListRead loop because the cursor have to all be closed + ** OP_FifoRead loop because the cursor have to all be closed ** before the trigger fires. If there are no row triggers, the ** cursors are opened only once on the outside the loop. */ @@ -297,7 +296,7 @@ void sqlite3DeleteFrom( /* This is the beginning of the delete loop when there are no ** row triggers */ if( !triggers_exist ){ - addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); + addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end); } /* Delete the row */ @@ -322,7 +321,6 @@ void sqlite3DeleteFrom( /* End of the delete loop */ sqlite3VdbeAddOp(v, OP_Goto, 0, addr); sqlite3VdbeResolveLabel(v, end); - sqlite3VdbeAddOp(v, OP_ListReset, 0, 0); /* Close the cursors after the loop if there are no row triggers */ if( !triggers_exist ){ @@ -442,6 +440,6 @@ void sqlite3GenerateIndexKey( sqlite3ColumnDefault(v, pTab, idx); } } - sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); + sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0); sqlite3IndexAffinityStr(v, pIdx); } diff --git a/ext/pdo_sqlite/sqlite/src/experimental.c b/ext/pdo_sqlite/sqlite/src/experimental.c index ec40891a3a..0bb0ae334e 100644 --- a/ext/pdo_sqlite/sqlite/src/experimental.c +++ b/ext/pdo_sqlite/sqlite/src/experimental.c @@ -15,7 +15,6 @@ ** $Id$ */ #include "sqliteInt.h" -#include "os.h" /* ** Set all the parameters in the compiled SQL statement to NULL. diff --git a/ext/pdo_sqlite/sqlite/src/expr.c b/ext/pdo_sqlite/sqlite/src/expr.c index 70bdd8692f..a83b9d78cf 100644 --- a/ext/pdo_sqlite/sqlite/src/expr.c +++ b/ext/pdo_sqlite/sqlite/src/expr.c @@ -34,12 +34,18 @@ ** SELECT * FROM t1 WHERE (select a from t1); */ char sqlite3ExprAffinity(Expr *pExpr){ - if( pExpr->op==TK_AS ){ + int op = pExpr->op; + if( op==TK_AS ){ return sqlite3ExprAffinity(pExpr->pLeft); } - if( pExpr->op==TK_SELECT ){ + if( op==TK_SELECT ){ return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr); } +#ifndef SQLITE_OMIT_CAST + if( op==TK_CAST ){ + return sqlite3AffinityType(&pExpr->token); + } +#endif return pExpr->affinity; } @@ -51,7 +57,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ CollSeq *pColl = 0; if( pExpr ){ pColl = pExpr->pColl; - if( pExpr->op==TK_AS && !pColl ){ + if( (pExpr->op==TK_AS || pExpr->op==TK_CAST) && !pColl ){ return sqlite3ExprCollSeq(pParse, pExpr->pLeft); } } @@ -87,6 +93,7 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ return SQLITE_AFF_NONE; }else{ /* One side is a column, the other is not. Use the columns affinity. */ + assert( aff1==0 || aff2==0 ); return (aff1 + aff2); } } @@ -207,9 +214,8 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ /* ** 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. +** on the stack. "#0" means the top of the stack. +** "#1" means the next down on the stack. 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. @@ -220,23 +226,19 @@ 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; } + if( v==0 ) 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; - } + p->iTable = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_Dup, depth, 0); + sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); return p; } @@ -378,6 +380,21 @@ void sqlite3ExprDelete(Expr *p){ sqliteFree(p); } +/* +** The Expr.token field might be a string literal that is quoted. +** If so, remove the quotation marks. +*/ +void sqlite3DequoteExpr(Expr *p){ + if( ExprHasAnyProperty(p, EP_Dequoted) ){ + return; + } + ExprSetProperty(p, EP_Dequoted); + if( p->token.dyn==0 ){ + sqlite3TokenCopy(&p->token, &p->token); + } + sqlite3Dequote((char*)p->token.z); +} + /* ** The following group of routines make deep copies of expressions, @@ -529,7 +546,7 @@ Select *sqlite3SelectDup(Select *p){ pNew->pOffset = sqlite3ExprDup(p->pOffset); pNew->iLimit = -1; pNew->iOffset = -1; - pNew->ppOpenTemp = 0; + pNew->ppOpenVirtual = 0; pNew->isResolved = p->isResolved; pNew->isAgg = p->isAgg; return pNew; @@ -607,6 +624,8 @@ void sqlite3ExprListDelete(ExprList *pList){ ** ** The return value from this routine is 1 to abandon the tree walk ** and 0 to continue. +** +** NOTICE: This routine does *not* descend into subqueries. */ static int walkExprList(ExprList *, int (*)(void *, Expr*), void *); static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){ @@ -664,17 +683,26 @@ static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){ */ static int exprNodeIsConstant(void *pArg, Expr *pExpr){ switch( pExpr->op ){ + /* Consider functions to be constant if all their arguments are constant + ** and *pArg==2 */ + case TK_FUNCTION: + if( *((int*)pArg)==2 ) return 0; + /* Fall through */ 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; + case TK_IN: + if( pExpr->pSelect ){ + *((int*)pArg) = 0; + return 2; + } default: return 0; } @@ -682,7 +710,7 @@ static int exprNodeIsConstant(void *pArg, Expr *pExpr){ /* ** Walk an expression tree. Return 1 if the expression is constant -** and 0 if it involves variables. +** and 0 if it involves variables or function calls. ** ** For the purposes of this function, a double-quoted string (ex: "abc") ** is considered a variable but a single-quoted string (ex: 'abc') is @@ -694,6 +722,21 @@ int sqlite3ExprIsConstant(Expr *p){ return isConst; } +/* +** Walk an expression tree. Return 1 if the expression is constant +** or a function call with constant arguments. Return and 0 if there +** are any 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 sqlite3ExprIsConstantOrFunction(Expr *p){ + int isConst = 2; + walkExprTree(p, exprNodeIsConstant, &isConst); + return isConst!=0; +} + /* ** 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 @@ -1218,19 +1261,25 @@ struct QueryCoder { */ #ifndef SQLITE_OMIT_SUBQUERY void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ - int label = 0; /* Address after sub-select code */ + int testAddr = 0; /* One-time test address */ 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). + /* This code must be run in its entirety every time it is encountered + ** if any of the following is true: + ** + ** * The right-hand side is a correlated subquery + ** * The right-hand side is an expression list containing variables + ** * We are inside a trigger + ** + ** If all of the above are false, then we can run this code just once + ** save the results, and reuse the same result on subsequent invocations. */ 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); + testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0); + assert( testAddr>0 ); sqlite3VdbeAddOp(v, OP_Integer, 1, 0); sqlite3VdbeAddOp(v, OP_MemStore, mem, 1); } @@ -1243,12 +1292,12 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ case TK_IN: { char affinity; KeyInfo keyInfo; - int addr; /* Address of OP_OpenTemp instruction */ + int addr; /* Address of OP_OpenVirtual instruction */ affinity = sqlite3ExprAffinity(pExpr->pLeft); /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' - ** expression it is handled the same way. A temporary table is + ** expression it is handled the same way. A virtual table is ** filled with single-field index keys representing the results ** from the SELECT or the . ** @@ -1261,7 +1310,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** is used. */ pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 0); + addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, pExpr->iTable, 0); memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1); @@ -1290,20 +1339,30 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** a column, use numeric affinity. */ int i; + ExprList *pList = pExpr->pList; + struct ExprList_item *pItem; + if( !affinity ){ affinity = SQLITE_AFF_NUMERIC; } keyInfo.aColl[0] = pExpr->pLeft->pColl; /* Loop through each expression in . */ - for(i=0; ipList->nExpr; i++){ - Expr *pE2 = pExpr->pList->a[i].pExpr; - - /* Check that the expression is constant and valid. */ - if( !sqlite3ExprIsConstant(pE2) ){ - sqlite3ErrorMsg(pParse, - "right-hand side of IN operator must be constant"); - return; + for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ + Expr *pE2 = pItem->pExpr; + + /* If the expression is not constant then we will need to + ** disable the test that was generated above that makes sure + ** this code only executes once. Because for a non-constant + ** expression we need to rerun this code each time. + */ + if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){ + VdbeOp *aOp = sqlite3VdbeGetOp(v, testAddr-1); + int i; + for(i=0; i<4; i++){ + aOp[i].opcode = OP_Noop; + } + testAddr = 0; } /* Evaluate the expression and insert it into the temp table */ @@ -1344,8 +1403,8 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ if( pExpr->pSelect ){ sqlite3VdbeAddOp(v, OP_AggContextPop, 0, 0); } - if( label<0 ){ - sqlite3VdbeResolveLabel(v, label); + if( testAddr ){ + sqlite3VdbeChangeP2(v, testAddr, sqlite3VdbeCurrentAddr(v)); } return; } @@ -1360,7 +1419,7 @@ static void codeInteger(Vdbe *v, const char *z, int n){ if( sqlite3GetInt32(z, &i) ){ sqlite3VdbeAddOp(v, OP_Integer, i, 0); }else if( sqlite3FitsIn64Bits(z) ){ - sqlite3VdbeOp3(v, OP_Integer, 0, 0, z, n); + sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n); }else{ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n); } @@ -1405,8 +1464,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_STRING: { assert( TK_FLOAT==OP_Real ); assert( TK_STRING==OP_String8 ); + sqlite3DequoteExpr(pExpr); sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n); - sqlite3VdbeDequoteP3(v, -1); break; } case TK_NULL: { @@ -1415,9 +1474,16 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { + int n; + const char *z; assert( TK_BLOB==OP_HexBlob ); - sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1); - sqlite3VdbeDequoteP3(v, -1); + n = pExpr->token.n - 3; + z = pExpr->token.z + 2; + assert( n>=0 ); + if( n==0 ){ + z = ""; + } + sqlite3VdbeOp3(v, op, 0, 0, z, n); break; } #endif @@ -1432,6 +1498,22 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0); break; } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + int aff, op; + sqlite3ExprCode(pParse, pExpr->pLeft); + aff = sqlite3AffinityType(&pExpr->token); + switch( aff ){ + case SQLITE_AFF_INTEGER: op = OP_ToInt; break; + case SQLITE_AFF_NUMERIC: op = OP_ToNumeric; break; + case SQLITE_AFF_TEXT: op = OP_ToText; break; + case SQLITE_AFF_NONE: op = OP_ToBlob; break; + } + sqlite3VdbeAddOp(v, op, 0, 0); + break; + } +#endif /* SQLITE_OMIT_CAST */ case TK_LT: case TK_LE: case TK_GT: @@ -1663,9 +1745,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( pExpr->iColumn==OE_Rollback || pExpr->iColumn == OE_Abort || pExpr->iColumn == OE_Fail ); + sqlite3DequoteExpr(pExpr); sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, pExpr->token.z, pExpr->token.n); - sqlite3VdbeDequoteP3(v, -1); } else { assert( pExpr->iColumn == OE_Ignore ); sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0); @@ -1717,11 +1799,9 @@ int sqlite3ExprCodeExprList( ){ struct ExprList_item *pItem; int i, n; - Vdbe *v; if( pList==0 ) return 0; - v = sqlite3GetVdbe(pParse); n = pList->nExpr; - for(pItem=pList->a, i=0; ia, i=n; i>0; i--, pItem++){ sqlite3ExprCode(pParse, pItem->pExpr); } return n; diff --git a/ext/pdo_sqlite/sqlite/src/func.c b/ext/pdo_sqlite/sqlite/src/func.c index 92b8625fc6..326d98eef6 100644 --- a/ext/pdo_sqlite/sqlite/src/func.c +++ b/ext/pdo_sqlite/sqlite/src/func.c @@ -26,6 +26,9 @@ #include "vdbeInt.h" #include "os.h" +/* +** Return the collating function associated with a function. +*/ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ return context->pColl; } @@ -78,6 +81,7 @@ static void typeofFunc( sqlite3_result_text(context, z, -1, SQLITE_STATIC); } + /* ** Implementation of the length() function */ @@ -183,7 +187,7 @@ static void substrFunc( static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int n = 0; double r; - char zBuf[100]; + char zBuf[500]; /* larger than the %f representation of the largest double */ assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; @@ -193,7 +197,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ } if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; r = sqlite3_value_double(argv[0]); - sprintf(zBuf,"%.*f",n,r); + sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } @@ -307,8 +311,14 @@ struct compareInfo { u8 matchSet; u8 noCase; }; + static const struct compareInfo globInfo = { '*', '?', '[', 0 }; -static const struct compareInfo likeInfo = { '%', '_', 0, 1 }; +/* The correct SQL-92 behavior is for the LIKE operator to ignore +** case. Thus 'a' LIKE 'A' would be true. */ +static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 }; +/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator +** is case sensitive causing 'a' LIKE 'A' to be false */ +static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 }; /* ** X is a pointer to the first byte of a UTF-8 character. Increment @@ -450,6 +460,15 @@ static int patternCompare( return *zString==0; } +/* +** Count the number of times that the LIKE operator (or GLOB which is +** just a variation of LIKE) gets called. This is used for testing +** only. +*/ +#ifdef SQLITE_TEST +int sqlite3_like_count = 0; +#endif + /* ** Implementation of the like() SQL function. This function implements @@ -460,8 +479,8 @@ static int patternCompare( ** ** is implemented as like(B,A). ** -** If the pointer retrieved by via a call to sqlite3_user_data() is -** not NULL, then this function uses UTF-16. Otherwise UTF-8. +** This same function (with a different compareInfo structure) computes +** the GLOB operator. */ static void likeFunc( sqlite3_context *context, @@ -484,24 +503,11 @@ static void likeFunc( escape = sqlite3ReadUtf8(zEsc); } if( zA && zB ){ - sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo, escape)); - } -} - -/* -** Implementation of the glob() SQL function. This function implements -** the build-in GLOB operator. The first argument to the function is the -** string and the second argument is the pattern. So, the SQL statements: -** -** A GLOB 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, 0)); + struct compareInfo *pInfo = sqlite3_user_data(context); +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + sqlite3_result_int(context, patternCompare(zA, zB, pInfo, escape)); } } @@ -876,16 +882,6 @@ static void countFinalize(sqlite3_context *context){ sqlite3_result_int(context, p ? p->n : 0); } -/* -** This function tracks state information for the min() and max() -** aggregate functions. -*/ -typedef struct MinMaxCtx MinMaxCtx; -struct MinMaxCtx { - char *z; /* The best so far */ - char zBuf[28]; /* Space that can be used for storage */ -}; - /* ** Routines to implement min() and max() aggregate functions. */ @@ -962,9 +958,6 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "coalesce", 1, 0, SQLITE_UTF8, 0, 0 }, { "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}, { "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc }, @@ -1036,8 +1029,77 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ } sqlite3RegisterDateTimeFunctions(db); #ifdef SQLITE_SSE - { - sqlite3SseFunctions(db); - } + sqlite3SseFunctions(db); +#endif +#ifdef SQLITE_CASE_SENSITIVE_LIKE + sqlite3RegisterLikeFunctions(db, 1); +#else + sqlite3RegisterLikeFunctions(db, 0); #endif } + +/* +** Set the LIKEOPT flag on the 2-argument function with the given name. +*/ +static void setLikeOptFlag(sqlite3 *db, const char *zName){ + FuncDef *pDef; + pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0); + if( pDef ){ + pDef->flags = SQLITE_FUNC_LIKEOPT; + } +} + +/* +** Register the built-in LIKE and GLOB functions. The caseSensitive +** parameter determines whether or not the LIKE operator is case +** sensitive. GLOB is always case sensitive. +*/ +void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ + struct compareInfo *pInfo; + if( caseSensitive ){ + pInfo = (struct compareInfo*)&likeInfoAlt; + }else{ + pInfo = (struct compareInfo*)&likeInfoNorm; + } + sqlite3_create_function(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0); + sqlite3_create_function(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0); + sqlite3_create_function(db, "glob", 2, SQLITE_UTF8, + (struct compareInfo*)&globInfo, likeFunc, 0,0); + setLikeOptFlag(db, "glob"); + if( caseSensitive ){ + setLikeOptFlag(db, "like"); + } +} + +/* +** pExpr points to an expression which implements a function. If +** it is appropriate to apply the LIKE optimization to that function +** then set aWc[0] through aWc[2] to the wildcard characters and +** return TRUE. If the function is not a LIKE-style function then +** return FALSE. +*/ +int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, char *aWc){ + FuncDef *pDef; + if( pExpr->op!=TK_FUNCTION ){ + return 0; + } + if( pExpr->pList->nExpr!=2 ){ + return 0; + } + pDef = sqlite3FindFunction(db, pExpr->token.z, pExpr->token.n, 2, + SQLITE_UTF8, 0); + if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKEOPT)==0 ){ + return 0; + } + + /* The memcpy() statement assumes that the wildcard characters are + ** the first three statements in the compareInfo structure. The + ** asserts() that follow verify that assumption + */ + memcpy(aWc, pDef->pUserData, 3); + assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); + assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); + assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); + + return 1; +} diff --git a/ext/pdo_sqlite/sqlite/src/insert.c b/ext/pdo_sqlite/sqlite/src/insert.c index ebcc70aedf..52ac2e55ca 100644 --- a/ext/pdo_sqlite/sqlite/src/insert.c +++ b/ext/pdo_sqlite/sqlite/src/insert.c @@ -373,7 +373,7 @@ void sqlite3Insert( ** back up and execute the SELECT code above. */ sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v)); - sqlite3VdbeAddOp(v, OP_OpenTemp, srcTab, 0); + sqlite3VdbeAddOp(v, OP_OpenVirtual, srcTab, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn); sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop); sqlite3VdbeResolveLabel(v, iCleanup); @@ -949,7 +949,7 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1); } } - jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); + jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0); sqlite3IndexAffinityStr(v, pIdx); /* Find out what action to take in case there is an indexing conflict */ @@ -1019,9 +1019,8 @@ void sqlite3GenerateConstraintChecks( } } contAddr = sqlite3VdbeCurrentAddr(v); - assert( contAddr<(1<<24) ); #if NULL_DISTINCT_FOR_UNIQUE - sqlite3VdbeChangeP2(v, jumpInst1, contAddr | (1<<24)); + sqlite3VdbeChangeP2(v, jumpInst1, contAddr); #endif sqlite3VdbeChangeP2(v, jumpInst2, contAddr); } @@ -1097,11 +1096,12 @@ void sqlite3OpenTableAndIndices( Vdbe *v = sqlite3GetVdbe(pParse); assert( v!=0 ); sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, op, base, pTab->tnum); VdbeComment((v, "# %s", pTab->zName)); + sqlite3VdbeAddOp(v, op, base, pTab->tnum); sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0); + VdbeComment((v, "# %s", pIdx->zName)); sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)&pIdx->keyInfo, P3_KEYINFO); } diff --git a/ext/pdo_sqlite/sqlite/src/keywordhash.h b/ext/pdo_sqlite/sqlite/src/keywordhash.h index 2eef13b20d..f825ba977c 100644 --- a/ext/pdo_sqlite/sqlite/src/keywordhash.h +++ b/ext/pdo_sqlite/sqlite/src/keywordhash.h @@ -1,83 +1,84 @@ -/* Hash score: 153 */ +/* Hash score: 156 */ static int keywordCode(const char *z, int n){ - static const char zText[515] = + static const char zText[526] = "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER" - "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYAND" - "EFERRABLEXCLUSIVEXISTSTATEMENTATTACHAVINGLOBEFOREIGNOREINDEXAUTOINCREMENT" - "BEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETECASECOLLATECOLUMN" - "COMMITCONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATECURRENT_TIMESTAMP" - "RAGMATCHDESCDETACHDISTINCTDROPRIMARYFAILIMITFROMFULLGROUPDATE" - "IMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDEREPLACEOUTERESTRICT" - "RIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEWHERE"; + "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYANALYZE" + "XCLUSIVEXISTSTATEMENTANDEFERRABLEATTACHAVINGLOBEFOREIGNOREINDEX" + "AUTOINCREMENTBEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETE" + "CASECASTCOLLATECOLUMNCOMMITCONFLICTCONSTRAINTERSECTCREATECROSS" + "CURRENT_DATECURRENT_TIMESTAMPRAGMATCHDESCDETACHDISTINCTDROPRIMARY" + "FAILIMITFROMFULLGROUPDATEIMMEDIATEINSERTINSTEADINTOFFSETISNULL" + "JOINORDEREPLACEOUTERESTRICTRIGHTROLLBACKROWHENUNIONUNIQUEUSING" + "VACUUMVALUESVIEWHERE"; static const unsigned char aHash[127] = { - 89, 79, 102, 88, 0, 4, 0, 0, 109, 0, 75, 0, 0, - 92, 43, 0, 90, 0, 101, 104, 94, 0, 0, 10, 0, 0, - 108, 0, 105, 100, 0, 28, 47, 0, 40, 0, 0, 63, 69, - 0, 62, 19, 0, 0, 32, 81, 0, 103, 72, 0, 0, 34, - 0, 60, 33, 0, 8, 0, 110, 37, 12, 0, 76, 39, 25, - 64, 0, 0, 31, 80, 52, 30, 49, 20, 86, 0, 35, 0, - 73, 26, 0, 70, 0, 0, 0, 0, 46, 65, 22, 85, 29, - 67, 84, 0, 1, 0, 9, 98, 57, 18, 0, 107, 74, 96, - 53, 6, 83, 0, 0, 48, 91, 0, 99, 0, 68, 0, 0, - 15, 0, 111, 50, 55, 0, 2, 54, 0, 106, + 91, 81, 104, 90, 0, 4, 0, 0, 111, 0, 77, 0, 0, + 94, 44, 0, 92, 0, 103, 106, 96, 0, 0, 10, 0, 0, + 110, 0, 107, 102, 0, 28, 48, 0, 41, 0, 0, 65, 71, + 0, 63, 19, 0, 0, 36, 83, 0, 105, 74, 0, 0, 33, + 0, 61, 37, 0, 8, 0, 112, 38, 12, 0, 78, 40, 25, + 66, 0, 0, 31, 82, 53, 30, 50, 20, 88, 0, 34, 0, + 75, 26, 0, 72, 0, 0, 0, 64, 47, 67, 22, 87, 29, + 69, 86, 0, 1, 0, 9, 100, 58, 18, 0, 109, 76, 98, + 54, 6, 85, 0, 0, 49, 93, 0, 101, 0, 70, 0, 0, + 15, 0, 113, 51, 56, 0, 2, 55, 0, 108, }; - static const unsigned char aNext[111] = { + static const unsigned char aNext[113] = { 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, - 0, 11, 0, 0, 0, 7, 0, 5, 13, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, - 0, 16, 0, 23, 51, 0, 0, 0, 0, 44, 58, 0, 0, - 0, 0, 0, 0, 0, 0, 71, 41, 0, 0, 24, 59, 21, - 0, 78, 0, 66, 0, 0, 82, 45, 0, 0, 0, 0, 0, - 0, 0, 38, 93, 95, 0, 0, 97, 0, 14, 27, 77, 0, - 56, 87, 0, 36, 0, 61, 0, + 0, 11, 0, 0, 0, 0, 5, 13, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 23, 52, 0, 0, 0, 0, 45, 0, 59, + 0, 0, 0, 0, 0, 0, 0, 0, 73, 42, 0, 0, 24, + 60, 21, 0, 80, 32, 68, 0, 0, 84, 46, 0, 0, 0, + 0, 0, 0, 0, 39, 95, 97, 0, 0, 99, 0, 14, 27, + 79, 0, 57, 89, 0, 35, 0, 62, 0, }; - static const unsigned char aLen[111] = { + static const unsigned char aLen[113] = { 5, 5, 4, 4, 9, 2, 3, 8, 2, 6, 4, 3, 7, 11, 2, 7, 5, 5, 4, 5, 3, 5, 10, 6, 4, 6, - 7, 6, 7, 9, 3, 3, 10, 9, 6, 9, 6, 6, 4, - 6, 3, 7, 6, 7, 5, 13, 2, 2, 5, 5, 6, 7, - 3, 7, 4, 4, 2, 7, 3, 8, 6, 4, 7, 6, 6, - 8, 10, 9, 6, 5, 12, 12, 17, 6, 5, 4, 6, 8, - 2, 4, 7, 4, 5, 4, 4, 5, 6, 9, 6, 7, 4, - 2, 6, 3, 6, 4, 5, 7, 5, 8, 5, 8, 3, 4, - 5, 6, 5, 6, 6, 4, 5, + 7, 6, 7, 9, 3, 7, 9, 6, 9, 3, 10, 6, 6, + 4, 6, 3, 7, 6, 7, 5, 13, 2, 2, 5, 5, 6, + 7, 3, 7, 4, 4, 2, 7, 3, 8, 6, 4, 4, 7, + 6, 6, 8, 10, 9, 6, 5, 12, 12, 17, 6, 5, 4, + 6, 8, 2, 4, 7, 4, 5, 4, 4, 5, 6, 9, 6, + 7, 4, 2, 6, 3, 6, 4, 5, 7, 5, 8, 5, 8, + 3, 4, 5, 6, 5, 6, 6, 4, 5, }; - static const unsigned short int aOffset[111] = { + static const unsigned short int aOffset[113] = { 0, 4, 7, 10, 10, 14, 19, 21, 26, 27, 32, 34, 36, 42, 51, 52, 57, 61, 65, 67, 71, 74, 78, 86, 91, 94, - 99, 105, 108, 113, 118, 122, 124, 133, 141, 146, 155, 160, 165, - 168, 170, 170, 174, 178, 180, 185, 187, 189, 198, 201, 205, 211, - 217, 217, 220, 223, 227, 229, 230, 234, 241, 247, 251, 258, 264, - 270, 278, 285, 294, 300, 305, 317, 317, 333, 337, 342, 346, 352, - 353, 360, 363, 370, 373, 378, 382, 386, 389, 395, 404, 410, 417, - 420, 420, 423, 426, 432, 436, 440, 447, 451, 459, 464, 472, 474, - 478, 483, 489, 494, 500, 506, 509, + 99, 105, 108, 113, 118, 122, 128, 136, 141, 150, 152, 162, 167, + 172, 175, 177, 177, 181, 185, 187, 192, 194, 196, 205, 208, 212, + 218, 224, 224, 227, 230, 234, 236, 237, 241, 248, 254, 258, 262, + 269, 275, 281, 289, 296, 305, 311, 316, 328, 328, 344, 348, 353, + 357, 363, 364, 371, 374, 381, 384, 389, 393, 397, 400, 406, 415, + 421, 428, 431, 431, 434, 437, 443, 447, 451, 458, 462, 470, 475, + 483, 485, 489, 494, 500, 505, 511, 517, 520, }; - static const unsigned char aCode[111] = { + static const unsigned char aCode[113] = { TK_ABORT, TK_TABLE, TK_JOIN_KW, TK_TEMP, TK_TEMP, TK_OR, TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_THEN, TK_END, TK_DEFAULT, TK_TRANSACTION,TK_ON, TK_JOIN_KW, TK_ALTER, TK_RAISE, TK_EACH, TK_CHECK, TK_KEY, TK_AFTER, TK_REFERENCES, TK_ESCAPE, TK_ELSE, TK_EXCEPT, TK_TRIGGER, TK_LIKE_KW, TK_EXPLAIN, TK_INITIALLY, - TK_ALL, TK_AND, TK_DEFERRABLE, TK_EXCLUSIVE, TK_EXISTS, - TK_STATEMENT, TK_ATTACH, TK_HAVING, TK_LIKE_KW, TK_BEFORE, - TK_FOR, TK_FOREIGN, TK_IGNORE, TK_REINDEX, TK_INDEX, - TK_AUTOINCR, TK_TO, TK_IN, TK_BEGIN, TK_JOIN_KW, - TK_RENAME, TK_BETWEEN, TK_NOT, TK_NOTNULL, TK_NULL, - TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC, TK_DEFERRED, - TK_DELETE, TK_CASE, TK_COLLATE, TK_COLUMNKW, TK_COMMIT, - TK_CONFLICT, TK_CONSTRAINT, TK_INTERSECT, TK_CREATE, TK_JOIN_KW, - TK_CTIME_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRAGMA, TK_MATCH, - TK_DESC, TK_DETACH, TK_DISTINCT, TK_IS, TK_DROP, - TK_PRIMARY, TK_FAIL, TK_LIMIT, TK_FROM, TK_JOIN_KW, - TK_GROUP, TK_UPDATE, TK_IMMEDIATE, TK_INSERT, TK_INSTEAD, - TK_INTO, TK_OF, TK_OFFSET, TK_SET, TK_ISNULL, - TK_JOIN, TK_ORDER, TK_REPLACE, TK_JOIN_KW, TK_RESTRICT, - TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_WHEN, TK_UNION, - TK_UNIQUE, TK_USING, TK_VACUUM, TK_VALUES, TK_VIEW, - TK_WHERE, + TK_ALL, TK_ANALYZE, TK_EXCLUSIVE, TK_EXISTS, TK_STATEMENT, + TK_AND, TK_DEFERRABLE, TK_ATTACH, TK_HAVING, TK_LIKE_KW, + TK_BEFORE, TK_FOR, TK_FOREIGN, TK_IGNORE, TK_REINDEX, + TK_INDEX, TK_AUTOINCR, TK_TO, TK_IN, TK_BEGIN, + TK_JOIN_KW, TK_RENAME, TK_BETWEEN, TK_NOT, TK_NOTNULL, + TK_NULL, TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC, + TK_DEFERRED, TK_DELETE, TK_CASE, TK_CAST, TK_COLLATE, + TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_CONSTRAINT, TK_INTERSECT, + TK_CREATE, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_CTIME_KW, + TK_PRAGMA, TK_MATCH, TK_DESC, TK_DETACH, TK_DISTINCT, + TK_IS, TK_DROP, TK_PRIMARY, TK_FAIL, TK_LIMIT, + TK_FROM, TK_JOIN_KW, TK_GROUP, TK_UPDATE, TK_IMMEDIATE, + TK_INSERT, TK_INSTEAD, TK_INTO, TK_OF, TK_OFFSET, + TK_SET, TK_ISNULL, TK_JOIN, TK_ORDER, TK_REPLACE, + TK_JOIN_KW, TK_RESTRICT, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, + TK_WHEN, TK_UNION, TK_UNIQUE, TK_USING, TK_VACUUM, + TK_VALUES, TK_VIEW, TK_WHERE, }; int h, i; if( n<2 ) return TK_ID; diff --git a/ext/pdo_sqlite/sqlite/src/main.c b/ext/pdo_sqlite/sqlite/src/main.c index dfc9dd7c62..d0ecd4fe52 100644 --- a/ext/pdo_sqlite/sqlite/src/main.c +++ b/ext/pdo_sqlite/sqlite/src/main.c @@ -234,7 +234,6 @@ const char *sqlite3ErrStr(int rc){ case SQLITE_DONE: case SQLITE_OK: z = "not an error"; break; case SQLITE_ERROR: z = "SQL logic error or missing database"; break; - case SQLITE_INTERNAL: z = "internal SQLite implementation flaw"; break; case SQLITE_PERM: z = "access permission denied"; break; case SQLITE_ABORT: z = "callback requested query abort"; break; case SQLITE_BUSY: z = "database is locked"; break; @@ -244,13 +243,11 @@ const char *sqlite3ErrStr(int rc){ case SQLITE_INTERRUPT: z = "interrupted"; break; case SQLITE_IOERR: z = "disk I/O error"; break; case SQLITE_CORRUPT: z = "database disk image is malformed"; break; - case SQLITE_NOTFOUND: z = "table or record not found"; break; - case SQLITE_FULL: z = "database is full"; break; + case SQLITE_FULL: z = "database or disk is full"; break; case SQLITE_CANTOPEN: z = "unable to open database file"; break; case SQLITE_PROTOCOL: z = "database locking protocol failure"; break; case SQLITE_EMPTY: z = "table contains no data"; break; case SQLITE_SCHEMA: z = "database schema has changed"; break; - case SQLITE_TOOBIG: z = "too much data for one table row"; break; case SQLITE_CONSTRAINT: z = "constraint failed"; break; case SQLITE_MISMATCH: z = "datatype mismatch"; break; case SQLITE_MISUSE: z = "library routine called out of sequence";break; @@ -298,7 +295,7 @@ static int sqliteDefaultBusyCallback( sqlite3OsSleep(delay); return 1; #else - int timeout = (int)Timeout; + int timeout = ((sqlite3 *)ptr)->busyTimeout; if( (count+1)*1000 > timeout ){ return 0; } @@ -307,6 +304,25 @@ static int sqliteDefaultBusyCallback( #endif } +/* +** Invoke the given busy handler. +** +** This routine is called when an operation failed with a lock. +** If this routine returns non-zero, the lock is retried. If it +** returns 0, the operation aborts with an SQLITE_BUSY error. +*/ +int sqlite3InvokeBusyHandler(BusyHandler *p){ + int rc; + if( p==0 || p->xFunc==0 || p->nBusy<0 ) return 0; + rc = p->xFunc(p->pArg, p->nBusy); + if( rc==0 ){ + p->nBusy = -1; + }else{ + p->nBusy++; + } + return rc; +} + /* ** This routine sets the busy callback for an Sqlite database to the ** given callback function with the given argument. @@ -321,6 +337,7 @@ int sqlite3_busy_handler( } db->busyHandler.xFunc = xBusy; db->busyHandler.pArg = pArg; + db->busyHandler.nBusy = 0; return SQLITE_OK; } @@ -454,6 +471,7 @@ int sqlite3_create_function( p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); if( p==0 ) return SQLITE_NOMEM; + p->flags = 0; p->xFunc = xFunc; p->xStep = xStep; p->xFinalize = xFinal; @@ -530,11 +548,11 @@ void *sqlite3_commit_hook( ** opened and used. If zFilename is the magic name ":memory:" then ** the database is stored in memory (and is thus forgotten as soon as ** the connection is closed.) If zFilename is NULL then the database -** is for temporary use only and is deleted as soon as the connection -** is closed. +** is a "virtual" database for transient use only and is deleted as +** soon as the connection is closed. ** -** A temporary database can be either a disk file (that is automatically -** deleted when the file is closed) or a set of red-black trees held in memory, +** A virtual database can be either a disk file (that is automatically +** deleted when the file is closed) or it an be held entirely in memory, ** depending on the values of the TEMP_STORE compile-time macro and the ** db->temp_store variable, according to the following chart: ** diff --git a/ext/pdo_sqlite/sqlite/src/opcodes.h b/ext/pdo_sqlite/sqlite/src/opcodes.h index 9757cd8ac2..dd8823c277 100644 --- a/ext/pdo_sqlite/sqlite/src/opcodes.h +++ b/ext/pdo_sqlite/sqlite/src/opcodes.h @@ -1,51 +1,51 @@ /* Automatically generated. Do not edit */ /* See the mkopcodeh.awk script for details */ #define OP_MemLoad 1 -#define OP_HexBlob 129 /* same as TK_BLOB */ +#define OP_HexBlob 131 /* same as TK_BLOB */ #define OP_Column 2 #define OP_SetCookie 3 #define OP_IfMemPos 4 -#define OP_Real 128 /* same as TK_FLOAT */ +#define OP_Real 130 /* same as TK_FLOAT */ #define OP_MoveGt 5 -#define OP_Ge 75 /* same as TK_GE */ +#define OP_Ge 77 /* same as TK_GE */ #define OP_AggFocus 6 #define OP_RowKey 7 #define OP_AggNext 8 -#define OP_Eq 71 /* same as TK_EQ */ +#define OP_Eq 73 /* same as TK_EQ */ #define OP_OpenWrite 9 -#define OP_NotNull 69 /* same as TK_NOTNULL */ +#define OP_NotNull 71 /* same as TK_NOTNULL */ #define OP_If 10 -#define OP_String8 90 /* same as TK_STRING */ -#define OP_Pop 11 -#define OP_AggContextPush 12 -#define OP_CollSeq 13 -#define OP_OpenRead 14 -#define OP_Expire 15 -#define OP_SortReset 16 -#define OP_AutoCommit 17 -#define OP_Gt 72 /* same as TK_GT */ -#define OP_Sort 18 -#define OP_ListRewind 19 +#define OP_ToInt 11 +#define OP_String8 92 /* same as TK_STRING */ +#define OP_Pop 12 +#define OP_AggContextPush 13 +#define OP_CollSeq 14 +#define OP_OpenRead 15 +#define OP_Expire 16 +#define OP_SortReset 17 +#define OP_AutoCommit 18 +#define OP_Gt 74 /* same as TK_GT */ +#define OP_Sort 19 #define OP_IntegrityCk 20 #define OP_SortInsert 21 #define OP_Function 22 -#define OP_And 63 /* same as TK_AND */ -#define OP_Subtract 82 /* same as TK_MINUS */ +#define OP_And 65 /* same as TK_AND */ +#define OP_Subtract 84 /* same as TK_MINUS */ #define OP_Noop 23 #define OP_Return 24 -#define OP_Remainder 85 /* same as TK_REM */ +#define OP_Remainder 87 /* same as TK_REM */ #define OP_NewRowid 25 -#define OP_Multiply 83 /* same as TK_STAR */ +#define OP_Multiply 85 /* same as TK_STAR */ #define OP_Variable 26 #define OP_String 27 #define OP_ParseSchema 28 #define OP_AggFunc 29 #define OP_Close 30 -#define OP_ListWrite 31 -#define OP_CreateIndex 32 -#define OP_IsUnique 33 -#define OP_IdxIsNull 34 -#define OP_NotFound 35 +#define OP_CreateIndex 31 +#define OP_IsUnique 32 +#define OP_IdxIsNull 33 +#define OP_NotFound 34 +#define OP_Int64 35 #define OP_MustBeInt 36 #define OP_Halt 37 #define OP_Rowid 38 @@ -55,90 +55,90 @@ #define OP_RowData 42 #define OP_MemMax 43 #define OP_Push 44 -#define OP_Or 62 /* same as TK_OR */ +#define OP_Or 64 /* same as TK_OR */ #define OP_NotExists 45 -#define OP_OpenTemp 46 -#define OP_MemIncr 47 -#define OP_Gosub 48 -#define OP_Divide 84 /* same as TK_SLASH */ -#define OP_AggSet 49 -#define OP_Integer 50 +#define OP_MemIncr 46 +#define OP_Gosub 47 +#define OP_Divide 86 /* same as TK_SLASH */ +#define OP_AggSet 48 +#define OP_Integer 49 +#define OP_ToNumeric 50 #define OP_SortNext 51 #define OP_Prev 52 -#define OP_Concat 86 /* same as TK_CONCAT */ -#define OP_BitAnd 77 /* same as TK_BITAND */ +#define OP_Concat 88 /* same as TK_CONCAT */ +#define OP_BitAnd 79 /* same as TK_BITAND */ #define OP_CreateTable 53 #define OP_Last 54 -#define OP_IsNull 68 /* same as TK_ISNULL */ +#define OP_IsNull 70 /* same as TK_ISNULL */ #define OP_IdxRowid 55 -#define OP_ShiftRight 80 /* same as TK_RSHIFT */ -#define OP_ResetCount 56 -#define OP_Callback 57 -#define OP_ContextPush 58 -#define OP_DropTrigger 59 -#define OP_DropIndex 60 -#define OP_IdxGE 61 -#define OP_IdxDelete 65 -#define OP_Vacuum 66 -#define OP_MoveLe 67 -#define OP_IfNot 76 -#define OP_DropTable 88 -#define OP_MakeRecord 91 -#define OP_Delete 92 -#define OP_AggContextPop 93 -#define OP_ListRead 94 -#define OP_ListReset 95 -#define OP_ShiftLeft 79 /* same as TK_LSHIFT */ -#define OP_Dup 96 -#define OP_Goto 97 -#define OP_Clear 98 -#define OP_IdxGT 99 -#define OP_MoveLt 100 -#define OP_Le 73 /* same as TK_LE */ -#define OP_VerifyCookie 101 -#define OP_Pull 102 -#define OP_Not 64 /* same as TK_NOT */ -#define OP_SetNumColumns 103 -#define OP_AbsValue 104 -#define OP_Transaction 105 -#define OP_Negative 87 /* same as TK_UMINUS */ -#define OP_Ne 70 /* same as TK_NE */ -#define OP_AggGet 106 -#define OP_ContextPop 107 -#define OP_BitOr 78 /* same as TK_BITOR */ -#define OP_Next 108 -#define OP_AggInit 109 -#define OP_IdxInsert 110 -#define OP_Distinct 111 -#define OP_Lt 74 /* same as TK_LT */ -#define OP_AggReset 112 -#define OP_Insert 113 -#define OP_Destroy 114 -#define OP_ReadCookie 115 -#define OP_ForceInt 116 -#define OP_OpenPseudo 117 -#define OP_Null 118 -#define OP_Blob 119 -#define OP_Add 81 /* same as TK_PLUS */ -#define OP_MemStore 120 -#define OP_Rewind 121 -#define OP_MoveGe 122 -#define OP_BitNot 89 /* same as TK_BITNOT */ -#define OP_Found 123 -#define OP_NullRow 124 - -/* The following opcode values are never used */ -#define OP_NotUsed_125 125 -#define OP_NotUsed_126 126 -#define OP_NotUsed_127 127 +#define OP_MakeIdxRec 56 +#define OP_ShiftRight 82 /* same as TK_RSHIFT */ +#define OP_ResetCount 57 +#define OP_FifoWrite 58 +#define OP_Callback 59 +#define OP_ContextPush 60 +#define OP_DropTrigger 61 +#define OP_DropIndex 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_ToBlob 94 +#define OP_Delete 95 +#define OP_AggContextPop 96 +#define OP_ShiftLeft 81 /* same as TK_LSHIFT */ +#define OP_Dup 97 +#define OP_Goto 98 +#define OP_FifoRead 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_ToText 105 +#define OP_Not 66 /* same as TK_NOT */ +#define OP_SetNumColumns 106 +#define OP_AbsValue 107 +#define OP_Transaction 108 +#define OP_Negative 89 /* same as TK_UMINUS */ +#define OP_Ne 72 /* same as TK_NE */ +#define OP_AggGet 109 +#define OP_ContextPop 110 +#define OP_BitOr 80 /* same as TK_BITOR */ +#define OP_Next 111 +#define OP_AggInit 112 +#define OP_IdxInsert 113 +#define OP_Distinct 114 +#define OP_Lt 76 /* same as TK_LT */ +#define OP_AggReset 115 +#define OP_Insert 116 +#define OP_Destroy 117 +#define OP_ReadCookie 118 +#define OP_ForceInt 119 +#define OP_LoadAnalysis 120 +#define OP_OpenVirtual 121 +#define OP_OpenPseudo 122 +#define OP_Null 123 +#define OP_Blob 124 +#define OP_Add 83 /* same as TK_PLUS */ +#define OP_MemStore 125 +#define OP_Rewind 126 +#define OP_MoveGe 127 +#define OP_BitNot 91 /* same as TK_BITNOT */ +#define OP_Found 128 +#define OP_NullRow 129 #define NOPUSH_MASK_0 65400 -#define NOPUSH_MASK_1 61871 -#define NOPUSH_MASK_2 64446 -#define NOPUSH_MASK_3 65363 +#define NOPUSH_MASK_1 29103 +#define NOPUSH_MASK_2 64439 +#define NOPUSH_MASK_3 65109 #define NOPUSH_MASK_4 65535 -#define NOPUSH_MASK_5 46015 -#define NOPUSH_MASK_6 64254 -#define NOPUSH_MASK_7 7987 -#define NOPUSH_MASK_8 0 +#define NOPUSH_MASK_5 52991 +#define NOPUSH_MASK_6 55285 +#define NOPUSH_MASK_7 59295 +#define NOPUSH_MASK_8 3 #define NOPUSH_MASK_9 0 diff --git a/ext/pdo_sqlite/sqlite/src/os_unix.c b/ext/pdo_sqlite/sqlite/src/os_unix.c index 9c361a1717..2ea9aa8e35 100644 --- a/ext/pdo_sqlite/sqlite/src/os_unix.c +++ b/ext/pdo_sqlite/sqlite/src/os_unix.c @@ -57,24 +57,35 @@ #endif /* -** Macros used to determine whether or not to use threads. The -** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for -** Posix threads and SQLITE_W32_THREADS is defined if we are -** synchronizing using Win32 threads. +** Include code that is common to all os_*.c files */ -#if defined(THREADSAFE) && THREADSAFE -# include -# define SQLITE_UNIX_THREADS 1 -#endif - +#include "os_common.h" /* -** Include code that is common to all os_*.c files +** The threadid macro resolves to the thread-id or to 0. Used for +** testing and debugging only. */ -#include "os_common.h" +#ifdef SQLITE_UNIX_THREADS +#define threadid pthread_self() +#else +#define threadid 0 +#endif -#if defined(THREADSAFE) && THREADSAFE && defined(__linux__) -#define getpid pthread_self +/* +** Set or check the OsFile.tid field. This field is set when an OsFile +** is first opened. All subsequent uses of the OsFile verify that the +** same thread is operating on the OsFile. Some operating systems do +** not allow locks to be overridden by other threads and that restriction +** means that sqlite3* database handles cannot be moved from one thread +** to another. This logic makes sure a user does not try to do that +** by mistake. +*/ +#ifdef SQLITE_UNIX_THREADS +# define SET_THREADID(X) X->tid = pthread_self() +# define CHECK_THREADID(X) (!pthread_equal(X->tid, pthread_self())) +#else +# define SET_THREADID(X) +# define CHECK_THREADID(X) 0 #endif /* @@ -264,6 +275,65 @@ struct threadTestData { int result; /* Result of the locking operation */ }; +#ifdef SQLITE_LOCK_TRACE +/* +** Print out information about all locking operations. +** +** This routine is used for troubleshooting locks on multithreaded +** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE +** command-line option on the compiler. This code is normally +** turnned off. +*/ +static int lockTrace(int fd, int op, struct flock *p){ + char *zOpName, *zType; + int s; + int savedErrno; + if( op==F_GETLK ){ + zOpName = "GETLK"; + }else if( op==F_SETLK ){ + zOpName = "SETLK"; + }else{ + s = fcntl(fd, op, p); + sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); + return s; + } + if( p->l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( p->l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( p->l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + assert( p->l_whence==SEEK_SET ); + s = fcntl(fd, op, p); + savedErrno = errno; + sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", + threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, + (int)p->l_pid, s); + if( s && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ + struct flock l2; + l2 = *p; + fcntl(fd, F_GETLK, &l2); + if( l2.l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( l2.l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( l2.l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", + zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); + } + errno = savedErrno; + return s; +} +#define fcntl lockTrace +#endif /* SQLITE_LOCK_TRACE */ + /* ** The testThreadLockingBehavior() routine launches two separate ** threads on this routine. This routine attempts to lock a file @@ -443,6 +513,7 @@ int sqlite3OsOpenReadWrite( int rc; assert( !id->isOpen ); id->dirfd = -1; + SET_THREADID(id); id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, SQLITE_DEFAULT_FILE_PERMISSIONS); if( id->h<0 ){ @@ -494,9 +565,11 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ if( access(zFilename, 0)==0 ){ return SQLITE_CANTOPEN; } + SET_THREADID(id); id->dirfd = -1; id->h = open(zFilename, - O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600); + O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, + SQLITE_DEFAULT_FILE_PERMISSIONS); if( id->h<0 ){ return SQLITE_CANTOPEN; } @@ -528,6 +601,7 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){ int rc; assert( !id->isOpen ); + SET_THREADID(id); id->dirfd = -1; id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); if( id->h<0 ){ @@ -572,6 +646,7 @@ int sqlite3OsOpenDirectory( ** open. */ return SQLITE_CANTOPEN; } + SET_THREADID(id); assert( id->dirfd<0 ); id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0); if( id->dirfd<0 ){ @@ -839,6 +914,7 @@ int sqlite3OsCheckReservedLock(OsFile *id){ int r = 0; assert( id->isOpen ); + if( CHECK_THREADID(id) ) return SQLITE_MISUSE; sqlite3OsEnterMutex(); /* Needed because id->pLock is shared across threads */ /* Check if a thread in this process holds such a lock */ @@ -956,6 +1032,7 @@ int sqlite3OsLock(OsFile *id, int locktype){ TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt ,getpid() ); + if( CHECK_THREADID(id) ) return SQLITE_MISUSE; /* If there is already a lock of this type or more restrictive on the ** OsFile, do nothing. Don't use the end_lock: exit path, as @@ -1002,6 +1079,7 @@ int sqlite3OsLock(OsFile *id, int locktype){ } lock.l_len = 1L; + lock.l_whence = SEEK_SET; /* A PENDING lock is needed before acquiring a SHARED lock and before @@ -1037,7 +1115,10 @@ int sqlite3OsLock(OsFile *id, int locktype){ lock.l_start = PENDING_BYTE; lock.l_len = 1L; lock.l_type = F_UNLCK; - fcntl(id->h, F_SETLK, &lock); + if( fcntl(id->h, F_SETLK, &lock)!=0 ){ + rc = SQLITE_IOERR; /* This should never happen */ + goto end_lock; + } if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; }else{ @@ -1107,6 +1188,7 @@ int sqlite3OsUnlock(OsFile *id, int locktype){ assert( id->isOpen ); TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, id->pLock->locktype, id->pLock->cnt, getpid()); + if( CHECK_THREADID(id) ) return SQLITE_MISUSE; assert( locktype<=SHARED_LOCK ); if( id->locktype<=locktype ){ @@ -1131,8 +1213,11 @@ int sqlite3OsUnlock(OsFile *id, int locktype){ lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); - fcntl(id->h, F_SETLK, &lock); - pLock->locktype = SHARED_LOCK; + if( fcntl(id->h, F_SETLK, &lock)==0 ){ + pLock->locktype = SHARED_LOCK; + }else{ + rc = SQLITE_IOERR; /* This should never happen */ + } } if( locktype==NO_LOCK ){ struct openCnt *pOpen; @@ -1146,8 +1231,11 @@ int sqlite3OsUnlock(OsFile *id, int locktype){ lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = lock.l_len = 0L; - fcntl(id->h, F_SETLK, &lock); - pLock->locktype = NO_LOCK; + if( fcntl(id->h, F_SETLK, &lock)==0 ){ + pLock->locktype = NO_LOCK; + }else{ + rc = SQLITE_IOERR; /* This should never happen */ + } } /* Decrement the count of locks against this same file. When the @@ -1177,6 +1265,7 @@ int sqlite3OsUnlock(OsFile *id, int locktype){ */ int sqlite3OsClose(OsFile *id){ if( !id->isOpen ) return SQLITE_OK; + if( CHECK_THREADID(id) ) return SQLITE_MISUSE; sqlite3OsUnlock(id, NO_LOCK); if( id->dirfd>=0 ) close(id->dirfd); id->dirfd = -1; @@ -1189,13 +1278,13 @@ int sqlite3OsClose(OsFile *id){ */ int *aNew; struct openCnt *pOpen = id->pOpen; - pOpen->nPending++; - aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) ); + aNew = sqliteRealloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) ); if( aNew==0 ){ /* If a malloc fails, just leak the file descriptor */ }else{ pOpen->aPending = aNew; - pOpen->aPending[pOpen->nPending-1] = id->h; + pOpen->aPending[pOpen->nPending] = id->h; + pOpen->nPending++; } }else{ /* There are no outstanding locks so we can close the file immediately */ diff --git a/ext/pdo_sqlite/sqlite/src/os_unix.h b/ext/pdo_sqlite/sqlite/src/os_unix.h index 4ea0aee362..5fdfc2ff4c 100644 --- a/ext/pdo_sqlite/sqlite/src/os_unix.h +++ b/ext/pdo_sqlite/sqlite/src/os_unix.h @@ -51,6 +51,17 @@ #include #include +/* +** Macros used to determine whether or not to use threads. The +** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for +** Posix threads and SQLITE_W32_THREADS is defined if we are +** synchronizing using Win32 threads. +*/ +#if defined(THREADSAFE) && THREADSAFE +# include +# define SQLITE_UNIX_THREADS 1 +#endif + /* ** The OsFile structure is a operating-system independing representation ** of an open file handle. It is defined differently for each architecture. @@ -70,6 +81,9 @@ struct OsFile { unsigned char isOpen; /* True if needs to be closed */ unsigned char fullSync; /* Use F_FULLSYNC if available */ int dirfd; /* File descriptor for the directory */ +#ifdef SQLITE_UNIX_THREADS + pthread_t tid; /* The thread authorized to use this OsFile */ +#endif }; /* diff --git a/ext/pdo_sqlite/sqlite/src/pager.c b/ext/pdo_sqlite/sqlite/src/pager.c index 892757406f..8fd65ba88e 100644 --- a/ext/pdo_sqlite/sqlite/src/pager.c +++ b/ext/pdo_sqlite/sqlite/src/pager.c @@ -779,7 +779,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ if( rc!=SQLITE_OK ) return rc; rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic)); - pPager->needSync = 1; + pPager->needSync = !pPager->noSync; return rc; } @@ -1758,7 +1758,11 @@ int sqlite3pager_pagecount(Pager *pPager){ pPager->errMask |= PAGER_ERR_DISK; return 0; } - n /= pPager->pageSize; + if( n>0 && npageSize ){ + n = 1; + }else{ + n /= pPager->pageSize; + } if( !MEMDB && n==PENDING_BYTE/pPager->pageSize ){ n++; } @@ -1866,7 +1870,7 @@ static void memoryTruncate(Pager *pPager){ /* ** 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 +** is currently not available. Repeat until the busy callback returns ** false or until the lock succeeds. ** ** Return SQLITE_OK on success and an error code if we cannot obtain @@ -1880,14 +1884,9 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ if( pPager->state>=locktype ){ rc = SQLITE_OK; }else{ - int busy = 1; - BusyHandler *pH; do { rc = sqlite3OsLock(&pPager->fd, locktype); - }while( rc==SQLITE_BUSY && - (pH = pPager->pBusyHandler)!=0 && - pH->xFunc && pH->xFunc(pH->pArg, busy++) - ); + }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) ); if( rc==SQLITE_OK ){ pPager->state = locktype; } @@ -3346,6 +3345,14 @@ const char *sqlite3pager_journalname(Pager *pPager){ return pPager->zJournal; } +/* +** Return true if fsync() calls are disabled for this pager. Return FALSE +** if fsync()s are executed normally. +*/ +int sqlite3pager_nosync(Pager *pPager){ + return pPager->noSync; +} + /* ** Set the codec for this pager */ diff --git a/ext/pdo_sqlite/sqlite/src/pager.h b/ext/pdo_sqlite/sqlite/src/pager.h index 63baf0dfd1..c3311c824b 100644 --- a/ext/pdo_sqlite/sqlite/src/pager.h +++ b/ext/pdo_sqlite/sqlite/src/pager.h @@ -100,6 +100,7 @@ void sqlite3pager_set_safety_level(Pager*,int); const char *sqlite3pager_filename(Pager*); const char *sqlite3pager_dirname(Pager*); const char *sqlite3pager_journalname(Pager*); +int sqlite3pager_nosync(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); diff --git a/ext/pdo_sqlite/sqlite/src/parse.c b/ext/pdo_sqlite/sqlite/src/parse.c index e3cd4429fb..11acdde36c 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. -** The author disclaims copyright to this source code. +** 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/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 51 "parse.y" #include "sqliteInt.h" #include "parse.h" @@ -43,7 +43,7 @@ struct TrigEvent { int a; IdList * b; }; */ struct AttachKey { int type; Token key; }; -#line 48 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 48 "parse.c" /* Next is all token values, in a form suitable for use by makeheaders. ** This section will be null unless lemon is run with the -m switch. */ @@ -93,35 +93,35 @@ struct AttachKey { int type; Token key; }; ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 241 +#define YYNOCODE 244 #define YYACTIONTYPE unsigned short int #define sqlite3ParserTOKENTYPE Token typedef union { sqlite3ParserTOKENTYPE yy0; - Expr* yy2; - struct {int value; int mask;} yy47; - SrcList* yy67; - ExprList* yy82; - struct AttachKey yy132; - struct TrigEvent yy210; - IdList* yy240; - struct LimitVal yy244; - Token yy258; - TriggerStep* yy347; - int yy412; - struct LikeOp yy438; - Select* yy459; - int yy481; + struct {int value; int mask;} yy35; + Expr* yy44; + int yy58; + Select* yy99; + struct LimitVal yy112; + Token yy144; + TriggerStep* yy203; + struct TrigEvent yy234; + IdList* yy258; + struct AttachKey yy300; + SrcList* yy367; + ExprList* yy412; + struct LikeOp yy432; + int yy487; } 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 565 -#define YYNRULE 305 -#define YYERRORSYMBOL 141 -#define YYERRSYMDT yy481 +#define YYNSTATE 578 +#define YYNRULE 310 +#define YYERRORSYMBOL 143 +#define YYERRSYMDT yy487 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -175,467 +175,486 @@ typedef union { ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 259, 65, 257, 112, 114, 110, 116, 66, 122, 124, - /* 10 */ 126, 128, 130, 132, 134, 136, 138, 140, 568, 142, - /* 20 */ 150, 122, 124, 126, 128, 130, 132, 134, 136, 138, - /* 30 */ 140, 130, 132, 134, 136, 138, 140, 108, 94, 143, - /* 40 */ 153, 158, 163, 152, 157, 118, 120, 112, 114, 110, - /* 50 */ 116, 72, 122, 124, 126, 128, 130, 132, 134, 136, - /* 60 */ 138, 140, 7, 106, 219, 258, 122, 124, 126, 128, - /* 70 */ 130, 132, 134, 136, 138, 140, 367, 13, 9, 369, - /* 80 */ 376, 381, 142, 871, 1, 564, 92, 27, 4, 399, - /* 90 */ 363, 384, 844, 341, 291, 28, 10, 95, 398, 33, - /* 100 */ 108, 94, 143, 153, 158, 163, 152, 157, 118, 120, - /* 110 */ 112, 114, 110, 116, 96, 122, 124, 126, 128, 130, - /* 120 */ 132, 134, 136, 138, 140, 456, 565, 142, 395, 305, - /* 130 */ 101, 102, 103, 288, 75, 394, 3, 563, 231, 275, - /* 140 */ 14, 15, 575, 597, 437, 108, 94, 143, 153, 158, - /* 150 */ 163, 152, 157, 118, 120, 112, 114, 110, 116, 13, - /* 160 */ 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, - /* 170 */ 573, 77, 142, 223, 232, 13, 490, 462, 452, 167, - /* 180 */ 306, 169, 170, 276, 254, 3, 563, 81, 277, 183, - /* 190 */ 108, 94, 143, 153, 158, 163, 152, 157, 118, 120, - /* 200 */ 112, 114, 110, 116, 52, 122, 124, 126, 128, 130, - /* 210 */ 132, 134, 136, 138, 140, 48, 54, 799, 448, 51, - /* 220 */ 797, 77, 14, 15, 49, 363, 134, 136, 138, 140, - /* 230 */ 16, 17, 18, 32, 33, 50, 308, 197, 14, 15, - /* 240 */ 367, 261, 13, 369, 376, 381, 142, 37, 337, 40, - /* 250 */ 59, 67, 69, 301, 332, 384, 364, 397, 259, 807, - /* 260 */ 257, 334, 51, 193, 108, 94, 143, 153, 158, 163, - /* 270 */ 152, 157, 118, 120, 112, 114, 110, 116, 262, 122, - /* 280 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 13, - /* 290 */ 171, 142, 40, 59, 67, 69, 301, 332, 642, 148, - /* 300 */ 365, 159, 164, 261, 334, 14, 15, 44, 45, 108, - /* 310 */ 94, 143, 153, 158, 163, 152, 157, 118, 120, 112, - /* 320 */ 114, 110, 116, 258, 122, 124, 126, 128, 130, 132, - /* 330 */ 134, 136, 138, 140, 148, 218, 159, 164, 184, 12, - /* 340 */ 284, 417, 48, 360, 358, 293, 290, 347, 352, 353, - /* 350 */ 289, 49, 14, 15, 688, 2, 96, 148, 4, 159, - /* 360 */ 164, 257, 50, 530, 46, 142, 367, 155, 165, 369, - /* 370 */ 376, 381, 13, 576, 47, 167, 75, 169, 170, 554, - /* 380 */ 172, 384, 207, 108, 94, 143, 153, 158, 163, 152, - /* 390 */ 157, 118, 120, 112, 114, 110, 116, 154, 122, 124, - /* 400 */ 126, 128, 130, 132, 134, 136, 138, 140, 299, 354, - /* 410 */ 350, 352, 353, 96, 96, 13, 34, 20, 294, 362, - /* 420 */ 345, 144, 581, 167, 258, 169, 170, 821, 142, 558, - /* 430 */ 213, 244, 254, 75, 75, 14, 15, 172, 186, 167, - /* 440 */ 533, 169, 170, 146, 147, 417, 108, 94, 143, 153, - /* 450 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, - /* 460 */ 96, 122, 124, 126, 128, 130, 132, 134, 136, 138, - /* 470 */ 140, 145, 354, 142, 22, 239, 383, 589, 14, 15, - /* 480 */ 75, 36, 336, 419, 172, 187, 842, 213, 528, 582, - /* 490 */ 331, 108, 94, 143, 153, 158, 163, 152, 157, 118, - /* 500 */ 120, 112, 114, 110, 116, 249, 122, 124, 126, 128, - /* 510 */ 130, 132, 134, 136, 138, 140, 306, 661, 142, 327, - /* 520 */ 574, 849, 148, 11, 159, 164, 309, 316, 318, 168, - /* 530 */ 42, 327, 666, 327, 212, 393, 108, 94, 143, 153, - /* 540 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, - /* 550 */ 96, 122, 124, 126, 128, 130, 132, 134, 136, 138, - /* 560 */ 140, 847, 83, 142, 321, 641, 372, 31, 663, 282, - /* 570 */ 75, 242, 308, 689, 231, 246, 167, 334, 169, 170, - /* 580 */ 269, 108, 94, 143, 153, 158, 163, 152, 157, 118, - /* 590 */ 120, 112, 114, 110, 116, 324, 122, 124, 126, 128, - /* 600 */ 130, 132, 134, 136, 138, 140, 246, 328, 142, 328, - /* 610 */ 225, 434, 24, 39, 433, 210, 167, 211, 169, 170, - /* 620 */ 167, 331, 169, 170, 583, 435, 108, 161, 143, 153, - /* 630 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, - /* 640 */ 248, 122, 124, 126, 128, 130, 132, 134, 136, 138, - /* 650 */ 140, 57, 58, 142, 624, 837, 323, 727, 271, 261, - /* 660 */ 167, 243, 169, 170, 313, 312, 247, 167, 798, 169, - /* 670 */ 170, 248, 94, 143, 153, 158, 163, 152, 157, 118, - /* 680 */ 120, 112, 114, 110, 116, 96, 122, 124, 126, 128, - /* 690 */ 130, 132, 134, 136, 138, 140, 279, 247, 142, 360, - /* 700 */ 358, 6, 5, 363, 346, 75, 274, 25, 257, 489, - /* 710 */ 13, 561, 33, 503, 13, 268, 267, 269, 143, 153, - /* 720 */ 158, 163, 152, 157, 118, 120, 112, 114, 110, 116, - /* 730 */ 64, 122, 124, 126, 128, 130, 132, 134, 136, 138, - /* 740 */ 140, 26, 76, 96, 400, 77, 71, 584, 96, 451, - /* 750 */ 166, 485, 29, 76, 402, 78, 167, 71, 169, 170, - /* 760 */ 295, 451, 211, 75, 30, 257, 314, 172, 75, 195, - /* 770 */ 514, 258, 292, 14, 15, 690, 77, 14, 15, 106, - /* 780 */ 195, 77, 77, 173, 191, 315, 203, 77, 344, 215, - /* 790 */ 106, 690, 327, 77, 173, 495, 338, 588, 529, 403, - /* 800 */ 179, 177, 296, 453, 251, 209, 475, 327, 175, 73, - /* 810 */ 74, 179, 177, 95, 531, 532, 35, 213, 475, 175, - /* 820 */ 73, 74, 457, 38, 95, 378, 438, 459, 258, 501, - /* 830 */ 449, 497, 841, 411, 461, 406, 653, 76, 311, 459, - /* 840 */ 387, 71, 322, 81, 323, 42, 101, 102, 103, 104, - /* 850 */ 105, 181, 185, 96, 356, 357, 96, 101, 102, 103, - /* 860 */ 104, 105, 181, 185, 195, 76, 655, 544, 328, 71, - /* 870 */ 96, 271, 431, 75, 106, 354, 75, 489, 173, 327, - /* 880 */ 298, 215, 410, 328, 428, 430, 429, 426, 427, 96, - /* 890 */ 75, 721, 195, 76, 91, 179, 177, 71, 348, 379, - /* 900 */ 349, 323, 106, 175, 73, 74, 173, 467, 95, 75, - /* 910 */ 271, 499, 445, 93, 77, 388, 446, 323, 323, 521, - /* 920 */ 195, 454, 45, 179, 177, 285, 836, 42, 41, 432, - /* 930 */ 106, 175, 73, 74, 173, 480, 95, 269, 488, 43, - /* 940 */ 486, 101, 102, 103, 104, 105, 181, 185, 800, 721, - /* 950 */ 417, 179, 177, 229, 422, 328, 96, 96, 96, 175, - /* 960 */ 73, 74, 814, 96, 95, 522, 53, 486, 479, 101, - /* 970 */ 102, 103, 104, 105, 181, 185, 75, 75, 75, 13, - /* 980 */ 107, 109, 423, 75, 55, 8, 106, 111, 496, 857, - /* 990 */ 19, 21, 23, 401, 96, 472, 56, 101, 102, 103, - /* 1000 */ 104, 105, 181, 185, 536, 240, 81, 339, 342, 863, - /* 1010 */ 546, 61, 96, 96, 75, 96, 341, 482, 113, 483, - /* 1020 */ 95, 96, 525, 417, 456, 542, 13, 96, 96, 523, - /* 1030 */ 417, 549, 75, 75, 552, 75, 115, 117, 472, 119, - /* 1040 */ 96, 75, 14, 15, 81, 121, 96, 75, 75, 77, - /* 1050 */ 417, 123, 125, 101, 102, 103, 60, 519, 466, 96, - /* 1060 */ 75, 498, 417, 240, 127, 417, 75, 64, 500, 62, - /* 1070 */ 129, 96, 63, 690, 96, 504, 508, 452, 68, 75, - /* 1080 */ 417, 494, 96, 131, 96, 96, 81, 96, 502, 14, - /* 1090 */ 15, 75, 96, 96, 75, 133, 555, 70, 135, 96, - /* 1100 */ 506, 512, 75, 510, 75, 75, 137, 75, 139, 141, - /* 1110 */ 96, 149, 75, 75, 81, 96, 151, 160, 516, 75, - /* 1120 */ 96, 96, 96, 162, 598, 80, 599, 96, 96, 82, - /* 1130 */ 75, 240, 221, 84, 174, 75, 96, 96, 96, 176, - /* 1140 */ 75, 75, 75, 96, 178, 180, 192, 75, 75, 518, - /* 1150 */ 96, 194, 204, 96, 79, 286, 75, 75, 75, 237, - /* 1160 */ 206, 208, 220, 75, 96, 96, 96, 236, 85, 235, - /* 1170 */ 75, 96, 87, 75, 241, 75, 867, 273, 215, 283, - /* 1180 */ 86, 77, 90, 97, 75, 75, 75, 88, 382, 470, - /* 1190 */ 474, 75, 89, 98, 99, 487, 100, 140, 156, 214, - /* 1200 */ 667, 668, 669, 182, 205, 188, 190, 189, 196, 199, - /* 1210 */ 198, 201, 215, 200, 202, 216, 217, 224, 222, 228, - /* 1220 */ 227, 229, 230, 226, 234, 238, 211, 245, 233, 253, - /* 1230 */ 250, 252, 255, 272, 260, 263, 265, 256, 264, 266, - /* 1240 */ 270, 278, 287, 280, 297, 281, 300, 320, 303, 302, - /* 1250 */ 305, 307, 304, 325, 333, 329, 310, 317, 326, 351, - /* 1260 */ 355, 370, 359, 330, 319, 340, 343, 368, 371, 361, - /* 1270 */ 374, 377, 385, 335, 375, 373, 396, 386, 380, 389, - /* 1280 */ 390, 54, 366, 391, 404, 392, 407, 405, 409, 408, - /* 1290 */ 412, 413, 418, 416, 829, 414, 424, 425, 415, 834, - /* 1300 */ 420, 439, 835, 421, 436, 440, 441, 442, 443, 444, - /* 1310 */ 447, 805, 450, 806, 455, 458, 828, 460, 728, 464, - /* 1320 */ 729, 843, 453, 465, 468, 471, 463, 845, 476, 469, - /* 1330 */ 481, 478, 473, 477, 484, 846, 493, 491, 848, 492, - /* 1340 */ 660, 662, 813, 855, 505, 507, 720, 509, 511, 723, - /* 1350 */ 513, 726, 515, 815, 524, 526, 527, 520, 517, 816, - /* 1360 */ 817, 818, 819, 534, 535, 820, 856, 539, 858, 540, - /* 1370 */ 545, 538, 543, 859, 862, 548, 551, 864, 553, 550, - /* 1380 */ 537, 557, 541, 547, 865, 556, 866, 560, 559, 547, - /* 1390 */ 562, + /* 0 */ 283, 581, 110, 137, 139, 135, 141, 268, 147, 149, + /* 10 */ 151, 153, 155, 157, 159, 161, 163, 165, 114, 119, + /* 20 */ 120, 167, 175, 147, 149, 151, 153, 155, 157, 159, + /* 30 */ 161, 163, 165, 155, 157, 159, 161, 163, 165, 132, + /* 40 */ 94, 168, 178, 183, 188, 177, 182, 143, 145, 137, + /* 50 */ 139, 135, 141, 72, 147, 149, 151, 153, 155, 157, + /* 60 */ 159, 161, 163, 165, 44, 45, 245, 111, 147, 149, + /* 70 */ 151, 153, 155, 157, 159, 161, 163, 165, 13, 427, + /* 80 */ 121, 578, 657, 639, 375, 347, 167, 39, 6, 5, + /* 90 */ 92, 3, 576, 363, 25, 355, 299, 255, 34, 269, + /* 100 */ 513, 129, 372, 112, 132, 94, 168, 178, 183, 188, + /* 110 */ 177, 182, 143, 145, 137, 139, 135, 141, 567, 147, + /* 120 */ 149, 151, 153, 155, 157, 159, 161, 163, 165, 77, + /* 130 */ 109, 373, 133, 77, 117, 119, 120, 7, 13, 32, + /* 140 */ 33, 300, 280, 14, 15, 377, 301, 610, 379, 386, + /* 150 */ 391, 167, 377, 366, 369, 379, 386, 391, 524, 330, + /* 160 */ 394, 64, 368, 374, 407, 705, 95, 394, 571, 132, + /* 170 */ 94, 168, 178, 183, 188, 177, 182, 143, 145, 137, + /* 180 */ 139, 135, 141, 9, 147, 149, 151, 153, 155, 157, + /* 190 */ 159, 161, 163, 165, 127, 125, 121, 373, 167, 101, + /* 200 */ 102, 103, 28, 14, 15, 408, 33, 860, 889, 1, + /* 210 */ 577, 3, 576, 4, 540, 332, 132, 94, 168, 178, + /* 220 */ 183, 188, 177, 182, 143, 145, 137, 139, 135, 141, + /* 230 */ 295, 147, 149, 151, 153, 155, 157, 159, 161, 163, + /* 240 */ 165, 2, 466, 377, 4, 167, 379, 386, 391, 16, + /* 250 */ 17, 18, 285, 159, 161, 163, 165, 240, 394, 173, + /* 260 */ 243, 184, 189, 132, 94, 168, 178, 183, 188, 177, + /* 270 */ 182, 143, 145, 137, 139, 135, 141, 96, 147, 149, + /* 280 */ 151, 153, 155, 157, 159, 161, 163, 165, 815, 291, + /* 290 */ 308, 813, 51, 500, 472, 462, 588, 539, 75, 322, + /* 300 */ 27, 133, 409, 704, 81, 272, 10, 173, 96, 184, + /* 310 */ 189, 96, 190, 13, 541, 542, 13, 393, 78, 167, + /* 320 */ 37, 361, 40, 59, 67, 69, 325, 356, 586, 75, + /* 330 */ 197, 368, 75, 316, 358, 95, 218, 132, 94, 168, + /* 340 */ 178, 183, 188, 177, 182, 143, 145, 137, 139, 135, + /* 350 */ 141, 77, 147, 149, 151, 153, 155, 157, 159, 161, + /* 360 */ 163, 165, 173, 113, 184, 189, 167, 110, 101, 102, + /* 370 */ 103, 318, 274, 405, 329, 121, 12, 461, 14, 15, + /* 380 */ 404, 14, 15, 238, 132, 94, 168, 178, 183, 188, + /* 390 */ 177, 182, 143, 145, 137, 139, 135, 141, 273, 147, + /* 400 */ 149, 151, 153, 155, 157, 159, 161, 163, 165, 96, + /* 410 */ 77, 51, 315, 427, 48, 36, 360, 196, 317, 129, + /* 420 */ 130, 112, 314, 49, 355, 209, 313, 13, 96, 110, + /* 430 */ 75, 197, 111, 96, 814, 485, 50, 589, 46, 461, + /* 440 */ 167, 40, 59, 67, 69, 325, 356, 482, 47, 75, + /* 450 */ 257, 467, 429, 358, 75, 197, 469, 232, 132, 94, + /* 460 */ 168, 178, 183, 188, 177, 182, 143, 145, 137, 139, + /* 470 */ 135, 141, 77, 147, 149, 151, 153, 155, 157, 159, + /* 480 */ 161, 163, 165, 323, 237, 13, 830, 169, 249, 258, + /* 490 */ 13, 703, 14, 15, 111, 96, 265, 485, 96, 192, + /* 500 */ 96, 194, 195, 13, 192, 167, 194, 195, 238, 171, + /* 510 */ 172, 476, 192, 471, 194, 195, 75, 211, 469, 75, + /* 520 */ 257, 75, 91, 132, 94, 168, 178, 183, 188, 177, + /* 530 */ 182, 143, 145, 137, 139, 135, 141, 170, 147, 149, + /* 540 */ 151, 153, 155, 157, 159, 161, 163, 165, 365, 48, + /* 550 */ 14, 15, 216, 65, 228, 14, 15, 298, 49, 251, + /* 560 */ 66, 13, 602, 13, 330, 96, 676, 212, 14, 15, + /* 570 */ 167, 50, 865, 222, 57, 58, 678, 275, 192, 20, + /* 580 */ 194, 195, 277, 403, 26, 351, 75, 499, 132, 94, + /* 590 */ 168, 178, 183, 188, 177, 182, 143, 145, 137, 139, + /* 600 */ 135, 141, 96, 147, 149, 151, 153, 155, 157, 159, + /* 610 */ 161, 163, 165, 587, 863, 83, 11, 167, 742, 345, + /* 620 */ 332, 312, 306, 75, 93, 358, 14, 15, 14, 15, + /* 630 */ 858, 173, 495, 184, 189, 132, 94, 168, 178, 183, + /* 640 */ 188, 177, 182, 143, 145, 137, 139, 135, 141, 594, + /* 650 */ 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, + /* 660 */ 22, 272, 352, 192, 167, 194, 195, 192, 295, 194, + /* 670 */ 195, 285, 505, 192, 42, 194, 195, 192, 351, 194, + /* 680 */ 195, 595, 132, 94, 168, 178, 183, 188, 177, 182, + /* 690 */ 143, 145, 137, 139, 135, 141, 338, 147, 149, 151, + /* 700 */ 153, 155, 157, 159, 161, 163, 165, 837, 511, 286, + /* 710 */ 507, 167, 382, 127, 125, 192, 339, 194, 195, 192, + /* 720 */ 543, 194, 195, 333, 340, 342, 351, 442, 274, 132, + /* 730 */ 94, 168, 178, 183, 188, 177, 182, 143, 145, 137, + /* 740 */ 139, 135, 141, 96, 147, 149, 151, 153, 155, 157, + /* 750 */ 159, 161, 163, 165, 273, 352, 110, 371, 167, 373, + /* 760 */ 388, 438, 440, 439, 75, 499, 362, 574, 33, 335, + /* 770 */ 538, 668, 656, 351, 31, 413, 132, 186, 168, 178, + /* 780 */ 183, 188, 177, 182, 143, 145, 137, 139, 135, 141, + /* 790 */ 509, 147, 149, 151, 153, 155, 157, 159, 161, 163, + /* 800 */ 165, 96, 736, 352, 283, 167, 110, 397, 123, 124, + /* 810 */ 531, 421, 193, 416, 115, 681, 116, 235, 477, 236, + /* 820 */ 351, 111, 75, 244, 94, 168, 178, 183, 188, 177, + /* 830 */ 182, 143, 145, 137, 139, 135, 141, 96, 147, 149, + /* 840 */ 151, 153, 155, 157, 159, 161, 163, 165, 96, 879, + /* 850 */ 352, 881, 167, 292, 455, 293, 270, 280, 75, 108, + /* 860 */ 554, 319, 857, 236, 42, 447, 13, 351, 13, 75, + /* 870 */ 134, 111, 168, 178, 183, 188, 177, 182, 143, 145, + /* 880 */ 137, 139, 135, 141, 96, 147, 149, 151, 153, 155, + /* 890 */ 157, 159, 161, 163, 165, 96, 76, 352, 444, 96, + /* 900 */ 71, 96, 443, 52, 208, 75, 136, 76, 106, 24, + /* 910 */ 412, 71, 180, 596, 445, 54, 75, 138, 266, 106, + /* 920 */ 75, 140, 75, 142, 441, 220, 96, 337, 336, 29, + /* 930 */ 96, 14, 15, 14, 15, 133, 220, 77, 96, 198, + /* 940 */ 96, 458, 179, 346, 348, 347, 133, 75, 433, 96, + /* 950 */ 198, 75, 144, 389, 285, 347, 204, 202, 320, 75, + /* 960 */ 146, 75, 148, 410, 200, 73, 74, 204, 202, 95, + /* 970 */ 75, 150, 398, 96, 347, 200, 73, 74, 852, 96, + /* 980 */ 95, 76, 823, 448, 597, 71, 432, 459, 293, 420, + /* 990 */ 96, 705, 303, 106, 75, 480, 77, 436, 437, 81, + /* 1000 */ 75, 152, 101, 102, 103, 104, 105, 206, 210, 705, + /* 1010 */ 220, 75, 154, 101, 102, 103, 104, 105, 206, 210, + /* 1020 */ 133, 30, 77, 240, 198, 456, 96, 347, 35, 464, + /* 1030 */ 45, 490, 463, 293, 96, 873, 498, 96, 496, 96, + /* 1040 */ 76, 204, 202, 736, 71, 96, 601, 75, 156, 200, + /* 1050 */ 73, 74, 106, 96, 95, 75, 158, 295, 75, 160, + /* 1060 */ 75, 162, 38, 492, 96, 853, 75, 164, 76, 220, + /* 1070 */ 41, 191, 71, 552, 75, 166, 482, 43, 427, 133, + /* 1080 */ 106, 528, 568, 198, 96, 75, 197, 101, 102, 103, + /* 1090 */ 104, 105, 206, 210, 816, 670, 77, 220, 240, 81, + /* 1100 */ 204, 202, 309, 96, 77, 75, 174, 133, 200, 73, + /* 1110 */ 74, 198, 493, 95, 77, 8, 489, 506, 427, 427, + /* 1120 */ 19, 21, 23, 411, 75, 176, 42, 234, 204, 202, + /* 1130 */ 427, 81, 427, 562, 427, 546, 200, 73, 74, 238, + /* 1140 */ 522, 95, 556, 96, 529, 427, 101, 102, 103, 104, + /* 1150 */ 105, 206, 210, 532, 535, 496, 466, 508, 510, 266, + /* 1160 */ 96, 533, 885, 559, 75, 185, 565, 96, 56, 512, + /* 1170 */ 96, 516, 96, 520, 101, 102, 103, 104, 105, 206, + /* 1180 */ 210, 75, 187, 55, 526, 53, 60, 61, 75, 199, + /* 1190 */ 96, 75, 201, 75, 203, 96, 64, 62, 96, 70, + /* 1200 */ 96, 63, 96, 68, 96, 611, 96, 514, 518, 462, + /* 1210 */ 84, 75, 205, 504, 96, 612, 75, 217, 81, 75, + /* 1220 */ 219, 75, 229, 75, 231, 75, 233, 75, 246, 81, + /* 1230 */ 79, 80, 96, 266, 82, 75, 262, 96, 263, 310, + /* 1240 */ 86, 96, 261, 96, 85, 96, 247, 96, 87, 97, + /* 1250 */ 99, 88, 90, 75, 267, 107, 89, 98, 75, 297, + /* 1260 */ 75, 307, 75, 364, 75, 392, 75, 484, 75, 497, + /* 1270 */ 118, 100, 131, 128, 165, 122, 181, 682, 239, 683, + /* 1280 */ 684, 207, 230, 213, 126, 214, 215, 221, 225, 224, + /* 1290 */ 223, 226, 240, 227, 241, 248, 242, 250, 254, 253, + /* 1300 */ 252, 255, 236, 264, 259, 256, 260, 271, 276, 278, + /* 1310 */ 279, 281, 284, 296, 282, 289, 287, 290, 288, 294, + /* 1320 */ 302, 305, 311, 304, 321, 324, 326, 344, 328, 327, + /* 1330 */ 331, 349, 357, 329, 353, 334, 341, 343, 380, 350, + /* 1340 */ 378, 381, 354, 367, 359, 370, 384, 387, 396, 395, + /* 1350 */ 399, 400, 385, 54, 406, 414, 376, 401, 390, 383, + /* 1360 */ 415, 417, 418, 402, 419, 422, 425, 423, 424, 434, + /* 1370 */ 426, 428, 430, 845, 431, 435, 850, 446, 851, 449, + /* 1380 */ 450, 451, 452, 453, 821, 454, 822, 457, 460, 465, + /* 1390 */ 743, 468, 744, 844, 470, 859, 463, 481, 475, 479, + /* 1400 */ 861, 474, 473, 478, 483, 486, 487, 491, 488, 494, + /* 1410 */ 862, 501, 502, 503, 864, 675, 677, 829, 871, 517, + /* 1420 */ 515, 735, 519, 521, 523, 738, 525, 741, 831, 534, + /* 1430 */ 832, 833, 530, 536, 834, 527, 537, 835, 544, 836, + /* 1440 */ 545, 547, 872, 874, 549, 875, 557, 555, 548, 550, + /* 1450 */ 553, 878, 880, 882, 561, 558, 883, 560, 551, 563, + /* 1460 */ 566, 569, 564, 570, 572, 573, 884, 555, 555, 555, + /* 1470 */ 555, 575, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 25, 30, 27, 72, 73, 74, 75, 36, 77, 78, - /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 10, 44, - /* 20 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - /* 30 */ 86, 81, 82, 83, 84, 85, 86, 62, 63, 64, + /* 0 */ 25, 10, 27, 74, 75, 76, 77, 26, 79, 80, + /* 10 */ 81, 82, 83, 84, 85, 86, 87, 88, 168, 169, + /* 20 */ 170, 46, 78, 79, 80, 81, 82, 83, 84, 85, + /* 30 */ 86, 87, 88, 83, 84, 85, 86, 87, 88, 64, /* 40 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - /* 50 */ 75, 23, 77, 78, 79, 80, 81, 82, 83, 84, - /* 60 */ 85, 86, 10, 60, 26, 90, 77, 78, 79, 80, - /* 70 */ 81, 82, 83, 84, 85, 86, 92, 27, 148, 95, - /* 80 */ 96, 97, 44, 142, 143, 144, 48, 23, 147, 25, - /* 90 */ 150, 107, 18, 90, 24, 155, 149, 94, 158, 159, - /* 100 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 110 */ 72, 73, 74, 75, 150, 77, 78, 79, 80, 81, - /* 120 */ 82, 83, 84, 85, 86, 51, 0, 44, 177, 178, - /* 130 */ 127, 128, 129, 83, 170, 184, 10, 11, 174, 157, - /* 140 */ 90, 91, 10, 115, 22, 62, 63, 64, 65, 66, - /* 150 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 27, - /* 160 */ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - /* 170 */ 10, 189, 44, 209, 210, 27, 102, 103, 104, 109, - /* 180 */ 45, 111, 112, 201, 202, 10, 11, 113, 206, 157, - /* 190 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 200 */ 72, 73, 74, 75, 94, 77, 78, 79, 80, 81, - /* 210 */ 82, 83, 84, 85, 86, 19, 106, 134, 96, 64, - /* 220 */ 18, 189, 90, 91, 28, 150, 83, 84, 85, 86, - /* 230 */ 14, 15, 16, 158, 159, 39, 101, 41, 90, 91, - /* 240 */ 92, 163, 27, 95, 96, 97, 44, 92, 93, 94, - /* 250 */ 95, 96, 97, 98, 99, 107, 181, 182, 25, 137, - /* 260 */ 27, 106, 64, 135, 62, 63, 64, 65, 66, 67, - /* 270 */ 68, 69, 70, 71, 72, 73, 74, 75, 200, 77, - /* 280 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 27, - /* 290 */ 24, 44, 94, 95, 96, 97, 98, 99, 24, 217, - /* 300 */ 26, 219, 220, 163, 106, 90, 91, 186, 187, 62, - /* 310 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - /* 320 */ 73, 74, 75, 90, 77, 78, 79, 80, 81, 82, - /* 330 */ 83, 84, 85, 86, 217, 218, 219, 220, 24, 150, - /* 340 */ 200, 150, 19, 81, 82, 24, 110, 165, 166, 167, - /* 350 */ 114, 28, 90, 91, 24, 144, 150, 217, 147, 219, - /* 360 */ 220, 27, 39, 101, 41, 44, 92, 64, 23, 95, - /* 370 */ 96, 97, 27, 10, 51, 109, 170, 111, 112, 188, - /* 380 */ 174, 107, 135, 62, 63, 64, 65, 66, 67, 68, - /* 390 */ 69, 70, 71, 72, 73, 74, 75, 94, 77, 78, - /* 400 */ 79, 80, 81, 82, 83, 84, 85, 86, 24, 227, - /* 410 */ 165, 166, 167, 150, 150, 27, 160, 149, 212, 163, - /* 420 */ 164, 44, 10, 109, 90, 111, 112, 10, 44, 238, - /* 430 */ 224, 201, 202, 170, 170, 90, 91, 174, 174, 109, - /* 440 */ 23, 111, 112, 66, 67, 150, 62, 63, 64, 65, - /* 450 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 460 */ 150, 77, 78, 79, 80, 81, 82, 83, 84, 85, - /* 470 */ 86, 94, 227, 44, 149, 212, 171, 10, 90, 91, - /* 480 */ 170, 168, 169, 188, 174, 221, 12, 224, 71, 10, - /* 490 */ 177, 62, 63, 64, 65, 66, 67, 68, 69, 70, - /* 500 */ 71, 72, 73, 74, 75, 117, 77, 78, 79, 80, - /* 510 */ 81, 82, 83, 84, 85, 86, 45, 10, 44, 150, - /* 520 */ 10, 10, 217, 13, 219, 220, 102, 103, 104, 110, - /* 530 */ 101, 150, 113, 150, 224, 64, 62, 63, 64, 65, - /* 540 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 550 */ 150, 77, 78, 79, 80, 81, 82, 83, 84, 85, - /* 560 */ 86, 10, 192, 44, 183, 24, 183, 26, 10, 199, - /* 570 */ 170, 26, 101, 24, 174, 26, 109, 106, 111, 112, - /* 580 */ 26, 62, 63, 64, 65, 66, 67, 68, 69, 70, - /* 590 */ 71, 72, 73, 74, 75, 226, 77, 78, 79, 80, - /* 600 */ 81, 82, 83, 84, 85, 86, 26, 226, 44, 226, - /* 610 */ 210, 29, 149, 169, 32, 24, 109, 26, 111, 112, - /* 620 */ 109, 177, 111, 112, 10, 43, 62, 63, 64, 65, - /* 630 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 640 */ 91, 77, 78, 79, 80, 81, 82, 83, 84, 85, - /* 650 */ 86, 14, 15, 44, 24, 101, 26, 10, 150, 163, - /* 660 */ 109, 116, 111, 112, 93, 94, 117, 109, 18, 111, - /* 670 */ 112, 91, 63, 64, 65, 66, 67, 68, 69, 70, - /* 680 */ 71, 72, 73, 74, 75, 150, 77, 78, 79, 80, - /* 690 */ 81, 82, 83, 84, 85, 86, 200, 117, 44, 81, - /* 700 */ 82, 145, 146, 150, 23, 170, 23, 151, 27, 174, - /* 710 */ 27, 158, 159, 157, 27, 24, 208, 26, 64, 65, - /* 720 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 730 */ 100, 77, 78, 79, 80, 81, 82, 83, 84, 85, - /* 740 */ 86, 152, 23, 150, 157, 189, 27, 10, 150, 157, - /* 750 */ 157, 216, 156, 23, 153, 157, 109, 27, 111, 112, - /* 760 */ 24, 157, 26, 170, 24, 27, 33, 174, 170, 50, - /* 770 */ 214, 90, 174, 90, 91, 101, 189, 90, 91, 60, - /* 780 */ 50, 189, 189, 64, 134, 52, 136, 189, 162, 115, - /* 790 */ 60, 25, 150, 189, 64, 21, 170, 10, 150, 21, - /* 800 */ 81, 82, 83, 62, 117, 212, 214, 150, 89, 90, - /* 810 */ 91, 81, 82, 94, 166, 167, 161, 224, 214, 89, - /* 820 */ 90, 91, 230, 150, 94, 183, 225, 235, 90, 55, - /* 830 */ 229, 57, 12, 55, 230, 57, 10, 23, 105, 235, - /* 840 */ 183, 27, 24, 113, 26, 101, 127, 128, 129, 130, - /* 850 */ 131, 132, 133, 150, 127, 128, 150, 127, 128, 129, - /* 860 */ 130, 131, 132, 133, 50, 23, 125, 129, 226, 27, - /* 870 */ 150, 150, 47, 170, 60, 227, 170, 174, 64, 150, - /* 880 */ 174, 115, 157, 226, 102, 103, 104, 53, 54, 150, - /* 890 */ 170, 10, 50, 23, 174, 81, 82, 27, 24, 24, - /* 900 */ 26, 26, 60, 89, 90, 91, 64, 26, 94, 170, - /* 910 */ 150, 137, 183, 174, 189, 24, 24, 26, 26, 216, - /* 920 */ 50, 186, 187, 81, 82, 83, 101, 101, 171, 208, - /* 930 */ 60, 89, 90, 91, 64, 24, 94, 26, 24, 34, - /* 940 */ 26, 127, 128, 129, 130, 131, 132, 133, 134, 10, - /* 950 */ 150, 81, 82, 27, 134, 226, 150, 150, 150, 89, - /* 960 */ 90, 91, 10, 150, 94, 24, 171, 26, 208, 127, - /* 970 */ 128, 129, 130, 131, 132, 133, 170, 170, 170, 27, - /* 980 */ 174, 174, 174, 170, 180, 12, 60, 174, 188, 10, - /* 990 */ 17, 18, 19, 20, 150, 150, 42, 127, 128, 129, - /* 1000 */ 130, 131, 132, 133, 31, 124, 113, 81, 82, 10, - /* 1010 */ 37, 172, 150, 150, 170, 150, 90, 157, 174, 126, - /* 1020 */ 94, 150, 49, 150, 51, 46, 27, 150, 150, 56, - /* 1030 */ 150, 58, 170, 170, 61, 170, 174, 174, 150, 174, - /* 1040 */ 150, 170, 90, 91, 113, 174, 150, 170, 170, 189, - /* 1050 */ 150, 174, 174, 127, 128, 129, 46, 126, 213, 150, - /* 1060 */ 170, 188, 150, 124, 174, 150, 170, 100, 188, 171, - /* 1070 */ 174, 150, 173, 10, 150, 102, 103, 104, 171, 170, - /* 1080 */ 150, 108, 150, 174, 150, 150, 113, 150, 188, 90, - /* 1090 */ 91, 170, 150, 150, 170, 174, 59, 23, 174, 150, - /* 1100 */ 188, 213, 170, 188, 170, 170, 174, 170, 174, 174, - /* 1110 */ 150, 174, 170, 170, 113, 150, 174, 174, 188, 170, - /* 1120 */ 150, 150, 150, 174, 115, 189, 115, 150, 150, 191, - /* 1130 */ 170, 124, 119, 193, 174, 170, 150, 150, 150, 174, - /* 1140 */ 170, 170, 170, 150, 174, 174, 174, 170, 170, 157, - /* 1150 */ 150, 174, 174, 150, 190, 150, 170, 170, 170, 121, - /* 1160 */ 174, 174, 174, 170, 150, 150, 150, 174, 194, 122, - /* 1170 */ 170, 150, 196, 170, 174, 170, 139, 174, 115, 174, - /* 1180 */ 195, 189, 123, 115, 170, 170, 170, 197, 174, 174, - /* 1190 */ 174, 170, 198, 150, 115, 174, 150, 86, 94, 150, - /* 1200 */ 113, 113, 113, 23, 134, 222, 18, 223, 23, 187, - /* 1210 */ 24, 150, 115, 26, 24, 150, 154, 26, 120, 99, - /* 1220 */ 172, 27, 162, 211, 172, 120, 26, 203, 211, 117, - /* 1230 */ 150, 150, 150, 101, 150, 204, 118, 154, 205, 23, - /* 1240 */ 150, 24, 115, 204, 24, 205, 171, 23, 175, 150, - /* 1250 */ 178, 150, 176, 211, 162, 211, 179, 179, 172, 24, - /* 1260 */ 228, 46, 228, 172, 179, 170, 170, 150, 23, 163, - /* 1270 */ 24, 23, 46, 180, 171, 173, 182, 23, 171, 98, - /* 1280 */ 150, 106, 182, 175, 150, 176, 150, 154, 25, 154, - /* 1290 */ 150, 154, 154, 101, 12, 231, 40, 38, 232, 101, - /* 1300 */ 233, 137, 101, 234, 47, 150, 154, 101, 150, 23, - /* 1310 */ 171, 10, 12, 137, 185, 18, 10, 10, 125, 150, - /* 1320 */ 125, 18, 62, 105, 150, 194, 185, 10, 125, 71, - /* 1330 */ 215, 23, 71, 150, 23, 10, 194, 116, 10, 150, - /* 1340 */ 10, 10, 10, 10, 116, 194, 10, 185, 105, 10, - /* 1350 */ 194, 10, 125, 10, 150, 150, 154, 23, 215, 10, - /* 1360 */ 10, 10, 10, 150, 24, 10, 10, 25, 10, 150, - /* 1370 */ 35, 163, 163, 10, 10, 150, 154, 10, 21, 150, - /* 1380 */ 236, 150, 237, 236, 10, 138, 10, 239, 139, 240, - /* 1390 */ 140, + /* 50 */ 75, 76, 77, 23, 79, 80, 81, 82, 83, 84, + /* 60 */ 85, 86, 87, 88, 189, 190, 26, 92, 79, 80, + /* 70 */ 81, 82, 83, 84, 85, 86, 87, 88, 27, 152, + /* 80 */ 230, 0, 24, 24, 26, 26, 46, 172, 147, 148, + /* 90 */ 50, 10, 11, 23, 153, 180, 159, 27, 162, 118, + /* 100 */ 159, 165, 166, 167, 64, 65, 66, 67, 68, 69, + /* 110 */ 70, 71, 72, 73, 74, 75, 76, 77, 191, 79, + /* 120 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 192, + /* 130 */ 25, 152, 62, 192, 168, 169, 170, 10, 27, 160, + /* 140 */ 161, 204, 205, 92, 93, 94, 209, 117, 97, 98, + /* 150 */ 99, 46, 94, 83, 84, 97, 98, 99, 217, 47, + /* 160 */ 109, 102, 92, 184, 185, 25, 96, 109, 241, 64, + /* 170 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 180 */ 75, 76, 77, 150, 79, 80, 81, 82, 83, 84, + /* 190 */ 85, 86, 87, 88, 83, 84, 230, 152, 46, 129, + /* 200 */ 130, 131, 157, 92, 93, 160, 161, 18, 144, 145, + /* 210 */ 146, 10, 11, 149, 103, 103, 64, 65, 66, 67, + /* 220 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + /* 230 */ 152, 79, 80, 81, 82, 83, 84, 85, 86, 87, + /* 240 */ 88, 146, 53, 94, 149, 46, 97, 98, 99, 14, + /* 250 */ 15, 16, 165, 85, 86, 87, 88, 117, 109, 220, + /* 260 */ 221, 222, 223, 64, 65, 66, 67, 68, 69, 70, + /* 270 */ 71, 72, 73, 74, 75, 76, 77, 152, 79, 80, + /* 280 */ 81, 82, 83, 84, 85, 86, 87, 88, 136, 211, + /* 290 */ 203, 18, 66, 104, 105, 106, 10, 152, 173, 174, + /* 300 */ 23, 62, 25, 24, 115, 26, 151, 220, 152, 222, + /* 310 */ 223, 152, 23, 27, 169, 170, 27, 175, 159, 46, + /* 320 */ 94, 95, 96, 97, 98, 99, 100, 101, 10, 173, + /* 330 */ 174, 92, 173, 174, 108, 96, 137, 64, 65, 66, + /* 340 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 350 */ 77, 192, 79, 80, 81, 82, 83, 84, 85, 86, + /* 360 */ 87, 88, 220, 23, 222, 223, 46, 27, 129, 130, + /* 370 */ 131, 215, 93, 180, 181, 230, 152, 159, 92, 93, + /* 380 */ 187, 92, 93, 227, 64, 65, 66, 67, 68, 69, + /* 390 */ 70, 71, 72, 73, 74, 75, 76, 77, 119, 79, + /* 400 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 152, + /* 410 */ 192, 66, 24, 152, 19, 171, 172, 24, 24, 165, + /* 420 */ 166, 167, 112, 28, 180, 24, 116, 27, 152, 27, + /* 430 */ 173, 174, 92, 152, 18, 217, 41, 10, 43, 159, + /* 440 */ 46, 96, 97, 98, 99, 100, 101, 152, 53, 173, + /* 450 */ 174, 233, 191, 108, 173, 174, 238, 137, 64, 65, + /* 460 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 470 */ 76, 77, 192, 79, 80, 81, 82, 83, 84, 85, + /* 480 */ 86, 87, 88, 24, 227, 27, 10, 46, 212, 213, + /* 490 */ 27, 24, 92, 93, 92, 152, 215, 217, 152, 111, + /* 500 */ 152, 113, 114, 27, 111, 46, 113, 114, 227, 68, + /* 510 */ 69, 216, 111, 233, 113, 114, 173, 174, 238, 173, + /* 520 */ 174, 173, 174, 64, 65, 66, 67, 68, 69, 70, + /* 530 */ 71, 72, 73, 74, 75, 76, 77, 96, 79, 80, + /* 540 */ 81, 82, 83, 84, 85, 86, 87, 88, 24, 19, + /* 550 */ 92, 93, 136, 31, 138, 92, 93, 23, 28, 213, + /* 560 */ 38, 27, 10, 27, 47, 152, 10, 224, 92, 93, + /* 570 */ 46, 41, 10, 43, 14, 15, 10, 119, 111, 151, + /* 580 */ 113, 114, 119, 66, 154, 152, 173, 174, 64, 65, + /* 590 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 600 */ 76, 77, 152, 79, 80, 81, 82, 83, 84, 85, + /* 610 */ 86, 87, 88, 10, 10, 195, 13, 46, 10, 186, + /* 620 */ 103, 85, 202, 173, 174, 108, 92, 93, 92, 93, + /* 630 */ 12, 220, 219, 222, 223, 64, 65, 66, 67, 68, + /* 640 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 10, + /* 650 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 660 */ 151, 26, 229, 111, 46, 113, 114, 111, 152, 113, + /* 670 */ 114, 165, 21, 111, 103, 113, 114, 111, 152, 113, + /* 680 */ 114, 10, 64, 65, 66, 67, 68, 69, 70, 71, + /* 690 */ 72, 73, 74, 75, 76, 77, 34, 79, 80, 81, + /* 700 */ 82, 83, 84, 85, 86, 87, 88, 10, 57, 203, + /* 710 */ 59, 46, 186, 83, 84, 111, 54, 113, 114, 111, + /* 720 */ 23, 113, 114, 104, 105, 106, 152, 211, 93, 64, + /* 730 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 740 */ 75, 76, 77, 152, 79, 80, 81, 82, 83, 84, + /* 750 */ 85, 86, 87, 88, 119, 229, 27, 164, 46, 152, + /* 760 */ 186, 104, 105, 106, 173, 174, 173, 160, 161, 107, + /* 770 */ 73, 10, 24, 152, 26, 21, 64, 65, 66, 67, + /* 780 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + /* 790 */ 139, 79, 80, 81, 82, 83, 84, 85, 86, 87, + /* 800 */ 88, 152, 10, 229, 25, 46, 27, 186, 129, 130, + /* 810 */ 219, 57, 112, 59, 24, 115, 26, 24, 26, 26, + /* 820 */ 152, 92, 173, 174, 65, 66, 67, 68, 69, 70, + /* 830 */ 71, 72, 73, 74, 75, 76, 77, 152, 79, 80, + /* 840 */ 81, 82, 83, 84, 85, 86, 87, 88, 152, 10, + /* 850 */ 229, 10, 46, 24, 186, 26, 204, 205, 173, 174, + /* 860 */ 131, 24, 12, 26, 103, 22, 27, 152, 27, 173, + /* 870 */ 174, 92, 66, 67, 68, 69, 70, 71, 72, 73, + /* 880 */ 74, 75, 76, 77, 152, 79, 80, 81, 82, 83, + /* 890 */ 84, 85, 86, 87, 88, 152, 23, 229, 29, 152, + /* 900 */ 27, 152, 33, 96, 159, 173, 174, 23, 35, 151, + /* 910 */ 155, 27, 66, 10, 45, 108, 173, 174, 126, 35, + /* 920 */ 173, 174, 173, 174, 49, 52, 152, 95, 96, 158, + /* 930 */ 152, 92, 93, 92, 93, 62, 52, 192, 152, 66, + /* 940 */ 152, 98, 96, 24, 229, 26, 62, 173, 174, 152, + /* 950 */ 66, 173, 174, 24, 165, 26, 83, 84, 85, 173, + /* 960 */ 174, 173, 174, 159, 91, 92, 93, 83, 84, 96, + /* 970 */ 173, 174, 24, 152, 26, 91, 92, 93, 103, 152, + /* 980 */ 96, 23, 139, 228, 10, 27, 136, 232, 26, 159, + /* 990 */ 152, 10, 203, 35, 173, 174, 192, 55, 56, 115, + /* 1000 */ 173, 174, 129, 130, 131, 132, 133, 134, 135, 103, + /* 1010 */ 52, 173, 174, 129, 130, 131, 132, 133, 134, 135, + /* 1020 */ 62, 24, 192, 117, 66, 24, 152, 26, 163, 189, + /* 1030 */ 190, 24, 64, 26, 152, 10, 24, 152, 26, 152, + /* 1040 */ 23, 83, 84, 10, 27, 152, 10, 173, 174, 91, + /* 1050 */ 92, 93, 35, 152, 96, 173, 174, 152, 173, 174, + /* 1060 */ 173, 174, 152, 159, 152, 103, 173, 174, 23, 52, + /* 1070 */ 175, 159, 27, 48, 173, 174, 152, 36, 152, 62, + /* 1080 */ 35, 159, 61, 66, 152, 173, 174, 129, 130, 131, + /* 1090 */ 132, 133, 134, 135, 136, 127, 192, 52, 117, 115, + /* 1100 */ 83, 84, 85, 152, 192, 173, 174, 62, 91, 92, + /* 1110 */ 93, 66, 128, 96, 192, 12, 211, 191, 152, 152, + /* 1120 */ 17, 18, 19, 20, 173, 174, 103, 215, 83, 84, + /* 1130 */ 152, 115, 152, 30, 152, 32, 91, 92, 93, 227, + /* 1140 */ 216, 96, 39, 152, 128, 152, 129, 130, 131, 132, + /* 1150 */ 133, 134, 135, 24, 51, 26, 53, 191, 191, 126, + /* 1160 */ 152, 58, 141, 60, 173, 174, 63, 152, 44, 191, + /* 1170 */ 152, 191, 152, 191, 129, 130, 131, 132, 133, 134, + /* 1180 */ 135, 173, 174, 183, 191, 175, 48, 176, 173, 174, + /* 1190 */ 152, 173, 174, 173, 174, 152, 102, 175, 152, 23, + /* 1200 */ 152, 177, 152, 175, 152, 117, 152, 104, 105, 106, + /* 1210 */ 196, 173, 174, 110, 152, 117, 173, 174, 115, 173, + /* 1220 */ 174, 173, 174, 173, 174, 173, 174, 173, 174, 115, + /* 1230 */ 193, 192, 152, 126, 194, 173, 174, 152, 123, 152, + /* 1240 */ 198, 152, 124, 152, 197, 152, 121, 152, 199, 117, + /* 1250 */ 117, 200, 125, 173, 174, 23, 201, 152, 173, 174, + /* 1260 */ 173, 174, 173, 174, 173, 174, 173, 174, 173, 174, + /* 1270 */ 24, 152, 24, 165, 88, 231, 96, 115, 152, 115, + /* 1280 */ 115, 23, 136, 225, 231, 226, 18, 23, 26, 190, + /* 1290 */ 24, 152, 117, 24, 152, 122, 156, 26, 101, 176, + /* 1300 */ 214, 27, 26, 122, 214, 164, 176, 206, 152, 152, + /* 1310 */ 119, 152, 152, 103, 156, 120, 207, 23, 208, 152, + /* 1320 */ 24, 208, 117, 207, 24, 175, 152, 23, 179, 178, + /* 1330 */ 152, 214, 164, 181, 214, 182, 182, 182, 48, 176, + /* 1340 */ 152, 23, 176, 173, 183, 173, 24, 23, 23, 48, + /* 1350 */ 100, 152, 175, 108, 185, 152, 185, 178, 175, 177, + /* 1360 */ 156, 152, 156, 179, 25, 152, 235, 156, 234, 42, + /* 1370 */ 103, 156, 236, 12, 237, 40, 103, 49, 103, 139, + /* 1380 */ 152, 156, 103, 152, 10, 23, 139, 175, 12, 188, + /* 1390 */ 127, 18, 127, 10, 10, 18, 64, 197, 107, 73, + /* 1400 */ 10, 152, 188, 152, 73, 127, 152, 218, 23, 23, + /* 1410 */ 10, 118, 152, 197, 10, 10, 10, 10, 10, 197, + /* 1420 */ 118, 10, 188, 107, 197, 10, 127, 10, 10, 152, + /* 1430 */ 10, 10, 23, 152, 10, 218, 156, 10, 152, 10, + /* 1440 */ 24, 239, 10, 10, 25, 10, 239, 37, 165, 152, + /* 1450 */ 165, 10, 10, 10, 156, 152, 10, 152, 240, 152, + /* 1460 */ 21, 140, 156, 152, 141, 242, 10, 243, 243, 243, + /* 1470 */ 243, 142, }; -#define YY_SHIFT_USE_DFLT (-70) +#define YY_SHIFT_USE_DFLT (-72) static const short yy_shift_ofst[] = { - /* 0 */ 175, 126, -70, -70, 973, 8, 52, -70, 216, 510, - /* 10 */ 160, 132, 363, -70, -70, -70, -70, -70, -70, 510, - /* 20 */ 412, 510, 479, 510, 614, 64, 737, 215, 541, 740, - /* 30 */ 787, 148, -70, 334, -70, 155, -70, 215, 198, -70, - /* 40 */ 744, -70, 905, 323, -70, -70, -70, -70, -70, -70, - /* 50 */ -70, 110, 744, -70, 954, -70, 637, -70, -70, 1010, - /* 60 */ -29, 744, 967, -70, -70, -70, -70, 744, -70, 1074, - /* 70 */ 870, 28, 719, 1009, 1011, -70, 730, -70, 70, 1001, - /* 80 */ -70, 236, -70, 545, 1007, 1038, 1047, 1013, 1059, -70, - /* 90 */ 870, 38, 870, 519, 870, -70, 1068, 215, 1079, 215, - /* 100 */ -70, -70, -70, -70, -70, -70, -70, 654, 870, 609, - /* 110 */ 870, -11, 870, -11, 870, -11, 870, -11, 870, -69, - /* 120 */ 870, -69, 870, -50, 870, -50, 870, -50, 870, -50, - /* 130 */ 870, 143, 870, 143, 870, 1111, 870, 1111, 870, 1111, - /* 140 */ 870, -70, -70, 377, -70, -70, -70, -70, 870, -56, - /* 150 */ 870, -11, -70, 303, -70, 1104, -70, -70, -70, 870, - /* 160 */ 564, 870, -69, -70, 345, 730, 266, 419, 1087, 1088, - /* 170 */ 1089, -70, 519, 870, 654, 870, -70, 870, -70, 870, - /* 180 */ -70, 1180, 1001, 314, -70, 814, 83, 1070, 650, 1188, - /* 190 */ -70, 870, 128, 870, 519, 1185, 196, 1186, -70, 1187, - /* 200 */ 215, 1190, -70, 870, 202, 870, 247, 870, 519, 591, - /* 210 */ -70, 870, -70, -70, 1097, 215, -70, -70, -70, 870, - /* 220 */ 519, 1098, 870, 1191, 870, 1120, -29, -70, 1194, -70, - /* 230 */ -70, 519, 1120, -29, -70, 870, 519, 1105, 870, 1200, - /* 240 */ 870, 519, -70, -70, 580, -70, -70, -70, 388, -70, - /* 250 */ 687, -70, 1112, -70, 683, 1097, 233, -70, -70, 215, - /* 260 */ -70, -70, 1132, 1118, -70, 1216, 215, 691, -70, 215, - /* 270 */ -70, -70, 870, 519, 1001, 330, 549, 1217, 233, 1132, - /* 280 */ 1118, -70, 842, -25, -70, -70, 1127, 50, -70, -70, - /* 290 */ -70, -70, 321, -70, 736, -70, 1220, -70, 384, 744, - /* 300 */ -70, 215, 1224, -70, 135, -70, 215, -70, 424, 733, - /* 310 */ -70, 571, -70, -70, -70, -70, 733, -70, 733, -70, - /* 320 */ 215, 818, -70, 215, 1120, -29, -70, -70, 1120, -29, - /* 330 */ -70, -70, 1194, -70, 954, -70, -70, 926, -70, 3, - /* 340 */ -70, -70, 3, -70, -70, 681, 618, 874, -70, 618, - /* 350 */ 1235, -70, -70, -70, 727, -70, -70, -70, 727, -70, - /* 360 */ -70, -70, -70, -70, 274, -16, -70, 215, -70, 1215, - /* 370 */ 1245, 215, 630, 1246, 744, -70, 1248, 215, 875, 744, - /* 380 */ -70, 870, 429, -70, 1226, 1254, 215, 891, 1181, 215, - /* 390 */ 1224, -70, 471, 1175, -70, -70, -70, -70, -70, 1001, - /* 400 */ 467, 122, 778, 215, 1097, -70, 215, 766, 1263, 1001, - /* 410 */ 507, 215, 1097, 582, 782, 1192, 215, 1097, -70, 1256, - /* 420 */ 820, 1282, 870, 474, 1259, 834, -70, -70, 1198, 1201, - /* 430 */ 825, 215, 554, -70, -70, 1257, -70, -70, 1164, 215, - /* 440 */ 674, 1206, 215, 1286, 215, 892, 826, 1301, 1176, 1300, - /* 450 */ 74, 511, 741, 323, -70, 1193, 1195, 1297, 1306, 1307, - /* 460 */ 74, 1303, 1260, 215, 1218, 215, 881, 215, 1258, 870, - /* 470 */ 519, 1317, 1261, 870, 519, 1203, 215, 1308, 215, 911, - /* 480 */ -70, 893, 551, 1311, 870, 914, 870, 519, 1325, 519, - /* 490 */ 1221, 215, 939, 1328, 774, 215, 1330, 215, 1331, 215, - /* 500 */ 1332, 215, 1333, 558, 1228, 215, 939, 1336, 1260, 215, - /* 510 */ 1243, 215, 881, 1339, 1227, 215, 1308, 931, 647, 1334, - /* 520 */ 870, 941, 1341, 952, 1343, 215, 1097, 417, 262, 1349, - /* 530 */ 1350, 1351, 1352, 215, 1340, 1355, 1335, 334, 1342, 215, - /* 540 */ 979, 1356, 738, 1358, 1363, -70, 1335, 215, 1364, 999, - /* 550 */ 1063, 1367, 1357, 215, 1037, 1247, 215, 1374, 1249, 1250, - /* 560 */ 215, 1376, -70, -70, -70, + /* 0 */ 201, 81, -72, -72, 1103, -9, 127, -72, 235, 603, + /* 10 */ 318, 286, 427, -72, -72, -72, -72, -72, -72, 603, + /* 20 */ 639, 603, 671, 603, 903, 277, 974, 400, 748, 997, + /* 30 */ 1036, 51, -72, 402, -72, 226, -72, 400, 345, -72, + /* 40 */ 1023, -72, 1041, 395, -72, -72, -72, -72, -72, -72, + /* 50 */ -72, 807, 1023, -72, 1124, -72, 560, -72, -72, 1138, + /* 60 */ 522, 1023, 1094, -72, -72, -72, -72, 1023, -72, 1176, + /* 70 */ 1045, 30, 873, 1088, 1098, -72, 884, -72, 388, 1114, + /* 80 */ -72, 310, -72, -19, 1107, 1115, 1118, 1125, 1127, -72, + /* 90 */ 1045, 40, 1045, 665, 1045, -72, 1132, 400, 1133, 400, + /* 100 */ -72, -72, -72, -72, -72, -72, 1232, 1045, 105, 402, + /* 110 */ -72, -72, 340, 630, 790, -72, 630, 1246, -72, -72, + /* 120 */ -72, 679, -72, -72, -72, 679, -72, -72, -72, -72, + /* 130 */ 1248, -72, 1045, -72, 759, 1045, -11, 1045, -11, 1045, + /* 140 */ -11, 1045, -11, 1045, -71, 1045, -71, 1045, -50, 1045, + /* 150 */ -50, 1045, -50, 1045, -50, 1045, 168, 1045, 168, 1045, + /* 160 */ 1186, 1045, 1186, 1045, 1186, 1045, -72, -72, 441, -72, + /* 170 */ -72, -72, -72, 1045, -56, 1045, -11, -72, 846, -72, + /* 180 */ 1180, -72, -72, -72, 1045, 712, 1045, -71, -72, 289, + /* 190 */ 884, 393, 700, 1162, 1164, 1165, -72, 665, 1045, 806, + /* 200 */ 1045, -72, 1045, -72, 1045, -72, 1258, 1114, 401, -72, + /* 210 */ 958, 152, 1146, 416, 1268, -72, 1045, 199, 1045, 665, + /* 220 */ 1264, 530, 1266, -72, 1262, 400, 1269, -72, 1045, 273, + /* 230 */ 1045, 320, 1045, 665, 793, -72, 1045, -72, -72, 1175, + /* 240 */ 400, -72, -72, -72, 806, 1045, 665, 1173, 1045, 1271, + /* 250 */ 1045, 1197, 522, -72, 1274, -72, -72, 665, 1197, 522, + /* 260 */ -72, 1045, 665, 1181, 1045, 1276, 1045, 665, -72, -72, + /* 270 */ 635, -72, -72, -72, 458, -72, 463, -72, 1191, -72, + /* 280 */ 534, 1175, 779, 400, -72, -72, 1210, 1195, -72, 1294, + /* 290 */ 400, 829, -72, 400, -72, -72, 1045, 665, 1114, 467, + /* 300 */ 279, 1296, 779, 1210, 1195, -72, 1017, -25, -72, -72, + /* 310 */ 1205, 536, -72, -72, -72, -72, 394, -72, 837, -72, + /* 320 */ 1300, -72, 459, 1023, -72, 400, 1304, -72, 112, -72, + /* 330 */ 400, -72, 619, 662, -72, 832, -72, -72, -72, -72, + /* 340 */ 662, -72, 662, -72, 400, 919, -72, 400, 1197, 522, + /* 350 */ -72, -72, 1197, 522, -72, -72, 1274, -72, 1124, -72, + /* 360 */ -72, 70, -72, 1045, 524, -72, 239, -72, -72, 239, + /* 370 */ -72, -72, -72, -72, 58, 149, -72, 400, -72, 1290, + /* 380 */ 1318, 400, 59, 1322, 1023, -72, 1324, 400, 929, 1023, + /* 390 */ -72, 1045, 571, -72, 1301, 1325, 400, 948, 1250, 400, + /* 400 */ 1304, -72, 517, 1245, -72, -72, -72, -72, -72, 1114, + /* 410 */ 552, 843, 754, 400, 1175, -72, 400, 140, 1339, 1114, + /* 420 */ 556, 400, 1175, 869, 657, 1267, 400, 1175, -72, 1327, + /* 430 */ 850, 1361, 1045, 618, 1335, 942, -72, -72, 1273, 1275, + /* 440 */ 875, 400, 962, -72, -72, 1328, -72, -72, 1240, 400, + /* 450 */ 906, 1279, 400, 1362, 400, 1001, 761, 1374, 1247, 1376, + /* 460 */ 189, 562, 968, 395, -72, 1263, 1265, 1373, 1383, 1384, + /* 470 */ 189, 1377, 1332, 400, 1291, 400, 792, 400, 1326, 1045, + /* 480 */ 665, 1390, 1331, 1045, 665, 1278, 400, 1385, 400, 1007, + /* 490 */ -72, 984, 604, 1386, 1045, 1012, 1045, 665, 1400, 665, + /* 500 */ 1293, 400, 1033, 1404, 651, 400, 1405, 400, 1406, 400, + /* 510 */ 1407, 400, 1408, 566, 1302, 400, 1033, 1411, 1332, 400, + /* 520 */ 1316, 400, 792, 1415, 1299, 400, 1385, 1016, 608, 1409, + /* 530 */ 1045, 1129, 1417, 476, 1418, 400, 1175, 697, 111, 1420, + /* 540 */ 1421, 1424, 1427, 400, 1416, 1429, 1410, 402, 1419, 400, + /* 550 */ 1025, 1432, 729, 1433, 1435, -72, 1410, 400, 1441, 839, + /* 560 */ 981, 1442, 841, 981, 1443, 1439, 400, 1021, 1321, 400, + /* 570 */ 1446, 1323, 1329, 400, 1456, -72, -72, -72, }; -#define YY_REDUCE_USE_DFLT (-71) +#define YY_REDUCE_USE_DFLT (-151) static const short yy_reduce_ofst[] = { - /* 0 */ -59, 211, -71, -71, 556, -71, -71, -71, -70, -53, - /* 10 */ -71, 189, -71, -71, -71, -71, -71, -71, -71, 268, - /* 20 */ -71, 325, -71, 463, -71, 589, -71, -60, 596, -71, - /* 30 */ -71, 75, -71, 256, 655, 313, -71, 673, 444, -71, - /* 40 */ 757, -71, -71, 121, -71, -71, -71, -71, -71, -71, - /* 50 */ -71, -71, 795, -71, 804, -71, -71, -71, -71, -71, - /* 60 */ 839, 898, 899, -71, -71, -71, -71, 907, -71, -71, - /* 70 */ 706, -71, 206, -71, -71, -71, 598, -71, 964, 936, - /* 80 */ -71, 938, 370, 940, 974, 985, 976, 990, 994, -71, - /* 90 */ 720, 82, 739, 82, 806, -71, -71, 1043, -71, 1046, - /* 100 */ -71, -71, -71, -71, -71, -71, -71, 82, 807, 82, - /* 110 */ 813, 82, 844, 82, 862, 82, 863, 82, 865, 82, - /* 120 */ 871, 82, 877, 82, 878, 82, 890, 82, 896, 82, - /* 130 */ 909, 82, 921, 82, 924, 82, 932, 82, 934, 82, - /* 140 */ 935, 82, -71, -71, -71, -71, -71, -71, 937, 117, - /* 150 */ 942, 82, -71, -71, -71, -71, -71, -71, -71, 943, - /* 160 */ 82, 949, 82, -71, 1049, 593, 964, -71, -71, -71, - /* 170 */ -71, -71, 82, 960, 82, 965, 82, 970, 82, 971, - /* 180 */ 82, -71, 32, 964, -71, 264, 82, 983, 984, -71, - /* 190 */ -71, 972, 82, 977, 82, -71, 1022, -71, -71, -71, - /* 200 */ 1061, -71, -71, 978, 82, 986, 82, 987, 82, -71, - /* 210 */ -71, 310, -71, -71, 1062, 1065, -71, -71, -71, 988, - /* 220 */ 82, -71, -36, -71, 400, 1012, 1048, -71, 1060, -71, - /* 230 */ -71, 82, 1017, 1052, -71, 993, 82, -71, 263, -71, - /* 240 */ 1000, 82, -71, 230, 1024, -71, -71, -71, 1080, -71, - /* 250 */ 1081, -71, -71, -71, 1082, 1083, 78, -71, -71, 1084, - /* 260 */ -71, -71, 1031, 1033, -71, -71, 508, -71, -71, 1090, - /* 270 */ -71, -71, 1003, 82, -18, 964, 1024, -71, 496, 1039, - /* 280 */ 1040, -71, 1005, 140, -71, -71, -71, 1043, -71, -71, - /* 290 */ -71, -71, 82, -71, -71, -71, -71, -71, 82, 1075, - /* 300 */ -71, 1099, 1073, 1076, 1072, -71, 1101, -71, -71, 1077, - /* 310 */ -71, -71, -71, -71, -71, -71, 1078, -71, 1085, -71, - /* 320 */ 381, -71, -71, 369, 1042, 1086, -71, -71, 1044, 1091, - /* 330 */ -71, -71, 1092, -71, 1093, -71, -71, 626, -71, 1095, - /* 340 */ -71, -71, 1096, -71, -71, 1106, 182, -71, -71, 245, - /* 350 */ -71, -71, -71, -71, 1032, -71, -71, -71, 1034, -71, - /* 360 */ -71, -71, -71, -71, 1094, 1100, -71, 1117, -71, -71, - /* 370 */ -71, 383, 1102, -71, 1103, -71, -71, 642, -71, 1107, - /* 380 */ -71, 1014, 305, -71, -71, -71, 657, -71, -71, 1130, - /* 390 */ 1108, 1109, -49, -71, -71, -71, -71, -71, -71, 587, - /* 400 */ 964, 601, -71, 1134, 1133, -71, 1136, 1135, -71, 725, - /* 410 */ 964, 1140, 1137, 1064, 1066, -71, 295, 1138, -71, 1067, - /* 420 */ 1069, -71, 808, 82, -71, -71, -71, -71, -71, -71, - /* 430 */ -71, 721, -71, -71, -71, -71, -71, -71, -71, 1155, - /* 440 */ 1152, -71, 1158, -71, 729, -71, 1139, -71, -71, -71, - /* 450 */ 592, 964, 1129, 735, -71, -71, -71, -71, -71, -71, - /* 460 */ 604, -71, 1141, 1169, -71, 845, 1131, 1174, -71, 1015, - /* 470 */ 82, -71, -71, 1016, 82, -71, 1183, 1115, 760, -71, - /* 480 */ -71, 860, 964, -71, 535, -71, 1021, 82, -71, 82, - /* 490 */ -71, 1189, 1142, -71, -71, 800, -71, 873, -71, 880, - /* 500 */ -71, 900, -71, 964, -71, 912, 1151, -71, 1162, 915, - /* 510 */ -71, 888, 1156, -71, -71, 930, 1143, 992, 964, -71, - /* 520 */ 703, -71, -71, 1204, -71, 1205, 1202, -71, 648, -71, - /* 530 */ -71, -71, -71, 1213, -71, -71, 1144, 1208, -71, 1219, - /* 540 */ 1145, -71, 1209, -71, -71, -71, 1147, 1225, -71, 1229, - /* 550 */ 1222, -71, -71, 191, -71, -71, 1231, -71, -71, 1148, - /* 560 */ 553, -71, -71, -71, -71, + /* 0 */ 64, 95, -151, -151, -59, -151, -151, -151, 33, 155, + /* 10 */ -151, 224, -151, -151, -151, -151, -151, -151, -151, 428, + /* 20 */ -151, 509, -151, 758, -151, 430, -151, 45, 771, -151, + /* 30 */ -151, -21, -151, -64, 865, 244, -151, 910, -85, -151, + /* 40 */ 895, -151, -151, -125, -151, -151, -151, -151, -151, -151, + /* 50 */ -151, -151, 1010, -151, 1000, -151, -151, -151, -151, -151, + /* 60 */ 1011, 1022, 1024, -151, -151, -151, -151, 1028, -151, -151, + /* 70 */ 125, -151, 156, -151, -151, -151, 159, -151, 1037, 1039, + /* 80 */ -151, 1040, 420, 1014, 1047, 1042, 1049, 1051, 1055, -151, + /* 90 */ 348, 411, 450, 411, 649, -151, -151, 1105, -151, 1119, + /* 100 */ -151, -151, -151, -151, -151, -151, -151, 685, 411, 254, + /* 110 */ -151, -151, 1108, -150, -151, -151, -34, -151, -151, -151, + /* 120 */ -151, 1044, -151, -151, -151, 1053, -151, -151, -151, -151, + /* 130 */ -151, -151, 696, -151, 411, 732, 411, 743, 411, 747, + /* 140 */ 411, 749, 411, 778, 411, 786, 411, 788, 411, 797, + /* 150 */ 411, 827, 411, 838, 411, 874, 411, 882, 411, 885, + /* 160 */ 411, 887, 411, 893, 411, 901, 411, -151, -151, -151, + /* 170 */ -151, -151, -151, 932, 39, 951, 411, -151, -151, -151, + /* 180 */ -151, -151, -151, -151, 991, 411, 1008, 411, -151, 1126, + /* 190 */ 912, 1037, -151, -151, -151, -151, -151, 411, 1015, 411, + /* 200 */ 1018, 411, 1020, 411, 1038, 411, -151, 745, 1037, -151, + /* 210 */ 343, 411, 1058, 1059, -151, -151, 1043, 411, 1046, 411, + /* 220 */ -151, 1099, -151, -151, -151, 1139, -151, -151, 1048, 411, + /* 230 */ 1050, 411, 1052, 411, -151, -151, 257, -151, -151, 1140, + /* 240 */ 1142, -151, -151, -151, 411, 1054, 411, -151, 276, -151, + /* 250 */ 346, 1086, 1123, -151, 1141, -151, -151, 411, 1090, 1130, + /* 260 */ -151, 1062, 411, -151, 281, -151, 1080, 411, -151, 652, + /* 270 */ 1101, -151, -151, -151, 1156, -151, 1157, -151, -151, -151, + /* 280 */ 1159, 1158, 506, 1160, -151, -151, 1109, 1110, -151, -151, + /* 290 */ 78, -151, -151, 1167, -151, -151, 1085, 411, -63, 1037, + /* 300 */ 1101, -151, 789, 1116, 1113, -151, 1087, 87, -151, -151, + /* 310 */ -151, 1105, -151, -151, -151, -151, 411, -151, -151, -151, + /* 320 */ -151, -151, 411, 1150, -151, 1174, 1151, 1149, 1152, -151, + /* 330 */ 1178, -151, -151, 1153, -151, -151, -151, -151, -151, -151, + /* 340 */ 1154, -151, 1155, -151, 433, -151, -151, 715, 1117, 1163, + /* 350 */ -151, -151, 1120, 1166, -151, -151, 1168, -151, 1161, -151, + /* 360 */ -151, 593, -151, 1089, 411, -151, 1170, -151, -151, 1172, + /* 370 */ -151, -151, -151, -151, 1169, 1171, -151, 1188, -151, -151, + /* 380 */ -151, 526, 1182, -151, 1177, -151, -151, 574, -151, 1183, + /* 390 */ -151, 1091, 142, -151, -151, -151, 621, -151, -151, 1199, + /* 400 */ 1179, 1184, 193, -151, -151, -151, -151, -151, -151, 804, + /* 410 */ 1037, 755, -151, 1203, 1204, -151, 1209, 1206, -151, 830, + /* 420 */ 1037, 1213, 1211, 1134, 1131, -151, 261, 1215, -151, 1136, + /* 430 */ 1137, -151, 774, 411, -151, -151, -151, -151, -151, -151, + /* 440 */ -151, 516, -151, -151, -151, -151, -151, -151, -151, 1228, + /* 450 */ 1225, -151, 1231, -151, 668, -151, 1212, -151, -151, -151, + /* 460 */ 218, 1037, 1201, 840, -151, -151, -151, -151, -151, -151, + /* 470 */ 280, -151, 1214, 1249, -151, 295, 1200, 1251, -151, 821, + /* 480 */ 411, -151, -151, 1093, 411, -151, 1254, 1189, 905, -151, + /* 490 */ -151, 904, 1037, -151, 413, -151, 1095, 411, -151, 411, + /* 500 */ -151, 1260, 1216, -151, -151, 926, -151, 966, -151, 967, + /* 510 */ -151, 978, -151, 1037, -151, 980, 1222, -151, 1234, 982, + /* 520 */ -151, 924, 1227, -151, -151, 993, 1217, 922, 1037, -151, + /* 530 */ 591, -151, -151, 1277, -151, 1281, 1280, -151, 145, -151, + /* 540 */ -151, -151, -151, 1286, -151, -151, 1202, 1283, -151, 1297, + /* 550 */ 1218, -151, 1285, -151, -151, -151, 1207, 1303, -151, 1305, + /* 560 */ 1298, -151, 1307, 1306, -151, -151, -73, -151, -151, 1311, + /* 570 */ -151, -151, 1223, 607, -151, -151, -151, -151, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 571, 571, 566, 569, 870, 870, 870, 570, 577, 870, - /* 10 */ 870, 870, 870, 597, 598, 599, 578, 579, 580, 870, - /* 20 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, - /* 30 */ 870, 870, 590, 600, 609, 592, 608, 870, 870, 610, - /* 40 */ 653, 616, 870, 870, 654, 657, 658, 659, 852, 853, - /* 50 */ 854, 870, 653, 617, 638, 636, 870, 639, 640, 870, - /* 60 */ 709, 653, 624, 618, 625, 707, 708, 653, 619, 870, - /* 70 */ 870, 739, 804, 745, 740, 736, 870, 664, 870, 870, - /* 80 */ 665, 673, 675, 682, 721, 712, 714, 702, 716, 670, - /* 90 */ 870, 717, 870, 718, 870, 738, 870, 870, 741, 870, - /* 100 */ 742, 743, 744, 746, 747, 748, 751, 752, 870, 753, - /* 110 */ 870, 754, 870, 755, 870, 756, 870, 757, 870, 758, - /* 120 */ 870, 759, 870, 760, 870, 761, 870, 762, 870, 763, - /* 130 */ 870, 764, 870, 765, 870, 766, 870, 767, 870, 768, - /* 140 */ 870, 769, 770, 870, 771, 778, 785, 788, 870, 773, - /* 150 */ 870, 772, 775, 870, 776, 870, 779, 777, 784, 870, - /* 160 */ 870, 870, 786, 787, 870, 804, 870, 870, 870, 870, - /* 170 */ 870, 791, 803, 870, 780, 870, 781, 870, 782, 870, - /* 180 */ 783, 870, 870, 870, 793, 870, 870, 870, 870, 870, - /* 190 */ 794, 870, 870, 870, 795, 870, 870, 870, 850, 870, - /* 200 */ 870, 870, 851, 870, 870, 870, 870, 870, 796, 870, - /* 210 */ 789, 804, 801, 802, 690, 870, 691, 792, 774, 870, - /* 220 */ 719, 870, 870, 703, 870, 710, 709, 704, 870, 594, - /* 230 */ 711, 706, 710, 709, 705, 870, 715, 870, 804, 713, - /* 240 */ 870, 722, 674, 685, 683, 684, 693, 694, 870, 695, - /* 250 */ 870, 696, 870, 697, 870, 690, 681, 595, 596, 870, - /* 260 */ 679, 680, 699, 701, 686, 870, 870, 870, 700, 870, - /* 270 */ 734, 735, 870, 698, 685, 870, 870, 870, 681, 699, - /* 280 */ 701, 687, 870, 681, 676, 677, 870, 870, 678, 671, - /* 290 */ 672, 790, 870, 737, 870, 749, 870, 750, 870, 653, - /* 300 */ 620, 870, 808, 626, 621, 627, 870, 628, 870, 870, - /* 310 */ 629, 870, 632, 633, 634, 635, 870, 630, 870, 631, - /* 320 */ 870, 870, 809, 870, 710, 709, 810, 812, 710, 709, - /* 330 */ 811, 622, 870, 623, 638, 637, 611, 870, 612, 870, - /* 340 */ 613, 745, 870, 614, 615, 601, 827, 870, 602, 827, - /* 350 */ 870, 603, 606, 607, 870, 822, 824, 825, 870, 823, - /* 360 */ 826, 605, 604, 593, 870, 870, 643, 870, 646, 870, - /* 370 */ 870, 870, 870, 870, 653, 647, 870, 870, 870, 653, - /* 380 */ 648, 870, 653, 649, 870, 870, 870, 870, 870, 870, - /* 390 */ 808, 626, 651, 870, 650, 652, 644, 645, 591, 870, - /* 400 */ 870, 587, 870, 870, 690, 585, 870, 870, 870, 870, - /* 410 */ 870, 870, 690, 833, 870, 870, 870, 690, 692, 838, - /* 420 */ 870, 870, 870, 870, 870, 870, 839, 840, 870, 870, - /* 430 */ 870, 870, 870, 830, 831, 870, 832, 586, 870, 870, - /* 440 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, - /* 450 */ 870, 870, 870, 870, 656, 870, 870, 870, 870, 870, - /* 460 */ 870, 870, 655, 870, 870, 870, 870, 870, 870, 870, - /* 470 */ 724, 870, 870, 870, 725, 870, 870, 732, 870, 870, - /* 480 */ 733, 870, 870, 870, 870, 870, 870, 730, 870, 731, - /* 490 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, - /* 500 */ 870, 870, 870, 870, 870, 870, 870, 870, 655, 870, - /* 510 */ 870, 870, 870, 870, 870, 870, 732, 870, 870, 870, - /* 520 */ 870, 870, 870, 870, 870, 870, 690, 870, 827, 870, - /* 530 */ 870, 870, 870, 870, 870, 870, 861, 870, 870, 870, - /* 540 */ 870, 870, 870, 870, 870, 860, 861, 870, 870, 870, - /* 550 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 868, - /* 560 */ 870, 870, 869, 572, 567, + /* 0 */ 584, 584, 579, 582, 888, 888, 888, 583, 590, 888, + /* 10 */ 888, 888, 888, 610, 611, 612, 591, 592, 593, 888, + /* 20 */ 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, + /* 30 */ 888, 888, 603, 613, 623, 605, 622, 888, 888, 624, + /* 40 */ 668, 631, 888, 888, 669, 672, 673, 674, 868, 869, + /* 50 */ 870, 888, 668, 632, 653, 651, 888, 654, 655, 888, + /* 60 */ 724, 668, 639, 633, 640, 722, 723, 668, 634, 888, + /* 70 */ 888, 754, 820, 760, 755, 751, 888, 679, 888, 888, + /* 80 */ 680, 688, 690, 697, 736, 727, 729, 717, 731, 685, + /* 90 */ 888, 732, 888, 733, 888, 753, 888, 888, 756, 888, + /* 100 */ 757, 758, 759, 761, 762, 763, 888, 888, 888, 888, + /* 110 */ 608, 609, 615, 843, 888, 616, 843, 888, 617, 620, + /* 120 */ 621, 888, 838, 840, 841, 888, 839, 842, 619, 618, + /* 130 */ 888, 764, 888, 767, 769, 888, 770, 888, 771, 888, + /* 140 */ 772, 888, 773, 888, 774, 888, 775, 888, 776, 888, + /* 150 */ 777, 888, 778, 888, 779, 888, 780, 888, 781, 888, + /* 160 */ 782, 888, 783, 888, 784, 888, 785, 786, 888, 787, + /* 170 */ 794, 801, 804, 888, 789, 888, 788, 791, 888, 792, + /* 180 */ 888, 795, 793, 800, 888, 888, 888, 802, 803, 888, + /* 190 */ 820, 888, 888, 888, 888, 888, 807, 819, 888, 796, + /* 200 */ 888, 797, 888, 798, 888, 799, 888, 888, 888, 809, + /* 210 */ 888, 888, 888, 888, 888, 810, 888, 888, 888, 811, + /* 220 */ 888, 888, 888, 866, 888, 888, 888, 867, 888, 888, + /* 230 */ 888, 888, 888, 812, 888, 805, 820, 817, 818, 705, + /* 240 */ 888, 706, 808, 790, 768, 888, 734, 888, 888, 718, + /* 250 */ 888, 725, 724, 719, 888, 607, 726, 721, 725, 724, + /* 260 */ 720, 888, 730, 888, 820, 728, 888, 737, 689, 700, + /* 270 */ 698, 699, 708, 709, 888, 710, 888, 711, 888, 712, + /* 280 */ 888, 705, 696, 888, 694, 695, 714, 716, 701, 888, + /* 290 */ 888, 888, 715, 888, 749, 750, 888, 713, 700, 888, + /* 300 */ 888, 888, 696, 714, 716, 702, 888, 696, 691, 692, + /* 310 */ 888, 888, 693, 686, 687, 806, 888, 752, 888, 765, + /* 320 */ 888, 766, 888, 668, 635, 888, 824, 641, 636, 642, + /* 330 */ 888, 643, 888, 888, 644, 888, 647, 648, 649, 650, + /* 340 */ 888, 645, 888, 646, 888, 888, 825, 888, 725, 724, + /* 350 */ 826, 828, 725, 724, 827, 637, 888, 638, 653, 652, + /* 360 */ 625, 888, 626, 888, 888, 627, 888, 628, 760, 888, + /* 370 */ 629, 630, 614, 606, 888, 888, 658, 888, 661, 888, + /* 380 */ 888, 888, 888, 888, 668, 662, 888, 888, 888, 668, + /* 390 */ 663, 888, 668, 664, 888, 888, 888, 888, 888, 888, + /* 400 */ 824, 641, 666, 888, 665, 667, 659, 660, 604, 888, + /* 410 */ 888, 600, 888, 888, 705, 598, 888, 888, 888, 888, + /* 420 */ 888, 888, 705, 849, 888, 888, 888, 705, 707, 854, + /* 430 */ 888, 888, 888, 888, 888, 888, 855, 856, 888, 888, + /* 440 */ 888, 888, 888, 846, 847, 888, 848, 599, 888, 888, + /* 450 */ 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, + /* 460 */ 888, 888, 888, 888, 671, 888, 888, 888, 888, 888, + /* 470 */ 888, 888, 670, 888, 888, 888, 888, 888, 888, 888, + /* 480 */ 739, 888, 888, 888, 740, 888, 888, 747, 888, 888, + /* 490 */ 748, 888, 888, 888, 888, 888, 888, 745, 888, 746, + /* 500 */ 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, + /* 510 */ 888, 888, 888, 888, 888, 888, 888, 888, 670, 888, + /* 520 */ 888, 888, 888, 888, 888, 888, 747, 888, 888, 888, + /* 530 */ 888, 888, 888, 888, 888, 888, 705, 888, 843, 888, + /* 540 */ 888, 888, 888, 888, 888, 888, 877, 888, 888, 888, + /* 550 */ 888, 888, 888, 888, 888, 876, 877, 888, 888, 888, + /* 560 */ 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, + /* 570 */ 888, 888, 886, 888, 888, 887, 585, 580, }; #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) @@ -681,10 +700,12 @@ static const YYCODETYPE yyFallback[] = { 0, /* ID => nothing */ 27, /* ABORT => ID */ 27, /* AFTER => ID */ + 27, /* ANALYZE => ID */ 27, /* ASC => ID */ 27, /* ATTACH => ID */ 27, /* BEFORE => ID */ 27, /* CASCADE => ID */ + 27, /* CAST => ID */ 27, /* CONFLICT => ID */ 27, /* DATABASE => ID */ 27, /* DESC => ID */ @@ -869,59 +890,60 @@ static const char *const yyTokenName[] = { "EXCLUSIVE", "COMMIT", "END", "ROLLBACK", "CREATE", "TABLE", "TEMP", "LP", "RP", "AS", "COMMA", "ID", - "ABORT", "AFTER", "ASC", "ATTACH", - "BEFORE", "CASCADE", "CONFLICT", "DATABASE", - "DESC", "DETACH", "EACH", "FAIL", - "FOR", "IGNORE", "INITIALLY", "INSTEAD", - "LIKE_KW", "MATCH", "KEY", "OF", - "OFFSET", "PRAGMA", "RAISE", "REPLACE", - "RESTRICT", "ROW", "STATEMENT", "TRIGGER", - "VACUUM", "VIEW", "REINDEX", "RENAME", - "CTIME_KW", "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", "DISTINCT", "DOT", - "FROM", "JOIN", "USING", "ORDER", - "BY", "GROUP", "HAVING", "LIMIT", - "WHERE", "INTO", "VALUES", "INTEGER", - "FLOAT", "BLOB", "REGISTER", "VARIABLE", - "EXISTS", "CASE", "WHEN", "THEN", - "ELSE", "INDEX", "TO", "ADD", - "COLUMNKW", "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", "add_column_fullname", "kwcolumn_opt", + "ABORT", "AFTER", "ANALYZE", "ASC", + "ATTACH", "BEFORE", "CASCADE", "CAST", + "CONFLICT", "DATABASE", "DESC", "DETACH", + "EACH", "FAIL", "FOR", "IGNORE", + "INITIALLY", "INSTEAD", "LIKE_KW", "MATCH", + "KEY", "OF", "OFFSET", "PRAGMA", + "RAISE", "REPLACE", "RESTRICT", "ROW", + "STATEMENT", "TRIGGER", "VACUUM", "VIEW", + "REINDEX", "RENAME", "CTIME_KW", "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", + "DISTINCT", "DOT", "FROM", "JOIN", + "USING", "ORDER", "BY", "GROUP", + "HAVING", "LIMIT", "WHERE", "INTO", + "VALUES", "INTEGER", "FLOAT", "BLOB", + "REGISTER", "VARIABLE", "EXISTS", "CASE", + "WHEN", "THEN", "ELSE", "INDEX", + "TO", "ADD", "COLUMNKW", "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", "typetoken", "typename", + "signed", "plus_num", "minus_num", "carg", + "ccons", "term", "expr", "onconf", + "sortorder", "autoinc", "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", "add_column_fullname", "kwcolumn_opt", }; #endif /* NDEBUG */ @@ -965,275 +987,280 @@ static const char *const yyRuleName[] = { /* 33 */ "nm ::= STRING", /* 34 */ "nm ::= JOIN_KW", /* 35 */ "type ::=", - /* 36 */ "type ::= typename", - /* 37 */ "type ::= typename LP signed RP", - /* 38 */ "type ::= typename LP signed COMMA signed RP", - /* 39 */ "typename ::= ids", - /* 40 */ "typename ::= typename ids", - /* 41 */ "signed ::= plus_num", - /* 42 */ "signed ::= minus_num", - /* 43 */ "carglist ::= carglist carg", - /* 44 */ "carglist ::=", - /* 45 */ "carg ::= CONSTRAINT nm ccons", - /* 46 */ "carg ::= ccons", - /* 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 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 */ "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 */ "term ::= BLOB", - /* 182 */ "expr ::= REGISTER", - /* 183 */ "expr ::= VARIABLE", - /* 184 */ "expr ::= ID LP exprlist RP", - /* 185 */ "expr ::= ID LP STAR RP", - /* 186 */ "term ::= CTIME_KW", - /* 187 */ "expr ::= expr AND expr", - /* 188 */ "expr ::= expr OR expr", - /* 189 */ "expr ::= expr LT expr", - /* 190 */ "expr ::= expr GT expr", - /* 191 */ "expr ::= expr LE expr", - /* 192 */ "expr ::= expr GE expr", - /* 193 */ "expr ::= expr NE expr", - /* 194 */ "expr ::= expr EQ expr", - /* 195 */ "expr ::= expr BITAND expr", - /* 196 */ "expr ::= expr BITOR expr", - /* 197 */ "expr ::= expr LSHIFT expr", - /* 198 */ "expr ::= expr RSHIFT expr", - /* 199 */ "expr ::= expr PLUS expr", - /* 200 */ "expr ::= expr MINUS expr", - /* 201 */ "expr ::= expr STAR expr", - /* 202 */ "expr ::= expr SLASH expr", - /* 203 */ "expr ::= expr REM expr", - /* 204 */ "expr ::= expr CONCAT expr", - /* 205 */ "likeop ::= LIKE_KW", - /* 206 */ "likeop ::= NOT LIKE_KW", - /* 207 */ "escape ::= ESCAPE expr", - /* 208 */ "escape ::=", - /* 209 */ "expr ::= expr likeop expr escape", - /* 210 */ "expr ::= expr ISNULL", - /* 211 */ "expr ::= expr IS NULL", - /* 212 */ "expr ::= expr NOTNULL", - /* 213 */ "expr ::= expr NOT NULL", - /* 214 */ "expr ::= expr IS NOT NULL", - /* 215 */ "expr ::= NOT expr", - /* 216 */ "expr ::= BITNOT expr", - /* 217 */ "expr ::= MINUS expr", - /* 218 */ "expr ::= PLUS expr", - /* 219 */ "between_op ::= BETWEEN", - /* 220 */ "between_op ::= NOT BETWEEN", - /* 221 */ "expr ::= expr between_op expr AND expr", - /* 222 */ "in_op ::= IN", - /* 223 */ "in_op ::= NOT IN", - /* 224 */ "expr ::= expr in_op LP exprlist RP", - /* 225 */ "expr ::= LP select RP", - /* 226 */ "expr ::= expr in_op LP select RP", - /* 227 */ "expr ::= expr in_op nm dbnm", - /* 228 */ "expr ::= EXISTS LP select RP", - /* 229 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 230 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 231 */ "case_exprlist ::= WHEN expr THEN expr", - /* 232 */ "case_else ::= ELSE expr", - /* 233 */ "case_else ::=", - /* 234 */ "case_operand ::= expr", - /* 235 */ "case_operand ::=", - /* 236 */ "exprlist ::= exprlist COMMA expritem", - /* 237 */ "exprlist ::= expritem", - /* 238 */ "expritem ::= expr", - /* 239 */ "expritem ::=", - /* 240 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf", - /* 241 */ "uniqueflag ::= UNIQUE", - /* 242 */ "uniqueflag ::=", - /* 243 */ "idxlist_opt ::=", - /* 244 */ "idxlist_opt ::= LP idxlist RP", - /* 245 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", - /* 246 */ "idxlist ::= idxitem collate sortorder", - /* 247 */ "idxitem ::= nm", - /* 248 */ "cmd ::= DROP INDEX fullname", - /* 249 */ "cmd ::= VACUUM", - /* 250 */ "cmd ::= VACUUM nm", - /* 251 */ "cmd ::= PRAGMA nm dbnm EQ nm", - /* 252 */ "cmd ::= PRAGMA nm dbnm EQ ON", - /* 253 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", - /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 255 */ "cmd ::= PRAGMA nm dbnm LP nm RP", - /* 256 */ "cmd ::= PRAGMA nm dbnm", - /* 257 */ "plus_num ::= plus_opt number", - /* 258 */ "minus_num ::= MINUS number", - /* 259 */ "number ::= INTEGER", - /* 260 */ "number ::= FLOAT", - /* 261 */ "plus_opt ::= PLUS", - /* 262 */ "plus_opt ::=", - /* 263 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", - /* 264 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 265 */ "trigger_time ::= BEFORE", - /* 266 */ "trigger_time ::= AFTER", - /* 267 */ "trigger_time ::= INSTEAD OF", - /* 268 */ "trigger_time ::=", - /* 269 */ "trigger_event ::= DELETE", - /* 270 */ "trigger_event ::= INSERT", - /* 271 */ "trigger_event ::= UPDATE", - /* 272 */ "trigger_event ::= UPDATE OF inscollist", - /* 273 */ "foreach_clause ::=", - /* 274 */ "foreach_clause ::= FOR EACH ROW", - /* 275 */ "foreach_clause ::= FOR EACH STATEMENT", - /* 276 */ "when_clause ::=", - /* 277 */ "when_clause ::= WHEN expr", - /* 278 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", - /* 279 */ "trigger_cmd_list ::=", - /* 280 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 281 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 282 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 283 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 284 */ "trigger_cmd ::= select", - /* 285 */ "expr ::= RAISE LP IGNORE RP", - /* 286 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 287 */ "raisetype ::= ROLLBACK", - /* 288 */ "raisetype ::= ABORT", - /* 289 */ "raisetype ::= FAIL", - /* 290 */ "cmd ::= DROP TRIGGER fullname", - /* 291 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", - /* 292 */ "key_opt ::=", - /* 293 */ "key_opt ::= KEY ids", - /* 294 */ "key_opt ::= KEY BLOB", - /* 295 */ "database_kw_opt ::= DATABASE", - /* 296 */ "database_kw_opt ::=", - /* 297 */ "cmd ::= DETACH database_kw_opt nm", - /* 298 */ "cmd ::= REINDEX", - /* 299 */ "cmd ::= REINDEX nm dbnm", - /* 300 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 301 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 302 */ "add_column_fullname ::= fullname", - /* 303 */ "kwcolumn_opt ::=", - /* 304 */ "kwcolumn_opt ::= COLUMNKW", + /* 36 */ "type ::= typetoken", + /* 37 */ "typetoken ::= typename", + /* 38 */ "typetoken ::= typename LP signed RP", + /* 39 */ "typetoken ::= typename LP signed COMMA signed RP", + /* 40 */ "typename ::= ids", + /* 41 */ "typename ::= typename ids", + /* 42 */ "signed ::= plus_num", + /* 43 */ "signed ::= minus_num", + /* 44 */ "carglist ::= carglist carg", + /* 45 */ "carglist ::=", + /* 46 */ "carg ::= CONSTRAINT nm ccons", + /* 47 */ "carg ::= ccons", + /* 48 */ "carg ::= DEFAULT term", + /* 49 */ "carg ::= DEFAULT LP expr RP", + /* 50 */ "carg ::= DEFAULT PLUS term", + /* 51 */ "carg ::= DEFAULT MINUS term", + /* 52 */ "carg ::= DEFAULT id", + /* 53 */ "ccons ::= NULL onconf", + /* 54 */ "ccons ::= NOT NULL onconf", + /* 55 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", + /* 56 */ "ccons ::= UNIQUE onconf", + /* 57 */ "ccons ::= CHECK LP expr RP onconf", + /* 58 */ "ccons ::= REFERENCES nm idxlist_opt refargs", + /* 59 */ "ccons ::= defer_subclause", + /* 60 */ "ccons ::= COLLATE id", + /* 61 */ "autoinc ::=", + /* 62 */ "autoinc ::= AUTOINCR", + /* 63 */ "refargs ::=", + /* 64 */ "refargs ::= refargs refarg", + /* 65 */ "refarg ::= MATCH nm", + /* 66 */ "refarg ::= ON DELETE refact", + /* 67 */ "refarg ::= ON UPDATE refact", + /* 68 */ "refarg ::= ON INSERT refact", + /* 69 */ "refact ::= SET NULL", + /* 70 */ "refact ::= SET DEFAULT", + /* 71 */ "refact ::= CASCADE", + /* 72 */ "refact ::= RESTRICT", + /* 73 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 74 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 75 */ "init_deferred_pred_opt ::=", + /* 76 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 77 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 78 */ "conslist_opt ::=", + /* 79 */ "conslist_opt ::= COMMA conslist", + /* 80 */ "conslist ::= conslist COMMA tcons", + /* 81 */ "conslist ::= conslist tcons", + /* 82 */ "conslist ::= tcons", + /* 83 */ "tcons ::= CONSTRAINT nm", + /* 84 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", + /* 85 */ "tcons ::= UNIQUE LP idxlist RP onconf", + /* 86 */ "tcons ::= CHECK expr onconf", + /* 87 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", + /* 88 */ "defer_subclause_opt ::=", + /* 89 */ "defer_subclause_opt ::= defer_subclause", + /* 90 */ "onconf ::=", + /* 91 */ "onconf ::= ON CONFLICT resolvetype", + /* 92 */ "orconf ::=", + /* 93 */ "orconf ::= OR resolvetype", + /* 94 */ "resolvetype ::= raisetype", + /* 95 */ "resolvetype ::= IGNORE", + /* 96 */ "resolvetype ::= REPLACE", + /* 97 */ "cmd ::= DROP TABLE fullname", + /* 98 */ "cmd ::= CREATE temp VIEW nm dbnm AS select", + /* 99 */ "cmd ::= DROP VIEW fullname", + /* 100 */ "cmd ::= select", + /* 101 */ "select ::= oneselect", + /* 102 */ "select ::= select multiselect_op oneselect", + /* 103 */ "multiselect_op ::= UNION", + /* 104 */ "multiselect_op ::= UNION ALL", + /* 105 */ "multiselect_op ::= INTERSECT", + /* 106 */ "multiselect_op ::= EXCEPT", + /* 107 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 108 */ "distinct ::= DISTINCT", + /* 109 */ "distinct ::= ALL", + /* 110 */ "distinct ::=", + /* 111 */ "sclp ::= selcollist COMMA", + /* 112 */ "sclp ::=", + /* 113 */ "selcollist ::= sclp expr as", + /* 114 */ "selcollist ::= sclp STAR", + /* 115 */ "selcollist ::= sclp nm DOT STAR", + /* 116 */ "as ::= AS nm", + /* 117 */ "as ::= ids", + /* 118 */ "as ::=", + /* 119 */ "from ::=", + /* 120 */ "from ::= FROM seltablist", + /* 121 */ "stl_prefix ::= seltablist joinop", + /* 122 */ "stl_prefix ::=", + /* 123 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt", + /* 124 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt", + /* 125 */ "seltablist_paren ::= select", + /* 126 */ "seltablist_paren ::= seltablist", + /* 127 */ "dbnm ::=", + /* 128 */ "dbnm ::= DOT nm", + /* 129 */ "fullname ::= nm dbnm", + /* 130 */ "joinop ::= COMMA", + /* 131 */ "joinop ::= JOIN", + /* 132 */ "joinop ::= JOIN_KW JOIN", + /* 133 */ "joinop ::= JOIN_KW nm JOIN", + /* 134 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 135 */ "on_opt ::= ON expr", + /* 136 */ "on_opt ::=", + /* 137 */ "using_opt ::= USING LP inscollist RP", + /* 138 */ "using_opt ::=", + /* 139 */ "orderby_opt ::=", + /* 140 */ "orderby_opt ::= ORDER BY sortlist", + /* 141 */ "sortlist ::= sortlist COMMA sortitem collate sortorder", + /* 142 */ "sortlist ::= sortitem collate sortorder", + /* 143 */ "sortitem ::= expr", + /* 144 */ "sortorder ::= ASC", + /* 145 */ "sortorder ::= DESC", + /* 146 */ "sortorder ::=", + /* 147 */ "collate ::=", + /* 148 */ "collate ::= COLLATE id", + /* 149 */ "groupby_opt ::=", + /* 150 */ "groupby_opt ::= GROUP BY exprlist", + /* 151 */ "having_opt ::=", + /* 152 */ "having_opt ::= HAVING expr", + /* 153 */ "limit_opt ::=", + /* 154 */ "limit_opt ::= LIMIT expr", + /* 155 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 156 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 157 */ "cmd ::= DELETE FROM fullname where_opt", + /* 158 */ "where_opt ::=", + /* 159 */ "where_opt ::= WHERE expr", + /* 160 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", + /* 161 */ "setlist ::= setlist COMMA nm EQ expr", + /* 162 */ "setlist ::= nm EQ expr", + /* 163 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", + /* 164 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", + /* 165 */ "insert_cmd ::= INSERT orconf", + /* 166 */ "insert_cmd ::= REPLACE", + /* 167 */ "itemlist ::= itemlist COMMA expr", + /* 168 */ "itemlist ::= expr", + /* 169 */ "inscollist_opt ::=", + /* 170 */ "inscollist_opt ::= LP inscollist RP", + /* 171 */ "inscollist ::= inscollist COMMA nm", + /* 172 */ "inscollist ::= nm", + /* 173 */ "expr ::= term", + /* 174 */ "expr ::= LP expr RP", + /* 175 */ "term ::= NULL", + /* 176 */ "expr ::= ID", + /* 177 */ "expr ::= JOIN_KW", + /* 178 */ "expr ::= nm DOT nm", + /* 179 */ "expr ::= nm DOT nm DOT nm", + /* 180 */ "term ::= INTEGER", + /* 181 */ "term ::= FLOAT", + /* 182 */ "term ::= STRING", + /* 183 */ "term ::= BLOB", + /* 184 */ "expr ::= REGISTER", + /* 185 */ "expr ::= VARIABLE", + /* 186 */ "expr ::= CAST LP expr AS typetoken RP", + /* 187 */ "expr ::= ID LP exprlist RP", + /* 188 */ "expr ::= ID LP STAR RP", + /* 189 */ "term ::= CTIME_KW", + /* 190 */ "expr ::= expr AND expr", + /* 191 */ "expr ::= expr OR expr", + /* 192 */ "expr ::= expr LT expr", + /* 193 */ "expr ::= expr GT expr", + /* 194 */ "expr ::= expr LE expr", + /* 195 */ "expr ::= expr GE expr", + /* 196 */ "expr ::= expr NE expr", + /* 197 */ "expr ::= expr EQ expr", + /* 198 */ "expr ::= expr BITAND expr", + /* 199 */ "expr ::= expr BITOR expr", + /* 200 */ "expr ::= expr LSHIFT expr", + /* 201 */ "expr ::= expr RSHIFT expr", + /* 202 */ "expr ::= expr PLUS expr", + /* 203 */ "expr ::= expr MINUS expr", + /* 204 */ "expr ::= expr STAR expr", + /* 205 */ "expr ::= expr SLASH expr", + /* 206 */ "expr ::= expr REM expr", + /* 207 */ "expr ::= expr CONCAT expr", + /* 208 */ "likeop ::= LIKE_KW", + /* 209 */ "likeop ::= NOT LIKE_KW", + /* 210 */ "escape ::= ESCAPE expr", + /* 211 */ "escape ::=", + /* 212 */ "expr ::= expr likeop expr escape", + /* 213 */ "expr ::= expr ISNULL", + /* 214 */ "expr ::= expr IS NULL", + /* 215 */ "expr ::= expr NOTNULL", + /* 216 */ "expr ::= expr NOT NULL", + /* 217 */ "expr ::= expr IS NOT NULL", + /* 218 */ "expr ::= NOT expr", + /* 219 */ "expr ::= BITNOT expr", + /* 220 */ "expr ::= MINUS expr", + /* 221 */ "expr ::= PLUS expr", + /* 222 */ "between_op ::= BETWEEN", + /* 223 */ "between_op ::= NOT BETWEEN", + /* 224 */ "expr ::= expr between_op expr AND expr", + /* 225 */ "in_op ::= IN", + /* 226 */ "in_op ::= NOT IN", + /* 227 */ "expr ::= expr in_op LP exprlist RP", + /* 228 */ "expr ::= LP select RP", + /* 229 */ "expr ::= expr in_op LP select RP", + /* 230 */ "expr ::= expr in_op nm dbnm", + /* 231 */ "expr ::= EXISTS LP select RP", + /* 232 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 233 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 234 */ "case_exprlist ::= WHEN expr THEN expr", + /* 235 */ "case_else ::= ELSE expr", + /* 236 */ "case_else ::=", + /* 237 */ "case_operand ::= expr", + /* 238 */ "case_operand ::=", + /* 239 */ "exprlist ::= exprlist COMMA expritem", + /* 240 */ "exprlist ::= expritem", + /* 241 */ "expritem ::= expr", + /* 242 */ "expritem ::=", + /* 243 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf", + /* 244 */ "uniqueflag ::= UNIQUE", + /* 245 */ "uniqueflag ::=", + /* 246 */ "idxlist_opt ::=", + /* 247 */ "idxlist_opt ::= LP idxlist RP", + /* 248 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", + /* 249 */ "idxlist ::= idxitem collate sortorder", + /* 250 */ "idxitem ::= nm", + /* 251 */ "cmd ::= DROP INDEX fullname", + /* 252 */ "cmd ::= VACUUM", + /* 253 */ "cmd ::= VACUUM nm", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ nm", + /* 255 */ "cmd ::= PRAGMA nm dbnm EQ ON", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", + /* 257 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 258 */ "cmd ::= PRAGMA nm dbnm LP nm RP", + /* 259 */ "cmd ::= PRAGMA nm dbnm", + /* 260 */ "plus_num ::= plus_opt number", + /* 261 */ "minus_num ::= MINUS number", + /* 262 */ "number ::= INTEGER", + /* 263 */ "number ::= FLOAT", + /* 264 */ "plus_opt ::= PLUS", + /* 265 */ "plus_opt ::=", + /* 266 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", + /* 267 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 268 */ "trigger_time ::= BEFORE", + /* 269 */ "trigger_time ::= AFTER", + /* 270 */ "trigger_time ::= INSTEAD OF", + /* 271 */ "trigger_time ::=", + /* 272 */ "trigger_event ::= DELETE", + /* 273 */ "trigger_event ::= INSERT", + /* 274 */ "trigger_event ::= UPDATE", + /* 275 */ "trigger_event ::= UPDATE OF inscollist", + /* 276 */ "foreach_clause ::=", + /* 277 */ "foreach_clause ::= FOR EACH ROW", + /* 278 */ "foreach_clause ::= FOR EACH STATEMENT", + /* 279 */ "when_clause ::=", + /* 280 */ "when_clause ::= WHEN expr", + /* 281 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", + /* 282 */ "trigger_cmd_list ::=", + /* 283 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", + /* 284 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", + /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", + /* 286 */ "trigger_cmd ::= DELETE FROM nm where_opt", + /* 287 */ "trigger_cmd ::= select", + /* 288 */ "expr ::= RAISE LP IGNORE RP", + /* 289 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 290 */ "raisetype ::= ROLLBACK", + /* 291 */ "raisetype ::= ABORT", + /* 292 */ "raisetype ::= FAIL", + /* 293 */ "cmd ::= DROP TRIGGER fullname", + /* 294 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", + /* 295 */ "key_opt ::=", + /* 296 */ "key_opt ::= KEY ids", + /* 297 */ "key_opt ::= KEY BLOB", + /* 298 */ "database_kw_opt ::= DATABASE", + /* 299 */ "database_kw_opt ::=", + /* 300 */ "cmd ::= DETACH database_kw_opt nm", + /* 301 */ "cmd ::= REINDEX", + /* 302 */ "cmd ::= REINDEX nm dbnm", + /* 303 */ "cmd ::= ANALYZE", + /* 304 */ "cmd ::= ANALYZE nm dbnm", + /* 305 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 306 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 307 */ "add_column_fullname ::= fullname", + /* 308 */ "kwcolumn_opt ::=", + /* 309 */ "kwcolumn_opt ::= COLUMNKW", }; #endif /* NDEBUG */ @@ -1291,72 +1318,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 157: - case 189: - case 206: -#line 334 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3SelectDelete((yypminor->yy459));} -#line 1301 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 159: + case 192: + case 209: +#line 369 "parse.y" +{sqlite3SelectDelete((yypminor->yy99));} +#line 1328 "parse.c" break; - case 170: + case 173: case 174: - case 194: - case 196: - case 204: - case 210: - case 224: -#line 593 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3ExprDelete((yypminor->yy2));} -#line 1312 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 175: - case 183: - case 192: - case 195: case 197: case 199: - case 209: - case 212: + case 207: case 213: - case 216: - case 222: -#line 812 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3ExprListDelete((yypminor->yy82));} -#line 1327 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 227: +#line 628 "parse.y" +{sqlite3ExprDelete((yypminor->yy44));} +#line 1339 "parse.c" break; - case 188: - case 193: - case 201: + case 178: + case 186: + case 195: + case 198: + case 200: case 202: -#line 463 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3SrcListDelete((yypminor->yy67));} -#line 1335 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 212: + case 215: + case 216: + case 219: + case 225: +#line 853 "parse.y" +{sqlite3ExprListDelete((yypminor->yy412));} +#line 1354 "parse.c" break; - case 198: -#line 525 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 191: + case 196: + case 204: + case 205: +#line 498 "parse.y" +{sqlite3SrcListDelete((yypminor->yy367));} +#line 1362 "parse.c" + break; + case 201: +#line 560 "parse.y" { - sqlite3ExprDelete((yypminor->yy244).pLimit); - sqlite3ExprDelete((yypminor->yy244).pOffset); + sqlite3ExprDelete((yypminor->yy112).pLimit); + sqlite3ExprDelete((yypminor->yy112).pOffset); } -#line 1343 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 1370 "parse.c" break; - case 205: case 208: - case 215: -#line 481 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3IdListDelete((yypminor->yy240));} -#line 1350 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 211: + case 218: +#line 516 "parse.y" +{sqlite3IdListDelete((yypminor->yy258));} +#line 1377 "parse.c" break; - case 230: - case 235: -#line 905 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DeleteTriggerStep((yypminor->yy347));} -#line 1356 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 233: + case 238: +#line 946 "parse.y" +{sqlite3DeleteTriggerStep((yypminor->yy203));} +#line 1383 "parse.c" break; - case 232: -#line 889 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3IdListDelete((yypminor->yy210).b);} -#line 1361 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 235: +#line 930 "parse.y" +{sqlite3IdListDelete((yypminor->yy234).b);} +#line 1388 "parse.c" break; default: break; /* If no destructor action specified: do nothing */ } @@ -1532,193 +1559,196 @@ 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[] = { - { 142, 1 }, - { 143, 2 }, - { 143, 1 }, - { 145, 1 }, { 144, 1 }, - { 144, 3 }, - { 147, 0 }, + { 145, 2 }, + { 145, 1 }, { 147, 1 }, + { 146, 1 }, { 146, 3 }, { 149, 0 }, { 149, 1 }, - { 149, 2 }, - { 148, 0 }, - { 148, 1 }, - { 148, 1 }, - { 148, 1 }, - { 146, 2 }, - { 146, 2 }, - { 146, 2 }, - { 146, 2 }, - { 151, 5 }, - { 153, 1 }, - { 153, 0 }, - { 152, 4 }, - { 152, 2 }, - { 155, 3 }, - { 155, 1 }, - { 158, 3 }, - { 159, 1 }, - { 162, 1 }, - { 163, 1 }, - { 163, 1 }, + { 148, 3 }, + { 151, 0 }, + { 151, 1 }, + { 151, 2 }, + { 150, 0 }, { 150, 1 }, { 150, 1 }, { 150, 1 }, - { 160, 0 }, - { 160, 1 }, - { 160, 4 }, - { 160, 6 }, + { 148, 2 }, + { 148, 2 }, + { 148, 2 }, + { 148, 2 }, + { 153, 5 }, + { 155, 1 }, + { 155, 0 }, + { 154, 4 }, + { 154, 2 }, + { 157, 3 }, + { 157, 1 }, + { 160, 3 }, + { 161, 1 }, { 164, 1 }, - { 164, 2 }, { 165, 1 }, { 165, 1 }, - { 161, 2 }, - { 161, 0 }, - { 168, 3 }, + { 152, 1 }, + { 152, 1 }, + { 152, 1 }, + { 162, 0 }, + { 162, 1 }, + { 166, 1 }, + { 166, 4 }, + { 166, 6 }, + { 167, 1 }, + { 167, 2 }, { 168, 1 }, - { 168, 2 }, - { 168, 3 }, - { 168, 3 }, - { 168, 2 }, - { 169, 2 }, - { 169, 3 }, - { 169, 5 }, - { 169, 2 }, - { 169, 5 }, - { 169, 4 }, - { 169, 1 }, - { 169, 2 }, - { 173, 0 }, - { 173, 1 }, - { 176, 0 }, - { 176, 2 }, - { 178, 2 }, - { 178, 3 }, - { 178, 3 }, - { 178, 3 }, - { 179, 2 }, + { 168, 1 }, + { 163, 2 }, + { 163, 0 }, + { 171, 3 }, + { 171, 1 }, + { 171, 2 }, + { 171, 4 }, + { 171, 3 }, + { 171, 3 }, + { 171, 2 }, + { 172, 2 }, + { 172, 3 }, + { 172, 5 }, + { 172, 2 }, + { 172, 5 }, + { 172, 4 }, + { 172, 1 }, + { 172, 2 }, + { 177, 0 }, + { 177, 1 }, + { 179, 0 }, { 179, 2 }, - { 179, 1 }, - { 179, 1 }, - { 177, 3 }, - { 177, 2 }, - { 180, 0 }, - { 180, 2 }, - { 180, 2 }, - { 156, 0 }, - { 156, 2 }, - { 181, 3 }, { 181, 2 }, - { 181, 1 }, + { 181, 3 }, + { 181, 3 }, + { 181, 3 }, + { 182, 2 }, { 182, 2 }, - { 182, 7 }, - { 182, 5 }, - { 182, 3 }, - { 182, 10 }, - { 184, 0 }, + { 182, 1 }, + { 182, 1 }, + { 180, 3 }, + { 180, 2 }, + { 183, 0 }, + { 183, 2 }, + { 183, 2 }, + { 158, 0 }, + { 158, 2 }, + { 184, 3 }, + { 184, 2 }, { 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, 1 }, - { 190, 1 }, - { 189, 9 }, - { 191, 1 }, - { 191, 1 }, - { 191, 0 }, - { 199, 2 }, - { 199, 0 }, - { 192, 3 }, - { 192, 2 }, - { 192, 4 }, - { 200, 2 }, - { 200, 1 }, - { 200, 0 }, - { 193, 0 }, + { 185, 7 }, + { 185, 5 }, + { 185, 3 }, + { 185, 10 }, + { 187, 0 }, + { 187, 1 }, + { 175, 0 }, + { 175, 3 }, + { 188, 0 }, + { 188, 2 }, + { 189, 1 }, + { 189, 1 }, + { 189, 1 }, + { 148, 3 }, + { 148, 7 }, + { 148, 3 }, + { 148, 1 }, + { 159, 1 }, + { 159, 3 }, + { 193, 1 }, { 193, 2 }, + { 193, 1 }, + { 193, 1 }, + { 192, 9 }, + { 194, 1 }, + { 194, 1 }, + { 194, 0 }, { 202, 2 }, { 202, 0 }, - { 201, 6 }, - { 201, 7 }, - { 206, 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 }, - { 172, 1 }, - { 172, 1 }, - { 172, 0 }, - { 211, 0 }, - { 211, 2 }, - { 195, 0 }, { 195, 3 }, + { 195, 2 }, + { 195, 4 }, + { 203, 2 }, + { 203, 1 }, + { 203, 0 }, { 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 }, + { 205, 2 }, + { 205, 0 }, + { 204, 6 }, + { 204, 7 }, + { 209, 1 }, + { 209, 1 }, + { 156, 0 }, + { 156, 2 }, + { 191, 2 }, + { 206, 1 }, + { 206, 1 }, + { 206, 2 }, + { 206, 3 }, + { 206, 4 }, + { 207, 2 }, + { 207, 0 }, + { 208, 4 }, + { 208, 0 }, + { 200, 0 }, + { 200, 3 }, + { 212, 5 }, + { 212, 3 }, + { 213, 1 }, + { 176, 1 }, + { 176, 1 }, + { 176, 0 }, + { 214, 0 }, { 214, 2 }, - { 214, 1 }, + { 198, 0 }, + { 198, 3 }, + { 199, 0 }, + { 199, 2 }, + { 201, 0 }, + { 201, 2 }, + { 201, 4 }, + { 201, 4 }, + { 148, 4 }, + { 197, 0 }, + { 197, 2 }, + { 148, 6 }, + { 216, 5 }, { 216, 3 }, - { 216, 1 }, - { 215, 0 }, - { 215, 3 }, - { 208, 3 }, - { 208, 1 }, + { 148, 8 }, + { 148, 5 }, + { 217, 2 }, + { 217, 1 }, + { 219, 3 }, + { 219, 1 }, + { 218, 0 }, + { 218, 3 }, + { 211, 3 }, + { 211, 1 }, { 174, 1 }, { 174, 3 }, - { 170, 1 }, + { 173, 1 }, { 174, 1 }, { 174, 1 }, { 174, 3 }, { 174, 5 }, - { 170, 1 }, - { 170, 1 }, - { 170, 1 }, - { 170, 1 }, + { 173, 1 }, + { 173, 1 }, + { 173, 1 }, + { 173, 1 }, { 174, 1 }, { 174, 1 }, + { 174, 6 }, { 174, 4 }, { 174, 4 }, - { 170, 1 }, + { 173, 1 }, { 174, 3 }, { 174, 3 }, { 174, 3 }, @@ -1737,10 +1767,10 @@ static const struct { { 174, 3 }, { 174, 3 }, { 174, 3 }, - { 217, 1 }, - { 217, 2 }, - { 218, 2 }, - { 218, 0 }, + { 220, 1 }, + { 220, 2 }, + { 221, 2 }, + { 221, 0 }, { 174, 4 }, { 174, 2 }, { 174, 3 }, @@ -1751,92 +1781,94 @@ static const struct { { 174, 2 }, { 174, 2 }, { 174, 2 }, - { 219, 1 }, - { 219, 2 }, + { 222, 1 }, + { 222, 2 }, { 174, 5 }, - { 220, 1 }, - { 220, 2 }, + { 223, 1 }, + { 223, 2 }, { 174, 5 }, { 174, 3 }, { 174, 5 }, { 174, 4 }, { 174, 4 }, { 174, 5 }, - { 222, 5 }, - { 222, 4 }, - { 223, 2 }, - { 223, 0 }, - { 221, 1 }, - { 221, 0 }, - { 212, 3 }, - { 212, 1 }, + { 225, 5 }, + { 225, 4 }, + { 226, 2 }, + { 226, 0 }, { 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 }, + { 215, 3 }, + { 215, 1 }, { 227, 1 }, { 227, 0 }, - { 146, 5 }, - { 229, 10 }, + { 148, 11 }, + { 228, 1 }, + { 228, 0 }, + { 178, 0 }, + { 178, 3 }, + { 186, 5 }, + { 186, 3 }, + { 229, 1 }, + { 148, 3 }, + { 148, 1 }, + { 148, 2 }, + { 148, 5 }, + { 148, 5 }, + { 148, 5 }, + { 148, 5 }, + { 148, 6 }, + { 148, 3 }, + { 169, 2 }, + { 170, 2 }, { 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, 1 }, { 230, 0 }, - { 235, 6 }, - { 235, 8 }, - { 235, 5 }, - { 235, 4 }, + { 148, 5 }, + { 232, 10 }, + { 234, 1 }, + { 234, 1 }, + { 234, 2 }, + { 234, 0 }, { 235, 1 }, - { 174, 4 }, - { 174, 6 }, - { 187, 1 }, - { 187, 1 }, - { 187, 1 }, - { 146, 3 }, - { 146, 6 }, + { 235, 1 }, + { 235, 1 }, + { 235, 3 }, + { 236, 0 }, + { 236, 3 }, + { 236, 3 }, { 237, 0 }, { 237, 2 }, - { 237, 2 }, - { 236, 1 }, - { 236, 0 }, - { 146, 3 }, - { 146, 1 }, - { 146, 3 }, - { 146, 6 }, - { 146, 6 }, + { 233, 3 }, + { 233, 0 }, + { 238, 6 }, + { 238, 8 }, + { 238, 5 }, + { 238, 4 }, { 238, 1 }, - { 239, 0 }, + { 174, 4 }, + { 174, 6 }, + { 190, 1 }, + { 190, 1 }, + { 190, 1 }, + { 148, 3 }, + { 148, 6 }, + { 240, 0 }, + { 240, 2 }, + { 240, 2 }, { 239, 1 }, + { 239, 0 }, + { 148, 3 }, + { 148, 1 }, + { 148, 3 }, + { 148, 1 }, + { 148, 3 }, + { 148, 6 }, + { 148, 6 }, + { 241, 1 }, + { 242, 0 }, + { 242, 1 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -1886,111 +1918,111 @@ static void yy_reduce( ** break; */ case 3: -#line 84 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 102 "parse.y" { sqlite3FinishCoding(pParse); } -#line 1893 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 1925 "parse.c" break; case 6: -#line 87 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 105 "parse.y" { sqlite3BeginParse(pParse, 0); } -#line 1898 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 1930 "parse.c" break; case 7: -#line 89 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 107 "parse.y" { sqlite3BeginParse(pParse, 1); } -#line 1903 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 1935 "parse.c" break; case 8: -#line 95 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy412);} -#line 1908 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 113 "parse.y" +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy58);} +#line 1940 "parse.c" break; case 12: -#line 100 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = TK_DEFERRED;} -#line 1913 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 118 "parse.y" +{yygotominor.yy58 = TK_DEFERRED;} +#line 1945 "parse.c" break; case 13: case 14: case 15: - case 101: case 103: - case 104: -#line 101 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = yymsp[0].major;} -#line 1923 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 105: + case 106: +#line 119 "parse.y" +{yygotominor.yy58 = yymsp[0].major;} +#line 1955 "parse.c" break; case 16: case 17: -#line 104 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 122 "parse.y" {sqlite3CommitTransaction(pParse);} -#line 1929 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 1961 "parse.c" break; case 18: -#line 106 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 124 "parse.y" {sqlite3RollbackTransaction(pParse);} -#line 1934 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 1966 "parse.c" break; case 20: -#line 111 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 129 "parse.y" { - sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258,yymsp[-3].minor.yy412,0); + sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy144,&yymsp[0].minor.yy144,yymsp[-3].minor.yy58,0); } -#line 1941 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 1973 "parse.c" break; case 21: - case 60: - case 74: - case 106: - case 220: + case 62: + case 76: + case 108: case 223: -#line 116 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = 1;} -#line 1951 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 226: +#line 134 "parse.y" +{yygotominor.yy58 = 1;} +#line 1983 "parse.c" break; case 22: - case 59: - case 73: + case 61: case 75: - case 86: - case 107: - case 108: - case 219: + case 77: + case 88: + case 109: + case 110: case 222: -#line 118 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = 0;} -#line 1964 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 225: +#line 136 "parse.y" +{yygotominor.yy58 = 0;} +#line 1996 "parse.c" break; case 23: -#line 119 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 137 "parse.y" { - sqlite3EndTable(pParse,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy0,0); + sqlite3EndTable(pParse,&yymsp[-1].minor.yy144,&yymsp[0].minor.yy0,0); } -#line 1971 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2003 "parse.c" break; case 24: -#line 122 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 140 "parse.y" { - sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy459); - sqlite3SelectDelete(yymsp[0].minor.yy459); + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy99); + sqlite3SelectDelete(yymsp[0].minor.yy99); } -#line 1979 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2011 "parse.c" break; case 27: -#line 133 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 152 "parse.y" { - yygotominor.yy258.z = yymsp[-2].minor.yy258.z; - yygotominor.yy258.n = (pParse->sLastToken.z-yymsp[-2].minor.yy258.z) + pParse->sLastToken.n; + yygotominor.yy144.z = yymsp[-2].minor.yy144.z; + yygotominor.yy144.n = (pParse->sLastToken.z-yymsp[-2].minor.yy144.z) + pParse->sLastToken.n; } -#line 1987 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2019 "parse.c" break; case 28: -#line 137 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 156 "parse.y" { - sqlite3AddColumn(pParse,&yymsp[0].minor.yy258); - yygotominor.yy258 = yymsp[0].minor.yy258; + sqlite3AddColumn(pParse,&yymsp[0].minor.yy144); + yygotominor.yy144 = yymsp[0].minor.yy144; } -#line 1995 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2027 "parse.c" break; case 29: case 30: @@ -1998,640 +2030,657 @@ static void yy_reduce( case 32: case 33: case 34: - case 259: - case 260: -#line 147 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = yymsp[0].minor.yy0;} -#line 2007 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 262: + case 263: +#line 166 "parse.y" +{yygotominor.yy144 = yymsp[0].minor.yy0;} +#line 2039 "parse.c" break; case 36: -#line 202 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy258,&yymsp[0].minor.yy258);} -#line 2012 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 226 "parse.y" +{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy144);} +#line 2044 "parse.c" break; case 37: -#line 203 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy258,&yymsp[0].minor.yy0);} -#line 2017 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 40: + case 116: + case 117: + case 128: + case 148: + case 250: + case 260: + case 261: +#line 227 "parse.y" +{yygotominor.yy144 = yymsp[0].minor.yy144;} +#line 2057 "parse.c" break; case 38: -#line 205 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy258,&yymsp[0].minor.yy0);} -#line 2022 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 228 "parse.y" +{ + yygotominor.yy144.z = yymsp[-3].minor.yy144.z; + yygotominor.yy144.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy144.z; +} +#line 2065 "parse.c" break; case 39: - case 114: - case 115: - case 126: - case 146: - case 247: - case 257: - case 258: -#line 207 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = yymsp[0].minor.yy258;} -#line 2034 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 40: -#line 208 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258.z=yymsp[-1].minor.yy258.z; yygotominor.yy258.n=yymsp[0].minor.yy258.n+(yymsp[0].minor.yy258.z-yymsp[-1].minor.yy258.z);} -#line 2039 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 232 "parse.y" +{ + yygotominor.yy144.z = yymsp[-5].minor.yy144.z; + yygotominor.yy144.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy144.z; +} +#line 2073 "parse.c" break; case 41: -#line 210 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = atoi(yymsp[0].minor.yy258.z); } -#line 2044 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 238 "parse.y" +{yygotominor.yy144.z=yymsp[-1].minor.yy144.z; yygotominor.yy144.n=yymsp[0].minor.yy144.n+(yymsp[0].minor.yy144.z-yymsp[-1].minor.yy144.z);} +#line 2078 "parse.c" break; case 42: -#line 211 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = -atoi(yymsp[0].minor.yy258.z); } -#line 2049 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 240 "parse.y" +{ yygotominor.yy58 = atoi(yymsp[0].minor.yy144.z); } +#line 2083 "parse.c" + break; + case 43: +#line 241 "parse.y" +{ yygotominor.yy58 = -atoi(yymsp[0].minor.yy144.z); } +#line 2088 "parse.c" break; - case 47: case 48: -#line 216 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy2);} -#line 2055 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 50: +#line 250 "parse.y" +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy44);} +#line 2094 "parse.c" break; case 49: -#line 218 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 251 "parse.y" +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy44);} +#line 2099 "parse.c" + break; + case 51: +#line 253 "parse.y" { - Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy2, 0, 0); + Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy44, 0, 0); sqlite3AddDefaultValue(pParse,p); } -#line 2063 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2107 "parse.c" break; - case 50: -#line 222 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 52: +#line 257 "parse.y" { - Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy258); + Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy144); sqlite3AddDefaultValue(pParse,p); } -#line 2071 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 52: -#line 231 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy412);} -#line 2076 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 53: -#line 233 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy412,yymsp[0].minor.yy412);} -#line 2081 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2115 "parse.c" break; case 54: -#line 234 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy412,0,0);} -#line 2086 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 266 "parse.y" +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy58);} +#line 2120 "parse.c" break; case 55: -#line 235 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3ExprDelete(yymsp[-2].minor.yy2);} -#line 2091 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 268 "parse.y" +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy58,yymsp[0].minor.yy58);} +#line 2125 "parse.c" break; case 56: -#line 237 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy258,yymsp[-1].minor.yy82,yymsp[0].minor.yy412);} -#line 2096 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 269 "parse.y" +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy58,0,0);} +#line 2130 "parse.c" break; case 57: -#line 238 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy412);} -#line 2101 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 270 "parse.y" +{sqlite3ExprDelete(yymsp[-2].minor.yy44);} +#line 2135 "parse.c" break; case 58: -#line 239 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddCollateType(pParse, yymsp[0].minor.yy258.z, yymsp[0].minor.yy258.n);} -#line 2106 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 272 "parse.y" +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy144,yymsp[-1].minor.yy412,yymsp[0].minor.yy58);} +#line 2140 "parse.c" break; - case 61: -#line 252 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = OE_Restrict * 0x010101; } -#line 2111 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 59: +#line 273 "parse.y" +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy58);} +#line 2145 "parse.c" break; - case 62: -#line 253 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = (yymsp[-1].minor.yy412 & yymsp[0].minor.yy47.mask) | yymsp[0].minor.yy47.value; } -#line 2116 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 60: +#line 274 "parse.y" +{sqlite3AddCollateType(pParse, yymsp[0].minor.yy144.z, yymsp[0].minor.yy144.n);} +#line 2150 "parse.c" break; case 63: -#line 255 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = 0; yygotominor.yy47.mask = 0x000000; } -#line 2121 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 287 "parse.y" +{ yygotominor.yy58 = OE_Restrict * 0x010101; } +#line 2155 "parse.c" break; case 64: -#line 256 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy412; yygotominor.yy47.mask = 0x0000ff; } -#line 2126 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 288 "parse.y" +{ yygotominor.yy58 = (yymsp[-1].minor.yy58 & yymsp[0].minor.yy35.mask) | yymsp[0].minor.yy35.value; } +#line 2160 "parse.c" break; case 65: -#line 257 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy412<<8; yygotominor.yy47.mask = 0x00ff00; } -#line 2131 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 290 "parse.y" +{ yygotominor.yy35.value = 0; yygotominor.yy35.mask = 0x000000; } +#line 2165 "parse.c" break; case 66: -#line 258 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy412<<16; yygotominor.yy47.mask = 0xff0000; } -#line 2136 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 291 "parse.y" +{ yygotominor.yy35.value = yymsp[0].minor.yy58; yygotominor.yy35.mask = 0x0000ff; } +#line 2170 "parse.c" break; case 67: -#line 260 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = OE_SetNull; } -#line 2141 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 292 "parse.y" +{ yygotominor.yy35.value = yymsp[0].minor.yy58<<8; yygotominor.yy35.mask = 0x00ff00; } +#line 2175 "parse.c" break; case 68: -#line 261 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = OE_SetDflt; } -#line 2146 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 293 "parse.y" +{ yygotominor.yy35.value = yymsp[0].minor.yy58<<16; yygotominor.yy35.mask = 0xff0000; } +#line 2180 "parse.c" break; case 69: -#line 262 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = OE_Cascade; } -#line 2151 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 295 "parse.y" +{ yygotominor.yy58 = OE_SetNull; } +#line 2185 "parse.c" break; case 70: -#line 263 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = OE_Restrict; } -#line 2156 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 296 "parse.y" +{ yygotominor.yy58 = OE_SetDflt; } +#line 2190 "parse.c" break; case 71: +#line 297 "parse.y" +{ yygotominor.yy58 = OE_Cascade; } +#line 2195 "parse.c" + break; case 72: - case 87: +#line 298 "parse.y" +{ yygotominor.yy58 = OE_Restrict; } +#line 2200 "parse.c" + break; + case 73: + case 74: case 89: case 91: - case 92: - case 163: -#line 265 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = yymsp[0].minor.yy412;} -#line 2167 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 76: -#line 275 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258.n = 0; yygotominor.yy258.z = 0;} -#line 2172 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 93: + case 94: + case 165: +#line 300 "parse.y" +{yygotominor.yy58 = yymsp[0].minor.yy58;} +#line 2211 "parse.c" break; - case 77: -#line 276 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258 = yymsp[-1].minor.yy0;} -#line 2177 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 78: +#line 310 "parse.y" +{yygotominor.yy144.n = 0; yygotominor.yy144.z = 0;} +#line 2216 "parse.c" break; - case 82: -#line 282 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy82,yymsp[0].minor.yy412,yymsp[-2].minor.yy412);} -#line 2182 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 79: +#line 311 "parse.y" +{yygotominor.yy144 = yymsp[-1].minor.yy0;} +#line 2221 "parse.c" break; - case 83: -#line 284 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy82,yymsp[0].minor.yy412,0,0);} -#line 2187 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 84: +#line 317 "parse.y" +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy412,yymsp[0].minor.yy58,yymsp[-2].minor.yy58);} +#line 2226 "parse.c" break; case 85: -#line 287 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 319 "parse.y" +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy412,yymsp[0].minor.yy58,0,0);} +#line 2231 "parse.c" + break; + case 87: +#line 322 "parse.y" { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy82, &yymsp[-3].minor.yy258, yymsp[-2].minor.yy82, yymsp[-1].minor.yy412); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy412); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy412, &yymsp[-3].minor.yy144, yymsp[-2].minor.yy412, yymsp[-1].minor.yy58); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy58); } -#line 2195 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2239 "parse.c" break; - case 88: case 90: -#line 301 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = OE_Default;} -#line 2201 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 93: -#line 306 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = OE_Ignore;} -#line 2206 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 94: - case 164: -#line 307 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = OE_Replace;} -#line 2212 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 92: +#line 336 "parse.y" +{yygotominor.yy58 = OE_Default;} +#line 2245 "parse.c" break; case 95: -#line 311 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy67, 0); -} -#line 2219 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 341 "parse.y" +{yygotominor.yy58 = OE_Ignore;} +#line 2250 "parse.c" break; case 96: -#line 318 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy258, &yymsp[-2].minor.yy258, yymsp[0].minor.yy459, yymsp[-5].minor.yy412); -} -#line 2226 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 166: +#line 342 "parse.y" +{yygotominor.yy58 = OE_Replace;} +#line 2256 "parse.c" break; case 97: -#line 321 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 346 "parse.y" { - sqlite3DropTable(pParse, yymsp[0].minor.yy67, 1); + sqlite3DropTable(pParse, yymsp[0].minor.yy367, 0); } -#line 2233 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2263 "parse.c" break; case 98: -#line 328 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 353 "parse.y" { - sqlite3Select(pParse, yymsp[0].minor.yy459, SRT_Callback, 0, 0, 0, 0, 0); - sqlite3SelectDelete(yymsp[0].minor.yy459); + sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy144, &yymsp[-2].minor.yy144, yymsp[0].minor.yy99, yymsp[-5].minor.yy58); } -#line 2241 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2270 "parse.c" break; case 99: - case 123: -#line 338 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy459 = yymsp[0].minor.yy459;} -#line 2247 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 356 "parse.y" +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy367, 1); +} +#line 2277 "parse.c" break; case 100: -#line 340 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 363 "parse.y" { - if( yymsp[0].minor.yy459 ){ - yymsp[0].minor.yy459->op = yymsp[-1].minor.yy412; - yymsp[0].minor.yy459->pPrior = yymsp[-2].minor.yy459; - } - yygotominor.yy459 = yymsp[0].minor.yy459; + sqlite3Select(pParse, yymsp[0].minor.yy99, SRT_Callback, 0, 0, 0, 0, 0); + sqlite3SelectDelete(yymsp[0].minor.yy99); } -#line 2258 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2285 "parse.c" break; - case 102: -#line 349 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = TK_ALL;} -#line 2263 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 101: + case 125: +#line 373 "parse.y" +{yygotominor.yy99 = yymsp[0].minor.yy99;} +#line 2291 "parse.c" break; - case 105: -#line 354 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 102: +#line 375 "parse.y" { - yygotominor.yy459 = sqlite3SelectNew(yymsp[-6].minor.yy82,yymsp[-5].minor.yy67,yymsp[-4].minor.yy2,yymsp[-3].minor.yy82,yymsp[-2].minor.yy2,yymsp[-1].minor.yy82,yymsp[-7].minor.yy412,yymsp[0].minor.yy244.pLimit,yymsp[0].minor.yy244.pOffset); + if( yymsp[0].minor.yy99 ){ + yymsp[0].minor.yy99->op = yymsp[-1].minor.yy58; + yymsp[0].minor.yy99->pPrior = yymsp[-2].minor.yy99; + } + yygotominor.yy99 = yymsp[0].minor.yy99; } -#line 2270 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2302 "parse.c" break; - case 109: - case 244: -#line 375 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy82 = yymsp[-1].minor.yy82;} -#line 2276 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 104: +#line 384 "parse.y" +{yygotominor.yy58 = TK_ALL;} +#line 2307 "parse.c" break; - case 110: - case 137: - case 147: - case 243: -#line 376 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy82 = 0;} -#line 2284 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 107: +#line 389 "parse.y" +{ + yygotominor.yy99 = sqlite3SelectNew(yymsp[-6].minor.yy412,yymsp[-5].minor.yy367,yymsp[-4].minor.yy44,yymsp[-3].minor.yy412,yymsp[-2].minor.yy44,yymsp[-1].minor.yy412,yymsp[-7].minor.yy58,yymsp[0].minor.yy112.pLimit,yymsp[0].minor.yy112.pOffset); +} +#line 2314 "parse.c" break; case 111: -#line 377 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 247: +#line 410 "parse.y" +{yygotominor.yy412 = yymsp[-1].minor.yy412;} +#line 2320 "parse.c" + break; + case 112: + case 139: + case 149: + case 246: +#line 411 "parse.y" +{yygotominor.yy412 = 0;} +#line 2328 "parse.c" + break; + case 113: +#line 412 "parse.y" { - yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-2].minor.yy82,yymsp[-1].minor.yy2,yymsp[0].minor.yy258.n?&yymsp[0].minor.yy258:0); + yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-2].minor.yy412,yymsp[-1].minor.yy44,yymsp[0].minor.yy144.n?&yymsp[0].minor.yy144:0); } -#line 2291 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2335 "parse.c" break; - case 112: -#line 380 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 114: +#line 415 "parse.y" { - yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-1].minor.yy82, sqlite3Expr(TK_ALL, 0, 0, 0), 0); + yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-1].minor.yy412, sqlite3Expr(TK_ALL, 0, 0, 0), 0); } -#line 2298 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2342 "parse.c" break; - case 113: -#line 383 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 115: +#line 418 "parse.y" { Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); - Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy258); - yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-3].minor.yy82, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); + Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy144); + yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-3].minor.yy412, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); } -#line 2307 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 116: -#line 395 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258.n = 0;} -#line 2312 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 117: -#line 407 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy67 = sqliteMalloc(sizeof(*yygotominor.yy67));} -#line 2317 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2351 "parse.c" break; case 118: -#line 408 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy67 = yymsp[0].minor.yy67;} -#line 2322 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 430 "parse.y" +{yygotominor.yy144.n = 0;} +#line 2356 "parse.c" break; case 119: -#line 413 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy67 = yymsp[-1].minor.yy67; - if( yygotominor.yy67 && yygotominor.yy67->nSrc>0 ) yygotominor.yy67->a[yygotominor.yy67->nSrc-1].jointype = yymsp[0].minor.yy412; -} -#line 2330 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 442 "parse.y" +{yygotominor.yy367 = sqliteMalloc(sizeof(*yygotominor.yy367));} +#line 2361 "parse.c" break; case 120: -#line 417 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy67 = 0;} -#line 2335 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 443 "parse.y" +{yygotominor.yy367 = yymsp[0].minor.yy367;} +#line 2366 "parse.c" break; case 121: -#line 418 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 448 "parse.y" { - yygotominor.yy67 = sqlite3SrcListAppend(yymsp[-5].minor.yy67,&yymsp[-4].minor.yy258,&yymsp[-3].minor.yy258); - if( yymsp[-2].minor.yy258.n ) sqlite3SrcListAddAlias(yygotominor.yy67,&yymsp[-2].minor.yy258); - if( yymsp[-1].minor.yy2 ){ - if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pOn = yymsp[-1].minor.yy2; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy2); } + yygotominor.yy367 = yymsp[-1].minor.yy367; + if( yygotominor.yy367 && yygotominor.yy367->nSrc>0 ) yygotominor.yy367->a[yygotominor.yy367->nSrc-1].jointype = yymsp[0].minor.yy58; +} +#line 2374 "parse.c" + break; + case 122: +#line 452 "parse.y" +{yygotominor.yy367 = 0;} +#line 2379 "parse.c" + break; + case 123: +#line 453 "parse.y" +{ + yygotominor.yy367 = sqlite3SrcListAppend(yymsp[-5].minor.yy367,&yymsp[-4].minor.yy144,&yymsp[-3].minor.yy144); + if( yymsp[-2].minor.yy144.n ) sqlite3SrcListAddAlias(yygotominor.yy367,&yymsp[-2].minor.yy144); + if( yymsp[-1].minor.yy44 ){ + if( yygotominor.yy367 && yygotominor.yy367->nSrc>1 ){ yygotominor.yy367->a[yygotominor.yy367->nSrc-2].pOn = yymsp[-1].minor.yy44; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy44); } } - if( yymsp[0].minor.yy240 ){ - if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pUsing = yymsp[0].minor.yy240; } - else { sqlite3IdListDelete(yymsp[0].minor.yy240); } + if( yymsp[0].minor.yy258 ){ + if( yygotominor.yy367 && yygotominor.yy367->nSrc>1 ){ yygotominor.yy367->a[yygotominor.yy367->nSrc-2].pUsing = yymsp[0].minor.yy258; } + else { sqlite3IdListDelete(yymsp[0].minor.yy258); } } } -#line 2351 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2395 "parse.c" break; - case 122: -#line 432 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy67 = sqlite3SrcListAppend(yymsp[-6].minor.yy67,0,0); - yygotominor.yy67->a[yygotominor.yy67->nSrc-1].pSelect = yymsp[-4].minor.yy459; - if( yymsp[-2].minor.yy258.n ) sqlite3SrcListAddAlias(yygotominor.yy67,&yymsp[-2].minor.yy258); - if( yymsp[-1].minor.yy2 ){ - if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pOn = yymsp[-1].minor.yy2; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy2); } + case 124: +#line 467 "parse.y" +{ + yygotominor.yy367 = sqlite3SrcListAppend(yymsp[-6].minor.yy367,0,0); + yygotominor.yy367->a[yygotominor.yy367->nSrc-1].pSelect = yymsp[-4].minor.yy99; + if( yymsp[-2].minor.yy144.n ) sqlite3SrcListAddAlias(yygotominor.yy367,&yymsp[-2].minor.yy144); + if( yymsp[-1].minor.yy44 ){ + if( yygotominor.yy367 && yygotominor.yy367->nSrc>1 ){ yygotominor.yy367->a[yygotominor.yy367->nSrc-2].pOn = yymsp[-1].minor.yy44; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy44); } } - if( yymsp[0].minor.yy240 ){ - if( yygotominor.yy67 && yygotominor.yy67->nSrc>1 ){ yygotominor.yy67->a[yygotominor.yy67->nSrc-2].pUsing = yymsp[0].minor.yy240; } - else { sqlite3IdListDelete(yymsp[0].minor.yy240); } + if( yymsp[0].minor.yy258 ){ + if( yygotominor.yy367 && yygotominor.yy367->nSrc>1 ){ yygotominor.yy367->a[yygotominor.yy367->nSrc-2].pUsing = yymsp[0].minor.yy258; } + else { sqlite3IdListDelete(yymsp[0].minor.yy258); } } } -#line 2368 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2412 "parse.c" break; - case 124: -#line 453 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 126: +#line 488 "parse.y" { - yygotominor.yy459 = sqlite3SelectNew(0,yymsp[0].minor.yy67,0,0,0,0,0,0,0); + yygotominor.yy99 = sqlite3SelectNew(0,yymsp[0].minor.yy367,0,0,0,0,0,0,0); } -#line 2375 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 125: -#line 459 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258.z=0; yygotominor.yy258.n=0;} -#line 2380 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2419 "parse.c" break; case 127: -#line 464 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy67 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258);} -#line 2385 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 494 "parse.y" +{yygotominor.yy144.z=0; yygotominor.yy144.n=0;} +#line 2424 "parse.c" break; - case 128: case 129: -#line 468 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = JT_INNER; } -#line 2391 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 499 "parse.y" +{yygotominor.yy367 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy144,&yymsp[0].minor.yy144);} +#line 2429 "parse.c" break; case 130: -#line 470 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } -#line 2396 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; case 131: -#line 471 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy258,0); } -#line 2401 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 503 "parse.y" +{ yygotominor.yy58 = JT_INNER; } +#line 2435 "parse.c" break; case 132: -#line 473 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy258,&yymsp[-1].minor.yy258); } -#line 2406 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 505 "parse.y" +{ yygotominor.yy58 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +#line 2440 "parse.c" break; case 133: - case 141: - case 150: - case 157: - case 171: - case 207: - case 232: - case 234: - case 238: -#line 477 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy2 = yymsp[0].minor.yy2;} -#line 2419 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 506 "parse.y" +{ yygotominor.yy58 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy144,0); } +#line 2445 "parse.c" break; case 134: - case 149: - case 156: - case 208: - case 233: - case 235: - case 239: -#line 478 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy2 = 0;} -#line 2430 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 508 "parse.y" +{ yygotominor.yy58 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy144,&yymsp[-1].minor.yy144); } +#line 2450 "parse.c" break; case 135: - case 168: -#line 482 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy240 = yymsp[-1].minor.yy240;} -#line 2436 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 143: + case 152: + case 159: + case 173: + case 210: + case 235: + case 237: + case 241: +#line 512 "parse.y" +{yygotominor.yy44 = yymsp[0].minor.yy44;} +#line 2463 "parse.c" break; case 136: - case 167: -#line 483 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy240 = 0;} -#line 2442 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 151: + case 158: + case 211: + case 236: + case 238: + case 242: +#line 513 "parse.y" +{yygotominor.yy44 = 0;} +#line 2474 "parse.c" + break; + case 137: + case 170: +#line 517 "parse.y" +{yygotominor.yy258 = yymsp[-1].minor.yy258;} +#line 2480 "parse.c" break; case 138: - case 148: -#line 494 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy82 = yymsp[0].minor.yy82;} -#line 2448 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 169: +#line 518 "parse.y" +{yygotominor.yy258 = 0;} +#line 2486 "parse.c" break; - case 139: -#line 495 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 140: + case 150: +#line 529 "parse.y" +{yygotominor.yy412 = yymsp[0].minor.yy412;} +#line 2492 "parse.c" + break; + case 141: +#line 530 "parse.y" { - yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82,yymsp[-2].minor.yy2,yymsp[-1].minor.yy258.n>0?&yymsp[-1].minor.yy258:0); - if( yygotominor.yy82 ) yygotominor.yy82->a[yygotominor.yy82->nExpr-1].sortOrder = yymsp[0].minor.yy412; + yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-4].minor.yy412,yymsp[-2].minor.yy44,yymsp[-1].minor.yy144.n>0?&yymsp[-1].minor.yy144:0); + if( yygotominor.yy412 ) yygotominor.yy412->a[yygotominor.yy412->nExpr-1].sortOrder = yymsp[0].minor.yy58; } -#line 2456 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2500 "parse.c" break; - case 140: -#line 499 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 142: +#line 534 "parse.y" { - yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy2,yymsp[-1].minor.yy258.n>0?&yymsp[-1].minor.yy258:0); - if( yygotominor.yy82 && yygotominor.yy82->a ) yygotominor.yy82->a[0].sortOrder = yymsp[0].minor.yy412; + yygotominor.yy412 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy44,yymsp[-1].minor.yy144.n>0?&yymsp[-1].minor.yy144:0); + if( yygotominor.yy412 && yygotominor.yy412->a ) yygotominor.yy412->a[0].sortOrder = yymsp[0].minor.yy58; } -#line 2464 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2508 "parse.c" break; - case 142: case 144: -#line 508 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = SQLITE_SO_ASC;} -#line 2470 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 143: -#line 509 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = SQLITE_SO_DESC;} -#line 2475 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 146: +#line 543 "parse.y" +{yygotominor.yy58 = SQLITE_SO_ASC;} +#line 2514 "parse.c" break; case 145: -#line 511 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy258.z = 0; yygotominor.yy258.n = 0;} -#line 2480 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 151: -#line 529 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy244.pLimit = 0; yygotominor.yy244.pOffset = 0;} -#line 2485 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 544 "parse.y" +{yygotominor.yy58 = SQLITE_SO_DESC;} +#line 2519 "parse.c" break; - case 152: -#line 530 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy244.pLimit = yymsp[0].minor.yy2; yygotominor.yy244.pOffset = 0;} -#line 2490 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 147: +#line 546 "parse.y" +{yygotominor.yy144.z = 0; yygotominor.yy144.n = 0;} +#line 2524 "parse.c" break; case 153: -#line 532 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy244.pLimit = yymsp[-2].minor.yy2; yygotominor.yy244.pOffset = yymsp[0].minor.yy2;} -#line 2495 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 564 "parse.y" +{yygotominor.yy112.pLimit = 0; yygotominor.yy112.pOffset = 0;} +#line 2529 "parse.c" break; case 154: -#line 534 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy244.pOffset = yymsp[-2].minor.yy2; yygotominor.yy244.pLimit = yymsp[0].minor.yy2;} -#line 2500 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 565 "parse.y" +{yygotominor.yy112.pLimit = yymsp[0].minor.yy44; yygotominor.yy112.pOffset = 0;} +#line 2534 "parse.c" break; case 155: -#line 538 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy67,yymsp[0].minor.yy2);} -#line 2505 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 567 "parse.y" +{yygotominor.yy112.pLimit = yymsp[-2].minor.yy44; yygotominor.yy112.pOffset = yymsp[0].minor.yy44;} +#line 2539 "parse.c" break; - case 158: -#line 549 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Update(pParse,yymsp[-3].minor.yy67,yymsp[-1].minor.yy82,yymsp[0].minor.yy2,yymsp[-4].minor.yy412);} -#line 2510 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 156: +#line 569 "parse.y" +{yygotominor.yy112.pOffset = yymsp[-2].minor.yy44; yygotominor.yy112.pLimit = yymsp[0].minor.yy44;} +#line 2544 "parse.c" break; - case 159: -#line 555 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82,yymsp[0].minor.yy2,&yymsp[-2].minor.yy258);} -#line 2515 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 157: +#line 573 "parse.y" +{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy367,yymsp[0].minor.yy44);} +#line 2549 "parse.c" break; case 160: -#line 556 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[0].minor.yy2,&yymsp[-2].minor.yy258);} -#line 2520 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 584 "parse.y" +{sqlite3Update(pParse,yymsp[-3].minor.yy367,yymsp[-1].minor.yy412,yymsp[0].minor.yy44,yymsp[-4].minor.yy58);} +#line 2554 "parse.c" break; case 161: -#line 562 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Insert(pParse, yymsp[-5].minor.yy67, yymsp[-1].minor.yy82, 0, yymsp[-4].minor.yy240, yymsp[-7].minor.yy412);} -#line 2525 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 590 "parse.y" +{yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-4].minor.yy412,yymsp[0].minor.yy44,&yymsp[-2].minor.yy144);} +#line 2559 "parse.c" break; case 162: -#line 564 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Insert(pParse, yymsp[-2].minor.yy67, 0, yymsp[0].minor.yy459, yymsp[-1].minor.yy240, yymsp[-4].minor.yy412);} -#line 2530 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 591 "parse.y" +{yygotominor.yy412 = sqlite3ExprListAppend(0,yymsp[0].minor.yy44,&yymsp[-2].minor.yy144);} +#line 2564 "parse.c" break; - case 165: - case 236: -#line 574 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-2].minor.yy82,yymsp[0].minor.yy2,0);} -#line 2536 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 163: +#line 597 "parse.y" +{sqlite3Insert(pParse, yymsp[-5].minor.yy367, yymsp[-1].minor.yy412, 0, yymsp[-4].minor.yy258, yymsp[-7].minor.yy58);} +#line 2569 "parse.c" break; - case 166: - case 237: -#line 575 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[0].minor.yy2,0);} -#line 2542 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 164: +#line 599 "parse.y" +{sqlite3Insert(pParse, yymsp[-2].minor.yy367, 0, yymsp[0].minor.yy99, yymsp[-1].minor.yy258, yymsp[-4].minor.yy58);} +#line 2574 "parse.c" break; - case 169: -#line 584 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy240 = sqlite3IdListAppend(yymsp[-2].minor.yy240,&yymsp[0].minor.yy258);} -#line 2547 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 167: + case 239: +#line 609 "parse.y" +{yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-2].minor.yy412,yymsp[0].minor.yy44,0);} +#line 2580 "parse.c" break; - case 170: -#line 585 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy240 = sqlite3IdListAppend(0,&yymsp[0].minor.yy258);} -#line 2552 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 168: + case 240: +#line 610 "parse.y" +{yygotominor.yy412 = sqlite3ExprListAppend(0,yymsp[0].minor.yy44,0);} +#line 2586 "parse.c" break; - case 172: -#line 596 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy2 = yymsp[-1].minor.yy2; sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2557 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 171: +#line 619 "parse.y" +{yygotominor.yy258 = sqlite3IdListAppend(yymsp[-2].minor.yy258,&yymsp[0].minor.yy144);} +#line 2591 "parse.c" break; - case 173: - case 178: - case 179: - case 180: - case 181: -#line 597 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy2 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} -#line 2566 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 172: +#line 620 "parse.y" +{yygotominor.yy258 = sqlite3IdListAppend(0,&yymsp[0].minor.yy144);} +#line 2596 "parse.c" break; case 174: +#line 631 "parse.y" +{yygotominor.yy44 = yymsp[-1].minor.yy44; sqlite3ExprSpan(yygotominor.yy44,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } +#line 2601 "parse.c" + break; case 175: -#line 598 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} -#line 2572 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 180: + case 181: + case 182: + case 183: +#line 632 "parse.y" +{yygotominor.yy44 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} +#line 2610 "parse.c" break; case 176: -#line 600 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 177: +#line 633 "parse.y" +{yygotominor.yy44 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} +#line 2616 "parse.c" + break; + case 178: +#line 635 "parse.y" { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy258); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy258); - yygotominor.yy2 = sqlite3Expr(TK_DOT, temp1, temp2, 0); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy144); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy144); + yygotominor.yy44 = sqlite3Expr(TK_DOT, temp1, temp2, 0); } -#line 2581 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2625 "parse.c" break; - case 177: -#line 605 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 179: +#line 640 "parse.y" { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy258); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy258); - Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy258); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy144); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy144); + Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy144); Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); - yygotominor.yy2 = sqlite3Expr(TK_DOT, temp1, temp4, 0); + yygotominor.yy44 = sqlite3Expr(TK_DOT, temp1, temp4, 0); } -#line 2592 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2636 "parse.c" break; - case 182: -#line 616 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy2 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} -#line 2597 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 184: +#line 651 "parse.y" +{yygotominor.yy44 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} +#line 2641 "parse.c" break; - case 183: -#line 617 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 185: +#line 652 "parse.y" { Token *pToken = &yymsp[0].minor.yy0; - Expr *pExpr = yygotominor.yy2 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); + Expr *pExpr = yygotominor.yy44 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); sqlite3ExprAssignVarNumber(pParse, pExpr); } -#line 2606 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2650 "parse.c" break; - case 184: -#line 622 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 186: +#line 658 "parse.y" { - yygotominor.yy2 = sqlite3ExprFunction(yymsp[-1].minor.yy82, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy44 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy44, 0, &yymsp[-1].minor.yy144); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); } -#line 2614 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2658 "parse.c" break; - case 185: -#line 626 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 187: +#line 663 "parse.y" { - yygotominor.yy2 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy44 = sqlite3ExprFunction(yymsp[-1].minor.yy412, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 2622 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2666 "parse.c" break; - case 186: -#line 630 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 188: +#line 667 "parse.y" +{ + yygotominor.yy44 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2674 "parse.c" + break; + case 189: +#line 671 "parse.y" { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ - yygotominor.yy2 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0); - if( yygotominor.yy2 ) yygotominor.yy2->op = TK_CONST_FUNC; + yygotominor.yy44 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0); + if( yygotominor.yy44 ) yygotominor.yy44->op = TK_CONST_FUNC; } -#line 2632 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2684 "parse.c" break; - case 187: - case 188: - case 189: case 190: case 191: case 192: @@ -2647,476 +2696,489 @@ static void yy_reduce( case 202: case 203: case 204: -#line 636 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy2 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy2, yymsp[0].minor.yy2, 0);} -#line 2654 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; case 205: -#line 655 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy438.operator = yymsp[0].minor.yy0; yygotominor.yy438.not = 0;} -#line 2659 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; case 206: -#line 656 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy438.operator = yymsp[0].minor.yy0; yygotominor.yy438.not = 1;} -#line 2664 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 209: -#line 660 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy2, 0); - pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy2, 0); - if( yymsp[0].minor.yy2 ){ - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy2, 0); - } - yygotominor.yy2 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy438.operator); - if( yymsp[-2].minor.yy438.not ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2, &yymsp[-3].minor.yy2->span, &yymsp[-1].minor.yy2->span); -} -#line 2678 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 207: +#line 677 "parse.y" +{yygotominor.yy44 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy44, yymsp[0].minor.yy44, 0);} +#line 2706 "parse.c" break; - case 210: -#line 671 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy2 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy2->span,&yymsp[0].minor.yy0); -} -#line 2686 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 208: +#line 696 "parse.y" +{yygotominor.yy432.operator = yymsp[0].minor.yy0; yygotominor.yy432.not = 0;} +#line 2711 "parse.c" break; - case 211: -#line 675 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy2 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy2->span,&yymsp[0].minor.yy0); -} -#line 2694 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 209: +#line 697 "parse.y" +{yygotominor.yy432.operator = yymsp[0].minor.yy0; yygotominor.yy432.not = 1;} +#line 2716 "parse.c" break; case 212: -#line 679 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 701 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy2->span,&yymsp[0].minor.yy0); + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy44, 0); + pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy44, 0); + if( yymsp[0].minor.yy44 ){ + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy44, 0); + } + yygotominor.yy44 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy432.operator); + if( yymsp[-2].minor.yy432.not ) yygotominor.yy44 = sqlite3Expr(TK_NOT, yygotominor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44, &yymsp[-3].minor.yy44->span, &yymsp[-1].minor.yy44->span); } -#line 2702 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2730 "parse.c" break; case 213: -#line 683 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 712 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy2->span,&yymsp[0].minor.yy0); + yygotominor.yy44 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-1].minor.yy44->span,&yymsp[0].minor.yy0); } -#line 2710 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2738 "parse.c" break; case 214: -#line 687 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 716 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy2->span,&yymsp[0].minor.yy0); + yygotominor.yy44 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-2].minor.yy44->span,&yymsp[0].minor.yy0); } -#line 2718 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2746 "parse.c" break; case 215: +#line 720 "parse.y" +{ + yygotominor.yy44 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-1].minor.yy44->span,&yymsp[0].minor.yy0); +} +#line 2754 "parse.c" + break; case 216: -#line 691 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 724 "parse.y" { - yygotominor.yy2 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy2->span); + yygotominor.yy44 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-2].minor.yy44->span,&yymsp[0].minor.yy0); } -#line 2727 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2762 "parse.c" break; case 217: -#line 699 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 728 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy2->span); + yygotominor.yy44 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-3].minor.yy44->span,&yymsp[0].minor.yy0); } -#line 2735 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2770 "parse.c" break; case 218: -#line 703 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 219: +#line 732 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy2->span); + yygotominor.yy44 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy44->span); } -#line 2743 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2779 "parse.c" + break; + case 220: +#line 740 "parse.y" +{ + yygotominor.yy44 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy44->span); +} +#line 2787 "parse.c" break; case 221: -#line 710 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 744 "parse.y" { - ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy2, 0); - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy2, 0); - yygotominor.yy2 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy2, 0, 0); - if( yygotominor.yy2 ) yygotominor.yy2->pList = pList; - if( yymsp[-3].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-4].minor.yy2->span,&yymsp[0].minor.yy2->span); + yygotominor.yy44 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy44->span); } -#line 2755 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2795 "parse.c" break; case 224: -#line 722 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 751 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy2, 0, 0); - if( yygotominor.yy2 ){ - yygotominor.yy2->pList = yymsp[-1].minor.yy82; + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy44, 0); + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy44, 0); + yygotominor.yy44 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy44, 0, 0); + if( yygotominor.yy44 ) yygotominor.yy44->pList = pList; + if( yymsp[-3].minor.yy58 ) yygotominor.yy44 = sqlite3Expr(TK_NOT, yygotominor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-4].minor.yy44->span,&yymsp[0].minor.yy44->span); +} +#line 2807 "parse.c" + break; + case 227: +#line 763 "parse.y" +{ + yygotominor.yy44 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy44, 0, 0); + if( yygotominor.yy44 ){ + yygotominor.yy44->pList = yymsp[-1].minor.yy412; }else{ - sqlite3ExprListDelete(yymsp[-1].minor.yy82); + sqlite3ExprListDelete(yymsp[-1].minor.yy412); } - if( yymsp[-3].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-4].minor.yy2->span,&yymsp[0].minor.yy0); + if( yymsp[-3].minor.yy58 ) yygotominor.yy44 = sqlite3Expr(TK_NOT, yygotominor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-4].minor.yy44->span,&yymsp[0].minor.yy0); } -#line 2769 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2821 "parse.c" break; - case 225: -#line 732 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 228: +#line 773 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( yygotominor.yy2 ) yygotominor.yy2->pSelect = yymsp[-1].minor.yy459; - if( !yygotominor.yy2 ) sqlite3SelectDelete(yymsp[-1].minor.yy459); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy44 = sqlite3Expr(TK_SELECT, 0, 0, 0); + if( yygotominor.yy44 ) yygotominor.yy44->pSelect = yymsp[-1].minor.yy99; + if( !yygotominor.yy44 ) sqlite3SelectDelete(yymsp[-1].minor.yy99); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2779 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2831 "parse.c" break; - case 226: -#line 738 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 229: +#line 779 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy2, 0, 0); - if( yygotominor.yy2 ) yygotominor.yy2->pSelect = yymsp[-1].minor.yy459; - if( !yygotominor.yy2 ) sqlite3SelectDelete(yymsp[-1].minor.yy459); - if( yymsp[-3].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-4].minor.yy2->span,&yymsp[0].minor.yy0); + yygotominor.yy44 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy44, 0, 0); + if( yygotominor.yy44 ) yygotominor.yy44->pSelect = yymsp[-1].minor.yy99; + if( !yygotominor.yy44 ) sqlite3SelectDelete(yymsp[-1].minor.yy99); + if( yymsp[-3].minor.yy58 ) yygotominor.yy44 = sqlite3Expr(TK_NOT, yygotominor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-4].minor.yy44->span,&yymsp[0].minor.yy0); } -#line 2790 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2842 "parse.c" break; - case 227: -#line 745 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 230: +#line 786 "parse.y" { - SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258); - yygotominor.yy2 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy2, 0, 0); - if( yygotominor.yy2 ) yygotominor.yy2->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); - if( yymsp[-2].minor.yy412 ) yygotominor.yy2 = sqlite3Expr(TK_NOT, yygotominor.yy2, 0, 0); - sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy2->span,yymsp[0].minor.yy258.z?&yymsp[0].minor.yy258:&yymsp[-1].minor.yy258); + SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy144,&yymsp[0].minor.yy144); + yygotominor.yy44 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy44, 0, 0); + if( yygotominor.yy44 ) yygotominor.yy44->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + if( yymsp[-2].minor.yy58 ) yygotominor.yy44 = sqlite3Expr(TK_NOT, yygotominor.yy44, 0, 0); + sqlite3ExprSpan(yygotominor.yy44,&yymsp[-3].minor.yy44->span,yymsp[0].minor.yy144.z?&yymsp[0].minor.yy144:&yymsp[-1].minor.yy144); } -#line 2801 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2853 "parse.c" break; - case 228: -#line 752 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 231: +#line 793 "parse.y" { - Expr *p = yygotominor.yy2 = sqlite3Expr(TK_EXISTS, 0, 0, 0); + Expr *p = yygotominor.yy44 = sqlite3Expr(TK_EXISTS, 0, 0, 0); if( p ){ - p->pSelect = yymsp[-1].minor.yy459; + p->pSelect = yymsp[-1].minor.yy99; sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } - if( !p ) sqlite3SelectDelete(yymsp[-1].minor.yy459); + if( !p ) sqlite3SelectDelete(yymsp[-1].minor.yy99); } -#line 2813 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2865 "parse.c" break; - case 229: -#line 763 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 232: +#line 804 "parse.y" { - yygotominor.yy2 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy2, yymsp[-1].minor.yy2, 0); - if( yygotominor.yy2 ) yygotominor.yy2->pList = yymsp[-2].minor.yy82; - sqlite3ExprSpan(yygotominor.yy2, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy44 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy44, yymsp[-1].minor.yy44, 0); + if( yygotominor.yy44 ) yygotominor.yy44->pList = yymsp[-2].minor.yy412; + sqlite3ExprSpan(yygotominor.yy44, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); } -#line 2822 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2874 "parse.c" break; - case 230: -#line 770 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 233: +#line 811 "parse.y" { - yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82, yymsp[-2].minor.yy2, 0); - yygotominor.yy82 = sqlite3ExprListAppend(yygotominor.yy82, yymsp[0].minor.yy2, 0); + yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-4].minor.yy412, yymsp[-2].minor.yy44, 0); + yygotominor.yy412 = sqlite3ExprListAppend(yygotominor.yy412, yymsp[0].minor.yy44, 0); } -#line 2830 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2882 "parse.c" break; - case 231: -#line 774 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 234: +#line 815 "parse.y" { - yygotominor.yy82 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy2, 0); - yygotominor.yy82 = sqlite3ExprListAppend(yygotominor.yy82, yymsp[0].minor.yy2, 0); + yygotominor.yy412 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy44, 0); + yygotominor.yy412 = sqlite3ExprListAppend(yygotominor.yy412, yymsp[0].minor.yy44, 0); } -#line 2838 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2890 "parse.c" break; - case 240: -#line 799 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 243: +#line 840 "parse.y" { - if( yymsp[-9].minor.yy412!=OE_None ) yymsp[-9].minor.yy412 = yymsp[0].minor.yy412; - if( yymsp[-9].minor.yy412==OE_Default) yymsp[-9].minor.yy412 = OE_Abort; - sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy258, &yymsp[-6].minor.yy258, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy258,0),yymsp[-2].minor.yy82,yymsp[-9].minor.yy412, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); + if( yymsp[-9].minor.yy58!=OE_None ) yymsp[-9].minor.yy58 = yymsp[0].minor.yy58; + if( yymsp[-9].minor.yy58==OE_Default) yymsp[-9].minor.yy58 = OE_Abort; + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy144, &yymsp[-6].minor.yy144, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy144,0),yymsp[-2].minor.yy412,yymsp[-9].minor.yy58, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); } -#line 2847 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2899 "parse.c" break; - case 241: - case 288: -#line 806 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = OE_Abort;} -#line 2853 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 242: -#line 807 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = OE_None;} -#line 2858 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 244: + case 291: +#line 847 "parse.y" +{yygotominor.yy58 = OE_Abort;} +#line 2905 "parse.c" break; case 245: -#line 817 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 848 "parse.y" +{yygotominor.yy58 = OE_None;} +#line 2910 "parse.c" + break; + case 248: +#line 858 "parse.y" { Expr *p = 0; - if( yymsp[-1].minor.yy258.n>0 ){ + if( yymsp[-1].minor.yy144.n>0 ){ p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy258.z, yymsp[-1].minor.yy258.n); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy144.z, yymsp[-1].minor.yy144.n); } - yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82, p, &yymsp[-2].minor.yy258); + yygotominor.yy412 = sqlite3ExprListAppend(yymsp[-4].minor.yy412, p, &yymsp[-2].minor.yy144); } -#line 2870 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2922 "parse.c" break; - case 246: -#line 825 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 249: +#line 866 "parse.y" { Expr *p = 0; - if( yymsp[-1].minor.yy258.n>0 ){ + if( yymsp[-1].minor.yy144.n>0 ){ p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy258.z, yymsp[-1].minor.yy258.n); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy144.z, yymsp[-1].minor.yy144.n); } - yygotominor.yy82 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy258); + yygotominor.yy412 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy144); } -#line 2882 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 248: -#line 838 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3DropIndex(pParse, yymsp[0].minor.yy67);} -#line 2887 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 249: - case 250: -#line 842 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Vacuum(pParse,0);} -#line 2893 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2934 "parse.c" break; case 251: - case 253: -#line 848 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy258,0);} -#line 2899 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 879 "parse.y" +{sqlite3DropIndex(pParse, yymsp[0].minor.yy367);} +#line 2939 "parse.c" break; case 252: -#line 849 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy0,0);} -#line 2904 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 253: +#line 883 "parse.y" +{sqlite3Vacuum(pParse,0);} +#line 2945 "parse.c" break; case 254: -#line 851 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 256: +#line 889 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy144,&yymsp[-2].minor.yy144,&yymsp[0].minor.yy144,0);} +#line 2951 "parse.c" + break; + case 255: +#line 890 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy144,&yymsp[-2].minor.yy144,&yymsp[0].minor.yy0,0);} +#line 2956 "parse.c" + break; + case 257: +#line 892 "parse.y" { - sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy258,1); + sqlite3Pragma(pParse,&yymsp[-3].minor.yy144,&yymsp[-2].minor.yy144,&yymsp[0].minor.yy144,1); } -#line 2911 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2963 "parse.c" break; - case 255: -#line 854 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy258,&yymsp[-3].minor.yy258,&yymsp[-1].minor.yy258,0);} -#line 2916 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 258: +#line 895 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy144,&yymsp[-3].minor.yy144,&yymsp[-1].minor.yy144,0);} +#line 2968 "parse.c" break; - case 256: -#line 855 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Pragma(pParse,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258,0,0);} -#line 2921 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 259: +#line 896 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy144,&yymsp[0].minor.yy144,0,0);} +#line 2973 "parse.c" break; - case 263: -#line 868 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 266: +#line 909 "parse.y" { Token all; - all.z = yymsp[-3].minor.yy258.z; - all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy258.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy347, &all); + all.z = yymsp[-3].minor.yy144.z; + all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy144.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all); } -#line 2931 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2983 "parse.c" break; - case 264: -#line 877 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 267: +#line 918 "parse.y" { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy258, &yymsp[-6].minor.yy258, yymsp[-5].minor.yy412, yymsp[-4].minor.yy210.a, yymsp[-4].minor.yy210.b, yymsp[-2].minor.yy67, yymsp[-1].minor.yy412, yymsp[0].minor.yy2, yymsp[-9].minor.yy412); - yygotominor.yy258 = (yymsp[-6].minor.yy258.n==0?yymsp[-7].minor.yy258:yymsp[-6].minor.yy258); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy144, &yymsp[-6].minor.yy144, yymsp[-5].minor.yy58, yymsp[-4].minor.yy234.a, yymsp[-4].minor.yy234.b, yymsp[-2].minor.yy367, yymsp[-1].minor.yy58, yymsp[0].minor.yy44, yymsp[-9].minor.yy58); + yygotominor.yy144 = (yymsp[-6].minor.yy144.n==0?yymsp[-7].minor.yy144:yymsp[-6].minor.yy144); } -#line 2939 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 2991 "parse.c" break; - case 265: case 268: -#line 883 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = TK_BEFORE; } -#line 2945 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 266: -#line 884 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = TK_AFTER; } -#line 2950 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 267: -#line 885 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = TK_INSTEAD;} -#line 2955 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 271: +#line 924 "parse.y" +{ yygotominor.yy58 = TK_BEFORE; } +#line 2997 "parse.c" break; case 269: +#line 925 "parse.y" +{ yygotominor.yy58 = TK_AFTER; } +#line 3002 "parse.c" + break; case 270: - case 271: -#line 890 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210.a = yymsp[0].major; yygotominor.yy210.b = 0;} -#line 2962 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 926 "parse.y" +{ yygotominor.yy58 = TK_INSTEAD;} +#line 3007 "parse.c" break; case 272: -#line 893 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy210.a = TK_UPDATE; yygotominor.yy210.b = yymsp[0].minor.yy240;} -#line 2967 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; case 273: case 274: -#line 896 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = TK_ROW; } -#line 2973 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 931 "parse.y" +{yygotominor.yy234.a = yymsp[0].major; yygotominor.yy234.b = 0;} +#line 3014 "parse.c" break; case 275: -#line 898 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy412 = TK_STATEMENT; } -#line 2978 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 934 "parse.y" +{yygotominor.yy234.a = TK_UPDATE; yygotominor.yy234.b = yymsp[0].minor.yy258;} +#line 3019 "parse.c" break; case 276: -#line 901 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy2 = 0; } -#line 2983 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; case 277: -#line 902 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy2 = yymsp[0].minor.yy2; } -#line 2988 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 937 "parse.y" +{ yygotominor.yy58 = TK_ROW; } +#line 3025 "parse.c" break; case 278: -#line 906 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - yymsp[-2].minor.yy347->pNext = yymsp[0].minor.yy347; - yygotominor.yy347 = yymsp[-2].minor.yy347; -} -#line 2996 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 939 "parse.y" +{ yygotominor.yy58 = TK_STATEMENT; } +#line 3030 "parse.c" break; case 279: -#line 910 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy347 = 0; } -#line 3001 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 942 "parse.y" +{ yygotominor.yy44 = 0; } +#line 3035 "parse.c" break; case 280: -#line 916 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy347 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy258, yymsp[-1].minor.yy82, yymsp[0].minor.yy2, yymsp[-4].minor.yy412); } -#line 3006 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 943 "parse.y" +{ yygotominor.yy44 = yymsp[0].minor.yy44; } +#line 3040 "parse.c" break; case 281: -#line 921 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy347 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy258, yymsp[-4].minor.yy240, yymsp[-1].minor.yy82, 0, yymsp[-7].minor.yy412);} -#line 3011 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 947 "parse.y" +{ + yymsp[-2].minor.yy203->pNext = yymsp[0].minor.yy203; + yygotominor.yy203 = yymsp[-2].minor.yy203; +} +#line 3048 "parse.c" break; case 282: -#line 924 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy347 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy258, yymsp[-1].minor.yy240, 0, yymsp[0].minor.yy459, yymsp[-4].minor.yy412);} -#line 3016 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 951 "parse.y" +{ yygotominor.yy203 = 0; } +#line 3053 "parse.c" break; case 283: -#line 928 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy347 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy258, yymsp[0].minor.yy2);} -#line 3021 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 957 "parse.y" +{ yygotominor.yy203 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy144, yymsp[-1].minor.yy412, yymsp[0].minor.yy44, yymsp[-4].minor.yy58); } +#line 3058 "parse.c" break; case 284: -#line 931 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy347 = sqlite3TriggerSelectStep(yymsp[0].minor.yy459); } -#line 3026 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 962 "parse.y" +{yygotominor.yy203 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy144, yymsp[-4].minor.yy258, yymsp[-1].minor.yy412, 0, yymsp[-7].minor.yy58);} +#line 3063 "parse.c" break; case 285: -#line 934 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy2 = sqlite3Expr(TK_RAISE, 0, 0, 0); - yygotominor.yy2->iColumn = OE_Ignore; - sqlite3ExprSpan(yygotominor.yy2, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); -} -#line 3035 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 965 "parse.y" +{yygotominor.yy203 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy144, yymsp[-1].minor.yy258, 0, yymsp[0].minor.yy99, yymsp[-4].minor.yy58);} +#line 3068 "parse.c" break; case 286: -#line 939 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ - yygotominor.yy2 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy258); - yygotominor.yy2->iColumn = yymsp[-3].minor.yy412; - sqlite3ExprSpan(yygotominor.yy2, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); -} -#line 3044 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 969 "parse.y" +{yygotominor.yy203 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy144, yymsp[0].minor.yy44);} +#line 3073 "parse.c" break; case 287: -#line 947 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = OE_Rollback;} -#line 3049 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 972 "parse.y" +{yygotominor.yy203 = sqlite3TriggerSelectStep(yymsp[0].minor.yy99); } +#line 3078 "parse.c" break; - case 289: -#line 949 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{yygotominor.yy412 = OE_Fail;} -#line 3054 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 290: -#line 954 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 288: +#line 975 "parse.y" { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy67); + yygotominor.yy44 = sqlite3Expr(TK_RAISE, 0, 0, 0); + yygotominor.yy44->iColumn = OE_Ignore; + sqlite3ExprSpan(yygotominor.yy44, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); } -#line 3061 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 3087 "parse.c" break; - case 291: -#line 960 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 289: +#line 980 "parse.y" { - sqlite3Attach(pParse, &yymsp[-3].minor.yy258, &yymsp[-1].minor.yy258, yymsp[0].minor.yy132.type, &yymsp[0].minor.yy132.key); + yygotominor.yy44 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy144); + yygotominor.yy44->iColumn = yymsp[-3].minor.yy58; + sqlite3ExprSpan(yygotominor.yy44, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); } -#line 3068 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 3096 "parse.c" + break; + case 290: +#line 988 "parse.y" +{yygotominor.yy58 = OE_Rollback;} +#line 3101 "parse.c" break; case 292: -#line 964 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy132.type = 0; } -#line 3073 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 990 "parse.y" +{yygotominor.yy58 = OE_Fail;} +#line 3106 "parse.c" break; case 293: -#line 965 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy132.type=1; yygotominor.yy132.key = yymsp[0].minor.yy258; } -#line 3078 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 995 "parse.y" +{ + sqlite3DropTrigger(pParse,yymsp[0].minor.yy367); +} +#line 3113 "parse.c" break; case 294: -#line 966 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{ yygotominor.yy132.type=2; yygotominor.yy132.key = yymsp[0].minor.yy0; } -#line 3083 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" - break; - case 297: -#line 972 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 1001 "parse.y" { - sqlite3Detach(pParse, &yymsp[0].minor.yy258); + sqlite3Attach(pParse, &yymsp[-3].minor.yy144, &yymsp[-1].minor.yy144, yymsp[0].minor.yy300.type, &yymsp[0].minor.yy300.key); } -#line 3090 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 3120 "parse.c" break; - case 298: -#line 978 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Reindex(pParse, 0, 0);} -#line 3095 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 295: +#line 1005 "parse.y" +{ yygotominor.yy300.type = 0; } +#line 3125 "parse.c" break; - case 299: -#line 979 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" -{sqlite3Reindex(pParse, &yymsp[-1].minor.yy258, &yymsp[0].minor.yy258);} -#line 3100 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" + case 296: +#line 1006 "parse.y" +{ yygotominor.yy300.type=1; yygotominor.yy300.key = yymsp[0].minor.yy144; } +#line 3130 "parse.c" + break; + case 297: +#line 1007 "parse.y" +{ yygotominor.yy300.type=2; yygotominor.yy300.key = yymsp[0].minor.yy0; } +#line 3135 "parse.c" break; case 300: -#line 984 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 1013 "parse.y" { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy67,&yymsp[0].minor.yy258); + sqlite3Detach(pParse, &yymsp[0].minor.yy144); } -#line 3107 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 3142 "parse.c" break; case 301: -#line 987 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 1019 "parse.y" +{sqlite3Reindex(pParse, 0, 0);} +#line 3147 "parse.c" + break; + case 302: +#line 1020 "parse.y" +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy144, &yymsp[0].minor.yy144);} +#line 3152 "parse.c" + break; + case 303: +#line 1025 "parse.y" +{sqlite3Analyze(pParse, 0, 0);} +#line 3157 "parse.c" + break; + case 304: +#line 1026 "parse.y" +{sqlite3Analyze(pParse, &yymsp[-1].minor.yy144, &yymsp[0].minor.yy144);} +#line 3162 "parse.c" + break; + case 305: +#line 1031 "parse.y" { - sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy258); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy367,&yymsp[0].minor.yy144); } -#line 3114 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 3169 "parse.c" break; - case 302: -#line 990 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" + case 306: +#line 1034 "parse.y" +{ + sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy144); +} +#line 3176 "parse.c" + break; + case 307: +#line 1037 "parse.y" { - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy67); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy367); } -#line 3121 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 3183 "parse.c" break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -3173,7 +3235,7 @@ static void yy_syntax_error( ){ sqlite3ParserARG_FETCH; #define TOKEN (yyminor.yy0) -#line 23 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.y" +#line 34 "parse.y" if( pParse->zErrMsg==0 ){ if( TOKEN.z[0] ){ @@ -3182,7 +3244,7 @@ static void yy_syntax_error( sqlite3ErrorMsg(pParse, "incomplete SQL statement"); } } -#line 3188 "/home/rei/php_dev/php5.1/ext/pdo_sqlite/sqlite/src/parse.c" +#line 3250 "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 9dc0a15f9f..c351d4025d 100644 --- a/ext/pdo_sqlite/sqlite/src/parse.h +++ b/ext/pdo_sqlite/sqlite/src/parse.h @@ -27,114 +27,116 @@ #define TK_ID 27 #define TK_ABORT 28 #define TK_AFTER 29 -#define TK_ASC 30 -#define TK_ATTACH 31 -#define TK_BEFORE 32 -#define TK_CASCADE 33 -#define TK_CONFLICT 34 -#define TK_DATABASE 35 -#define TK_DESC 36 -#define TK_DETACH 37 -#define TK_EACH 38 -#define TK_FAIL 39 -#define TK_FOR 40 -#define TK_IGNORE 41 -#define TK_INITIALLY 42 -#define TK_INSTEAD 43 -#define TK_LIKE_KW 44 -#define TK_MATCH 45 -#define TK_KEY 46 -#define TK_OF 47 -#define TK_OFFSET 48 -#define TK_PRAGMA 49 -#define TK_RAISE 50 -#define TK_REPLACE 51 -#define TK_RESTRICT 52 -#define TK_ROW 53 -#define TK_STATEMENT 54 -#define TK_TRIGGER 55 -#define TK_VACUUM 56 -#define TK_VIEW 57 -#define TK_REINDEX 58 -#define TK_RENAME 59 -#define TK_CTIME_KW 60 -#define TK_ALTER 61 -#define TK_OR 62 -#define TK_AND 63 -#define TK_NOT 64 -#define TK_IS 65 -#define TK_BETWEEN 66 -#define TK_IN 67 -#define TK_ISNULL 68 -#define TK_NOTNULL 69 -#define TK_NE 70 -#define TK_EQ 71 -#define TK_GT 72 -#define TK_LE 73 -#define TK_LT 74 -#define TK_GE 75 -#define TK_ESCAPE 76 -#define TK_BITAND 77 -#define TK_BITOR 78 -#define TK_LSHIFT 79 -#define TK_RSHIFT 80 -#define TK_PLUS 81 -#define TK_MINUS 82 -#define TK_STAR 83 -#define TK_SLASH 84 -#define TK_REM 85 -#define TK_CONCAT 86 -#define TK_UMINUS 87 -#define TK_UPLUS 88 -#define TK_BITNOT 89 -#define TK_STRING 90 -#define TK_JOIN_KW 91 -#define TK_CONSTRAINT 92 -#define TK_DEFAULT 93 -#define TK_NULL 94 -#define TK_PRIMARY 95 -#define TK_UNIQUE 96 -#define TK_CHECK 97 -#define TK_REFERENCES 98 -#define TK_COLLATE 99 -#define TK_AUTOINCR 100 -#define TK_ON 101 -#define TK_DELETE 102 -#define TK_UPDATE 103 -#define TK_INSERT 104 -#define TK_SET 105 -#define TK_DEFERRABLE 106 -#define TK_FOREIGN 107 -#define TK_DROP 108 -#define TK_UNION 109 -#define TK_ALL 110 -#define TK_INTERSECT 111 -#define TK_EXCEPT 112 -#define TK_SELECT 113 -#define TK_DISTINCT 114 -#define TK_DOT 115 -#define TK_FROM 116 -#define TK_JOIN 117 -#define TK_USING 118 -#define TK_ORDER 119 -#define TK_BY 120 -#define TK_GROUP 121 -#define TK_HAVING 122 -#define TK_LIMIT 123 -#define TK_WHERE 124 -#define TK_INTO 125 -#define TK_VALUES 126 -#define TK_INTEGER 127 -#define TK_FLOAT 128 -#define TK_BLOB 129 -#define TK_REGISTER 130 -#define TK_VARIABLE 131 -#define TK_EXISTS 132 -#define TK_CASE 133 -#define TK_WHEN 134 -#define TK_THEN 135 -#define TK_ELSE 136 -#define TK_INDEX 137 -#define TK_TO 138 -#define TK_ADD 139 -#define TK_COLUMNKW 140 +#define TK_ANALYZE 30 +#define TK_ASC 31 +#define TK_ATTACH 32 +#define TK_BEFORE 33 +#define TK_CASCADE 34 +#define TK_CAST 35 +#define TK_CONFLICT 36 +#define TK_DATABASE 37 +#define TK_DESC 38 +#define TK_DETACH 39 +#define TK_EACH 40 +#define TK_FAIL 41 +#define TK_FOR 42 +#define TK_IGNORE 43 +#define TK_INITIALLY 44 +#define TK_INSTEAD 45 +#define TK_LIKE_KW 46 +#define TK_MATCH 47 +#define TK_KEY 48 +#define TK_OF 49 +#define TK_OFFSET 50 +#define TK_PRAGMA 51 +#define TK_RAISE 52 +#define TK_REPLACE 53 +#define TK_RESTRICT 54 +#define TK_ROW 55 +#define TK_STATEMENT 56 +#define TK_TRIGGER 57 +#define TK_VACUUM 58 +#define TK_VIEW 59 +#define TK_REINDEX 60 +#define TK_RENAME 61 +#define TK_CTIME_KW 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 +#define TK_ADD 141 +#define TK_COLUMNKW 142 diff --git a/ext/pdo_sqlite/sqlite/src/parse.y b/ext/pdo_sqlite/sqlite/src/parse.y index e5203fdf91..c7b661652a 100644 --- a/ext/pdo_sqlite/sqlite/src/parse.y +++ b/ext/pdo_sqlite/sqlite/src/parse.y @@ -16,10 +16,21 @@ ** ** @(#) $Id$ */ + +// All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ + +// The type of the data attached to each token is Token. This is also the +// default type for non-terminals. +// %token_type {Token} %default_type {Token} + +// The generated parser function takes a 4th argument as follows: %extra_argument {Parse *pParse} + +// This code runs whenever there is a syntax error +// %syntax_error { if( pParse->zErrMsg==0 ){ if( TOKEN.z[0] ){ @@ -29,7 +40,14 @@ } } } + +// The name of the generated procedure that implements the parser +// is as follows: %name sqlite3Parser + +// The following text is included near the beginning of the C source +// code file that implements the parser. +// %include { #include "sqliteInt.h" #include "parse.h" @@ -126,9 +144,10 @@ create_table_args ::= AS select(S). { columnlist ::= columnlist COMMA column. columnlist ::= column. -// About the only information used for a column is the name of the -// column. The type is always just "text". But the code will accept -// an elaborate typename. Perhaps someday we'll do something with it. +// A "column" is a complete description of a single column in a +// CREATE TABLE statement. This includes the column name, its +// datatype, and other keywords such as PRIMARY KEY, UNIQUE, REFERENCES, +// NOT NULL and so forth. // column(A) ::= columnid(X) type carglist. { A.z = X.z; @@ -151,7 +170,7 @@ id(A) ::= ID(X). {A = X;} // This obviates the need for the "id" nonterminal. // %fallback ID - ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT + ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH KEY OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT @@ -198,22 +217,38 @@ nm(A) ::= ID(X). {A = X;} nm(A) ::= STRING(X). {A = X;} nm(A) ::= JOIN_KW(X). {A = X;} +// A typetoken is really one or more tokens that form a type name such +// as can be found after the column name in a CREATE TABLE statement. +// Multiple tokens are concatenated to form the value of the typetoken. +// +%type typetoken {Token} type ::= . -type ::= typename(X). {sqlite3AddColumnType(pParse,&X,&X);} -type ::= typename(X) LP signed RP(Y). {sqlite3AddColumnType(pParse,&X,&Y);} -type ::= typename(X) LP signed COMMA signed RP(Y). - {sqlite3AddColumnType(pParse,&X,&Y);} +type ::= typetoken(X). {sqlite3AddColumnType(pParse,&X);} +typetoken(A) ::= typename(X). {A = X;} +typetoken(A) ::= typename(X) LP signed RP(Y). { + A.z = X.z; + A.n = &Y.z[Y.n] - X.z; +} +typetoken(A) ::= typename(X) LP signed COMMA signed RP(Y). { + A.z = X.z; + A.n = &Y.z[Y.n] - X.z; +} %type typename {Token} typename(A) ::= ids(X). {A = X;} typename(A) ::= typename(X) ids(Y). {A.z=X.z; A.n=Y.n+(Y.z-X.z);} %type signed {int} signed(A) ::= plus_num(X). { A = atoi(X.z); } signed(A) ::= minus_num(X). { A = -atoi(X.z); } + +// "carglist" is a list of additional constraints that come after the +// column name and column type in a CREATE TABLE statement. +// carglist ::= carglist carg. carglist ::= . carg ::= CONSTRAINT nm ccons. carg ::= ccons. carg ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,X);} +carg ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,X);} carg ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,X);} carg ::= DEFAULT MINUS term(X). { Expr *p = sqlite3Expr(TK_UMINUS, X, 0, 0); @@ -619,6 +654,12 @@ expr(A) ::= VARIABLE(X). { Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); sqlite3ExprAssignVarNumber(pParse, pExpr); } +%ifndef SQLITE_OMIT_CAST +expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { + A = sqlite3Expr(TK_CAST, E, 0, &T); + sqlite3ExprSpan(A,&X,&Y); +} +%endif // SQLITE_OMIT_CAST expr(A) ::= ID(X) LP exprlist(Y) RP(E). { A = sqlite3ExprFunction(Y, &X); sqlite3ExprSpan(A,&X,&E); @@ -979,6 +1020,12 @@ cmd ::= REINDEX. {sqlite3Reindex(pParse, 0, 0);} cmd ::= REINDEX nm(X) dbnm(Y). {sqlite3Reindex(pParse, &X, &Y);} %endif +/////////////////////////////////// ANALYZE /////////////////////////////////// +%ifndef SQLITE_OMIT_ANALYZE +cmd ::= ANALYZE. {sqlite3Analyze(pParse, 0, 0);} +cmd ::= ANALYZE nm(X) dbnm(Y). {sqlite3Analyze(pParse, &X, &Y);} +%endif + //////////////////////// ALTER TABLE table ... //////////////////////////////// %ifndef SQLITE_OMIT_ALTERTABLE cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). { diff --git a/ext/pdo_sqlite/sqlite/src/pragma.c b/ext/pdo_sqlite/sqlite/src/pragma.c index 226c1829ae..839488e862 100644 --- a/ext/pdo_sqlite/sqlite/src/pragma.c +++ b/ext/pdo_sqlite/sqlite/src/pragma.c @@ -583,12 +583,13 @@ void sqlite3Pragma( while(pFK){ int j; for(j=0; jnCol; j++){ + char *zCol = pFK->aCol[j].zCol; sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeAddOp(v, OP_Integer, j, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[pFK->aCol[j].iFrom].zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->aCol[j].zCol, 0); + sqlite3VdbeOp3(v, zCol ? OP_String8 : OP_Null, 0, 0, zCol, 0); sqlite3VdbeAddOp(v, OP_Callback, 5, 0); } ++i; @@ -602,14 +603,25 @@ void sqlite3Pragma( #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ extern void sqlite3ParserTrace(FILE*, char *); - if( getBoolean(zRight) ){ - sqlite3ParserTrace(stdout, "parser: "); - }else{ - sqlite3ParserTrace(0, 0); + if( zRight ){ + if( getBoolean(zRight) ){ + sqlite3ParserTrace(stderr, "parser: "); + }else{ + sqlite3ParserTrace(0, 0); + } } }else #endif + /* Reinstall the LIKE and GLOB functions. The variant of LIKE + ** used will be case sensitive or not depending on the RHS. + */ + if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ + if( zRight ){ + sqlite3RegisterLikeFunctions(db, getBoolean(zRight)); + } + }else + #ifndef SQLITE_OMIT_INTEGRITY_CHECK if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ int i, j, addr; diff --git a/ext/pdo_sqlite/sqlite/src/prepare.c b/ext/pdo_sqlite/sqlite/src/prepare.c index d1fec1b844..628afbd991 100644 --- a/ext/pdo_sqlite/sqlite/src/prepare.c +++ b/ext/pdo_sqlite/sqlite/src/prepare.c @@ -294,6 +294,11 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqlite3SafetyOn(db); sqliteFree(zSql); +#ifndef SQLITE_OMIT_ANALYZE + if( rc==SQLITE_OK ){ + sqlite3AnalysisLoad(db, iDb); + } +#endif sqlite3BtreeCloseCursor(curMain); } if( sqlite3_malloc_failed ){ @@ -370,7 +375,7 @@ int sqlite3ReadSchema(Parse *pParse){ rc = sqlite3Init(db, &pParse->zErrMsg); } } - assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy ); + assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized) || db->init.busy ); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; @@ -526,4 +531,3 @@ int sqlite3_prepare16( return rc; } #endif /* SQLITE_OMIT_UTF16 */ - diff --git a/ext/pdo_sqlite/sqlite/src/printf.c b/ext/pdo_sqlite/sqlite/src/printf.c index 6e700771b4..d4cb66499f 100644 --- a/ext/pdo_sqlite/sqlite/src/printf.c +++ b/ext/pdo_sqlite/sqlite/src/printf.c @@ -111,6 +111,7 @@ static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etRADIX, 0, 0 }, { 's', 0, 4, etSTRING, 0, 0 }, + { 'g', 0, 1, etGENERIC, 30, 0 }, { 'z', 0, 6, etDYNSTRING, 0, 0 }, { 'q', 0, 4, etSQLESCAPE, 0, 0 }, { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, @@ -122,7 +123,6 @@ static const et_info fmtinfo[] = { { 'f', 0, 1, etFLOAT, 0, 0 }, { 'e', 0, 1, etEXP, 30, 0 }, { 'E', 0, 1, etEXP, 14, 0 }, - { 'g', 0, 1, etGENERIC, 30, 0 }, { 'G', 0, 1, etGENERIC, 14, 0 }, { 'i', 10, 1, etRADIX, 0, 0 }, { 'n', 0, 0, etSIZE, 0, 0 }, @@ -210,9 +210,11 @@ static int vxprintf( etByte flag_plussign; /* True if "+" flag is present */ etByte flag_blanksign; /* True if " " flag is present */ etByte flag_alternateform; /* True if "#" flag is present */ + etByte flag_altform2; /* True if "!" flag is present */ etByte flag_zeropad; /* True if field width constant starts with zero */ etByte flag_long; /* True if "l" flag is present */ etByte flag_longlong; /* True if the "ll" flag is present */ + etByte done; /* Loop termination flag */ UINT64_TYPE longvalue; /* Value for integer types */ LONGDOUBLE_TYPE realvalue; /* Value for real types */ const et_info *infop; /* Pointer to the appropriate info structure */ @@ -225,7 +227,7 @@ static int vxprintf( " "; #define etSPACESIZE (sizeof(spaces)-1) #ifndef etNOFLOATINGPOINT - int exp; /* exponent of real numbers */ + int exp, e2; /* exponent of real numbers */ double rounder; /* Used for rounding floating point values */ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ @@ -254,17 +256,19 @@ static int vxprintf( } /* Find out what flags are present */ flag_leftjustify = flag_plussign = flag_blanksign = - flag_alternateform = flag_zeropad = 0; + flag_alternateform = flag_altform2 = flag_zeropad = 0; + done = 0; do{ switch( c ){ - case '-': flag_leftjustify = 1; c = 0; break; - case '+': flag_plussign = 1; c = 0; break; - case ' ': flag_blanksign = 1; c = 0; break; - case '#': flag_alternateform = 1; c = 0; break; - case '0': flag_zeropad = 1; c = 0; break; - default: break; + case '-': flag_leftjustify = 1; break; + case '+': flag_plussign = 1; break; + case ' ': flag_blanksign = 1; break; + case '#': flag_alternateform = 1; break; + case '!': flag_altform2 = 1; break; + case '0': flag_zeropad = 1; break; + default: done = 1; break; } - }while( c==0 && (c=(*++fmt))!=0 ); + }while( !done && (c=(*++fmt))!=0 ); /* Get the field width */ width = 0; if( c=='*' ){ @@ -336,6 +340,7 @@ static int vxprintf( ** At this point, variables are initialized as follows: ** ** flag_alternateform TRUE if a '#' is present. + ** flag_altform2 TRUE if a '!' is present. ** flag_plussign TRUE if a '+' is present. ** flag_leftjustify TRUE if a '-' is present or if the ** field width was negative. @@ -414,7 +419,7 @@ static int vxprintf( realvalue = va_arg(ap,double); #ifndef etNOFLOATINGPOINT if( precision<0 ) precision = 6; /* Set default precision */ - if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10; + if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10; if( realvalue<0.0 ){ realvalue = -realvalue; prefix = '-'; @@ -423,8 +428,7 @@ static int vxprintf( else if( flag_blanksign ) prefix = ' '; else prefix = 0; } - if( infop->type==etGENERIC && precision>0 ) precision--; - rounder = 0.0; + if( xtype==etGENERIC && precision>0 ) precision--; #if 0 /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); @@ -432,12 +436,13 @@ static int vxprintf( /* It makes more sense to use 0.5 */ for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1); #endif - if( infop->type==etFLOAT ) realvalue += rounder; + if( xtype==etFLOAT ) realvalue += rounder; /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; if( realvalue>0.0 ){ - while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; } - while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; } + while( realvalue>1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; } + while( realvalue>1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; } + while( realvalue>10.0 && exp<=350 ){ realvalue *= 0.1; exp++; } while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; } while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; } if( exp>350 || exp<-350 ){ @@ -467,51 +472,67 @@ static int vxprintf( }else{ flag_rtz = 0; } - /* - ** The "exp+precision" test causes output to be of type etEXP if - ** the precision is too large to fit in buf[]. - */ + if( xtype==etEXP ){ + e2 = 0; + }else{ + e2 = exp; + } nsd = 0; - if( xtype==etFLOAT && exp+precision0 || flag_alternateform); - if( prefix ) *(bufpt++) = prefix; /* Sign */ - if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */ - else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd); - if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */ - for(exp++; exp<0 && precision>0; precision--, exp++){ - *(bufpt++) = '0'; + flag_dp = (precision>0) | flag_alternateform | flag_altform2; + /* The sign in front of the number */ + if( prefix ){ + *(bufpt++) = prefix; + } + /* Digits prior to the decimal point */ + if( e2<0 ){ + *(bufpt++) = '0'; + }else{ + for(; e2>=0; e2--){ + *(bufpt++) = et_getdigit(&realvalue,&nsd); } - while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd); - *(bufpt--) = 0; /* Null terminate */ - if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */ - while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; - if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + /* The decimal point */ + if( flag_dp ){ + *(bufpt++) = '.'; + } + /* "0" digits after the decimal point but before the first + ** significant digit of the number */ + for(e2++; e2<0 && precision>0; precision--, e2++){ + *(bufpt++) = '0'; + } + /* Significant digits after the decimal point */ + while( (precision--)>0 ){ + *(bufpt++) = et_getdigit(&realvalue,&nsd); + } + /* Remove trailing zeros and the "." if no digits follow the "." */ + if( flag_rtz && flag_dp ){ + while( bufpt[-1]=='0' ) *(--bufpt) = 0; + assert( bufpt>buf ); + if( bufpt[-1]=='.' ){ + if( flag_altform2 ){ + *(bufpt++) = '0'; + }else{ + *(--bufpt) = 0; + } } - bufpt++; /* point to next free slot */ - }else{ /* etEXP or etGENERIC */ - flag_dp = (precision>0 || flag_alternateform); - if( prefix ) *(bufpt++) = prefix; /* Sign */ - *(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */ - if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */ - while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd); - bufpt--; /* point to last digit */ - if( flag_rtz && flag_dp ){ /* Remove tail zeros */ - while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; - if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + /* Add the "eNNN" suffix */ + if( flag_exp || (xtype==etEXP && exp) ){ + *(bufpt++) = aDigits[infop->charset]; + if( exp<0 ){ + *(bufpt++) = '-'; exp = -exp; + }else{ + *(bufpt++) = '+'; } - bufpt++; /* point to next free slot */ - if( exp || flag_exp ){ - *(bufpt++) = aDigits[infop->charset]; - if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */ - else { *(bufpt++) = '+'; } - if( exp>=100 ){ - *(bufpt++) = (exp/100)+'0'; /* 100's digit */ - exp %= 100; - } - *(bufpt++) = exp/10+'0'; /* 10's digit */ - *(bufpt++) = exp%10+'0'; /* 1's digit */ + if( exp>=100 ){ + *(bufpt++) = (exp/100)+'0'; /* 100's digit */ + exp %= 100; } + *(bufpt++) = exp/10+'0'; /* 10's digit */ + *(bufpt++) = exp%10+'0'; /* 1's digit */ } + *bufpt = 0; + /* The converted number is in buf[] and zero terminated. Output it. ** Note that the number is in the usual order, not reversed as with ** integer conversions. */ @@ -564,36 +585,35 @@ static int vxprintf( if( precision>=0 && precisionetBUFSIZE ){ - bufpt = zExtra = sqliteMalloc( n ); - if( bufpt==0 ) return -1; - }else{ - bufpt = buf; - } - j = 0; - if( needQuote ) bufpt[j++] = '\''; - for(i=0; (c=arg[i])!=0; i++){ - bufpt[j++] = c; - if( c=='\'' ) bufpt[j++] = c; - } - if( needQuote ) bufpt[j++] = '\''; - bufpt[j] = 0; - length = j; - if( precision>=0 && precisionetBUFSIZE ){ + bufpt = zExtra = sqliteMalloc( n ); + if( bufpt==0 ) return -1; + }else{ + bufpt = buf; } + j = 0; + if( needQuote ) bufpt[j++] = '\''; + for(i=0; (c=arg[i])!=0; i++){ + bufpt[j++] = c; + if( c=='\'' ) bufpt[j++] = c; + } + if( needQuote ) bufpt[j++] = '\''; + bufpt[j] = 0; + length = j; + if( precision>=0 && precisionz ){ diff --git a/ext/pdo_sqlite/sqlite/src/select.c b/ext/pdo_sqlite/sqlite/src/select.c index 4c2a717239..a4eb3fca4a 100644 --- a/ext/pdo_sqlite/sqlite/src/select.c +++ b/ext/pdo_sqlite/sqlite/src/select.c @@ -85,7 +85,7 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ Token *apAll[3]; Token *p; static const struct { - const char *zKeyword; + const char zKeyword[8]; u8 nChar; u8 code; } keywords[] = { @@ -155,6 +155,15 @@ static void setToken(Token *p, const char *z){ p->dyn = 0; } +/* +** Create an expression node for an identifier with the name of zName +*/ +static Expr *createIdExpr(const char *zName){ + Token dummy; + setToken(&dummy, zName); + return sqlite3Expr(TK_ID, 0, 0, &dummy); +} + /* ** Add a term to the WHERE expression in *ppExpr that requires the @@ -168,24 +177,20 @@ static void addWhereTerm( const char *zAlias2, /* Alias for second table. May be NULL */ Expr **ppExpr /* Add the equality term to this expression */ ){ - Token dummy; Expr *pE1a, *pE1b, *pE1c; Expr *pE2a, *pE2b, *pE2c; Expr *pE; - setToken(&dummy, zCol); - pE1a = sqlite3Expr(TK_ID, 0, 0, &dummy); - pE2a = sqlite3Expr(TK_ID, 0, 0, &dummy); + pE1a = createIdExpr(zCol); + pE2a = createIdExpr(zCol); if( zAlias1==0 ){ zAlias1 = pTab1->zName; } - setToken(&dummy, zAlias1); - pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy); + pE1b = createIdExpr(zAlias1); if( zAlias2==0 ){ zAlias2 = pTab2->zName; } - setToken(&dummy, zAlias2); - pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy); + pE2b = createIdExpr(zAlias2); pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0); pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0); pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0); @@ -321,10 +326,7 @@ void sqlite3SelectDelete(Select *p){ ** stack into the sorter. */ static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){ - int i; - for(i=0; inExpr; i++){ - sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr); - } + sqlite3ExprCodeExprList(pParse, pOrderBy); sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0); sqlite3VdbeAddOp(v, OP_SortInsert, 0, 0); } @@ -402,9 +404,7 @@ static int selectInnerLoop( } }else{ nColumn = pEList->nExpr; - for(i=0; inExpr; i++){ - sqlite3ExprCode(pParse, pEList->a[i].pExpr); - } + sqlite3ExprCodeExprList(pParse, pEList); } /* If the DISTINCT keyword was present on the SELECT statement @@ -412,14 +412,15 @@ static int selectInnerLoop( ** part of the result. */ if( hasDistinct ){ + int n = pEList->nExpr; #if NULL_ALWAYS_DISTINCT sqlite3VdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqlite3VdbeCurrentAddr(v)+7); #endif /* Deliberately leave the affinity string off of the following ** OP_MakeRecord */ - sqlite3VdbeAddOp(v, OP_MakeRecord, pEList->nExpr * -1, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, -n, 0); sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0); + sqlite3VdbeAddOp(v, OP_Pop, n+1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue); VdbeComment((v, "# skip indistinct records")); sqlite3VdbeAddOp(v, OP_IdxInsert, distinct, 0); @@ -511,33 +512,25 @@ static int selectInnerLoop( } #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ - /* Send the data to the callback function. + /* Send the data to the callback function or to a subroutine. In the + ** case of a subroutine, the subroutine itself is responsible for + ** popping the data from the stack. */ + case SRT_Subroutine: case SRT_Callback: case SRT_Sorter: { if( pOrderBy ){ sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); pushOntoSorter(pParse, v, pOrderBy); + }else if( eDest==SRT_Subroutine ){ + sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm); }else{ - assert( eDest==SRT_Callback ); + assert( eDest!=SRT_Sorter ); sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0); } break; } - /* Invoke a subroutine to handle the results. The subroutine itself - ** is responsible for popping the results off of the stack. - */ - case SRT_Subroutine: { - if( pOrderBy ){ - sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - pushOntoSorter(pParse, v, pOrderBy); - }else{ - sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm); - } - 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 @@ -1322,9 +1315,9 @@ static void computeLimitRegisters(Parse *pParse, Select *p){ ** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not ** UNION ALL). ** -** The value returned is the address of the OP_OpenTemp instruction. +** The value returned is the address of the OP_OpenVirtual instruction. */ -static int openTempIndex(Parse *pParse, Select *p, int iTab){ +static int openVirtualIndex(Parse *pParse, Select *p, int iTab){ KeyInfo *pKeyInfo; int nColumn; sqlite3 *db = pParse->db; @@ -1346,18 +1339,18 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab){ pKeyInfo->aColl[i] = db->pDfltColl; } } - addr = sqlite3VdbeOp3(v, OP_OpenTemp, iTab, 0, + addr = sqlite3VdbeOp3(v, OP_OpenVirtual, iTab, 0, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); 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. +** Add the address "addr" to the set of all OpenVirtual opcode addresses +** that are being accumulated in p->ppOpenVirtual. */ -static int multiSelectOpenTempAddr(Select *p, int addr){ - IdList *pList = *p->ppOpenTemp = sqlite3IdListAppend(*p->ppOpenTemp, 0); +static int multiSelectOpenVirtualAddr(Select *p, int addr){ + IdList *pList = *p->ppOpenVirtual = sqlite3IdListAppend(*p->ppOpenVirtual, 0); if( pList==0 ){ return SQLITE_NOMEM; } @@ -1430,7 +1423,7 @@ static int multiSelect( int rc = SQLITE_OK; /* Success code from a subroutine */ Select *pPrior; /* Another SELECT immediately to our left */ Vdbe *v; /* Generate code to this VDBE */ - IdList *pOpenTemp = 0;/* OP_OpenTemp opcodes that need a KeyInfo */ + IdList *pOpenVirtual = 0;/* OP_OpenVirtual opcodes that need a KeyInfo */ int aAddr[5]; /* Addresses of SetNumColumns operators */ int nAddr = 0; /* Number used */ int nCol; /* Number of columns in the result set */ @@ -1465,21 +1458,21 @@ static int multiSelect( } /* If *p this is the right-most select statement, then initialize - ** p->ppOpenTemp to point to pOpenTemp. If *p is not the right most - ** statement then p->ppOpenTemp will have already been initialized - ** by a prior call to this same procedure. Pass along the pOpenTemp + ** p->ppOpenVirtual to point to pOpenVirtual. If *p is not the right most + ** statement then p->ppOpenVirtual will have already been initialized + ** by a prior call to this same procedure. Pass along the pOpenVirtual ** pointer to pPrior, the next statement to our left. */ - if( p->ppOpenTemp==0 ){ - p->ppOpenTemp = &pOpenTemp; + if( p->ppOpenVirtual==0 ){ + p->ppOpenVirtual = &pOpenVirtual; } - pPrior->ppOpenTemp = p->ppOpenTemp; + pPrior->ppOpenVirtual = p->ppOpenVirtual; /* Create the destination temporary table if necessary */ if( eDest==SRT_TempTable ){ assert( p->pEList ); - sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0); + sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, 0); assert( nAddr==0 ); aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 0); eDest = SRT_Table; @@ -1536,9 +1529,9 @@ static int multiSelect( rc = 1; goto multi_select_end; } - addr = sqlite3VdbeAddOp(v, OP_OpenTemp, unionTab, 0); + addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, unionTab, 0); if( p->op!=TK_ALL ){ - rc = multiSelectOpenTempAddr(p, addr); + rc = multiSelectOpenVirtualAddr(p, addr); if( rc!=SQLITE_OK ){ goto multi_select_end; } @@ -1628,8 +1621,8 @@ static int multiSelect( goto multi_select_end; } - addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab1, 0); - rc = multiSelectOpenTempAddr(p, addr); + addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, tab1, 0); + rc = multiSelectOpenVirtualAddr(p, addr); if( rc!=SQLITE_OK ){ goto multi_select_end; } @@ -1646,8 +1639,8 @@ static int multiSelect( /* Code the current SELECT into temporary table "tab2" */ - addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab2, 0); - rc = multiSelectOpenTempAddr(p, addr); + addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, tab2, 0); + rc = multiSelectOpenVirtualAddr(p, addr); if( rc!=SQLITE_OK ){ goto multi_select_end; } @@ -1725,11 +1718,11 @@ static int multiSelect( ** SELECT might also skip this part if it has no ORDER BY clause and ** no temp tables are required. */ - if( p->pOrderBy || (pOpenTemp && pOpenTemp->nId>0) ){ + if( p->pOrderBy || (pOpenVirtual && pOpenVirtual->nId>0) ){ int i; /* Loop counter */ KeyInfo *pKeyInfo; /* Collating sequence for the result set */ - assert( p->ppOpenTemp == &pOpenTemp ); + assert( p->ppOpenVirtual == &pOpenVirtual ); pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*sizeof(CollSeq*)); if( !pKeyInfo ){ rc = SQLITE_NOMEM; @@ -1746,9 +1739,9 @@ static int multiSelect( } } - for(i=0; pOpenTemp && inId; i++){ + for(i=0; pOpenVirtual && inId; i++){ int p3type = (i==0?P3_KEYINFO_HANDOFF:P3_KEYINFO); - int addr = pOpenTemp->a[i].idx; + int addr = pOpenVirtual->a[i].idx; sqlite3VdbeChangeP3(v, addr, (char *)pKeyInfo, p3type); } @@ -1768,17 +1761,17 @@ static int multiSelect( generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm); } - if( !pOpenTemp ){ + if( !pOpenVirtual ){ /* This happens for UNION ALL ... ORDER BY */ sqliteFree(pKeyInfo); } } multi_select_end: - if( pOpenTemp ){ - sqlite3IdListDelete(pOpenTemp); + if( pOpenVirtual ){ + sqlite3IdListDelete(pOpenVirtual); } - p->ppOpenTemp = 0; + p->ppOpenVirtual = 0; return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ @@ -2183,7 +2176,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ /* If the output is destined for a temporary table, open that table. */ if( eDest==SRT_TempTable ){ - sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0); + sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 1); } @@ -2653,7 +2646,7 @@ int sqlite3Select( /* If the output is destined for a temporary table, open that table. */ if( eDest==SRT_TempTable ){ - sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0); + sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, pEList->nExpr); } @@ -2737,7 +2730,7 @@ int sqlite3Select( */ if( isDistinct ){ distinct = pParse->nTab++; - openTempIndex(pParse, p, distinct); + openVirtualIndex(pParse, p, distinct); }else{ distinct = -1; } @@ -2766,9 +2759,7 @@ int sqlite3Select( int lbl1 = 0; pParse->fillAgg = 1; if( pGroupBy ){ - for(i=0; inExpr; i++){ - sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr); - } + sqlite3ExprCodeExprList(pParse, pGroupBy); /* No affinity string is attached to the following OP_MakeRecord ** because we do not need to do any coercion of datatypes. */ sqlite3VdbeAddOp(v, OP_MakeRecord, pGroupBy->nExpr, 0); diff --git a/ext/pdo_sqlite/sqlite/src/shell.c b/ext/pdo_sqlite/sqlite/src/shell.c index e6411fc363..cd32a9e172 100644 --- a/ext/pdo_sqlite/sqlite/src/shell.c +++ b/ext/pdo_sqlite/sqlite/src/shell.c @@ -984,10 +984,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ p->showHeader = 1; memset(p->colWidth,0,ArraySize(p->colWidth)); p->colWidth[0] = 4; - p->colWidth[1] = 12; + p->colWidth[1] = 14; p->colWidth[2] = 10; p->colWidth[3] = 10; - p->colWidth[4] = 35; + p->colWidth[4] = 33; }else if (p->explainPrev.valid) { p->explainPrev.valid = 0; p->mode = p->explainPrev.mode; @@ -1093,6 +1093,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } } } + *z = 0; if( i+1!=nCol ){ fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n", zFile, lineno, nCol, i+1); diff --git a/ext/pdo_sqlite/sqlite/src/sqlite.h.in b/ext/pdo_sqlite/sqlite/src/sqlite.h.in index ecd337199a..ceed1f8249 100644 --- a/ext/pdo_sqlite/sqlite/src/sqlite.h.in +++ b/ext/pdo_sqlite/sqlite/src/sqlite.h.in @@ -158,7 +158,7 @@ int sqlite3_exec( */ #define SQLITE_OK 0 /* Successful result */ #define SQLITE_ERROR 1 /* SQL error or missing database */ -#define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ #define SQLITE_PERM 3 /* Access permission denied */ #define SQLITE_ABORT 4 /* Callback routine requested an abort */ #define SQLITE_BUSY 5 /* The database file is locked */ @@ -168,13 +168,13 @@ int sqlite3_exec( #define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ #define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ #define SQLITE_EMPTY 16 /* Database is empty */ #define SQLITE_SCHEMA 17 /* The database schema changed */ -#define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ +#define SQLITE_TOOBIG 18 /* NOT USED. Too much data for one row */ #define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_MISUSE 21 /* Library used incorrectly */ @@ -452,6 +452,7 @@ int sqlite3_set_authorizer( #define SQLITE_DETACH 25 /* Database Name NULL */ #define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ #define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ /* @@ -1002,10 +1003,9 @@ int sqlite3_value_type(sqlite3_value*); void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* -** The pUserData parameter to the sqlite3_create_function() and -** sqlite3_create_aggregate() routines used to register user functions -** is available to the implementation of the function using this -** call. +** The pUserData parameter to the sqlite3_create_function() +** routine used to register user functions is available to +** the implementation of the function using this call. */ void *sqlite3_user_data(sqlite3_context*); diff --git a/ext/pdo_sqlite/sqlite/src/sqliteInt.h b/ext/pdo_sqlite/sqlite/src/sqliteInt.h index f0ffbd2e85..a5245015eb 100644 --- a/ext/pdo_sqlite/sqlite/src/sqliteInt.h +++ b/ext/pdo_sqlite/sqlite/src/sqliteInt.h @@ -39,7 +39,6 @@ # define _LARGEFILE_SOURCE 1 #endif -#include "config.h" #include "sqlite3.h" #include "hash.h" #include "parse.h" @@ -209,6 +208,7 @@ typedef struct BusyHandler BusyHandler; struct BusyHandler { int (*xFunc)(void *,int); /* The busy callback */ void *pArg; /* First arg to busy callback */ + int nBusy; /* Incremented with each busy call */ }; /* @@ -298,30 +298,30 @@ extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */ /* ** Forward references to structures */ +typedef struct AggExpr AggExpr; +typedef struct AuthContext AuthContext; +typedef struct CollSeq CollSeq; typedef struct Column Column; -typedef struct Table Table; -typedef struct Index Index; +typedef struct Db Db; typedef struct Expr Expr; typedef struct ExprList ExprList; -typedef struct Parse Parse; -typedef struct Token Token; -typedef struct IdList IdList; -typedef struct SrcList SrcList; -typedef struct WhereInfo WhereInfo; -typedef struct WhereLevel WhereLevel; -typedef struct Select Select; -typedef struct AggExpr AggExpr; -typedef struct FuncDef FuncDef; -typedef struct Trigger Trigger; -typedef struct TriggerStep TriggerStep; -typedef struct TriggerStack TriggerStack; typedef struct FKey FKey; -typedef struct Db Db; -typedef struct AuthContext AuthContext; +typedef struct FuncDef FuncDef; +typedef struct IdList IdList; +typedef struct Index Index; typedef struct KeyClass KeyClass; -typedef struct CollSeq CollSeq; typedef struct KeyInfo KeyInfo; typedef struct NameContext NameContext; +typedef struct Parse Parse; +typedef struct Select Select; +typedef struct SrcList SrcList; +typedef struct Table Table; +typedef struct Token Token; +typedef struct TriggerStack TriggerStack; +typedef struct TriggerStep TriggerStep; +typedef struct Trigger Trigger; +typedef struct WhereInfo WhereInfo; +typedef struct WhereLevel WhereLevel; /* ** Each database file to be accessed by the system is an instance @@ -496,17 +496,23 @@ struct sqlite3 { ** points to a linked list of these structures. */ struct FuncDef { - char *zName; /* SQL name of the function */ - int nArg; /* Number of arguments. -1 means unlimited */ + i16 nArg; /* Number of arguments. -1 means unlimited */ u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */ + u8 needCollSeq; /* True if sqlite3GetFuncCollSeq() might be called */ + u8 flags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */ void (*xFinalize)(sqlite3_context*); /* Aggregate finializer */ - u8 needCollSeq; /* True if sqlite3GetFuncCollSeq() might be called */ + char zName[1]; /* SQL name of the function. MUST BE LAST */ }; +/* +** Possible values for FuncDef.flags +*/ +#define SQLITE_FUNC_LIKEOPT 0x01 /* Candidate for the LIKE optimization */ + /* ** information about each column of an SQL table is held in an instance ** of this structure. @@ -745,6 +751,7 @@ struct Index { char *zName; /* Name of this index */ int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ + unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ @@ -839,12 +846,13 @@ struct Expr { /* ** The following are the meanings of bits in the Expr.flags field. */ -#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ -#define EP_Agg 0x0002 /* Contains one or more aggregate functions */ -#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */ -#define EP_Error 0x0008 /* Expression contains one or more errors */ -#define EP_Not 0x0010 /* Operator preceeded by NOT */ -#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */ +#define EP_FromJoin 0x01 /* Originated in ON or USING clause of a join */ +#define EP_Agg 0x02 /* Contains one or more aggregate functions */ +#define EP_Resolved 0x04 /* IDs have been resolved to COLUMNs */ +#define EP_Error 0x08 /* Expression contains one or more errors */ +#define EP_Not 0x10 /* Operator preceeded by NOT */ +#define EP_VarSelect 0x20 /* pSelect is correlated, not constant */ +#define EP_Dequoted 0x40 /* True if the string has been dequoted */ /* ** These macros can be used to test, set, or clear bits in the @@ -924,8 +932,8 @@ struct SrcList { char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ Table *pTab; /* An SQL table corresponding to zName */ Select *pSelect; /* A SELECT statement used in place of a table name */ - int jointype; /* Type of join between this table and the next */ - int iCursor; /* The VDBE cursor number used to access this table */ + u8 jointype; /* Type of join between this table and the next */ + i16 iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ IdList *pUsing; /* The USING clause of a join */ Bitmask colUsed; /* Bit N (1< #include #include +#include #define NUM_PREPARED_STMTS 10 #define MAX_PREPARED_STMTS 100 @@ -42,7 +43,9 @@ typedef struct SqlFunc SqlFunc; struct SqlFunc { Tcl_Interp *interp; /* The TCL interpret to execute the function */ - char *zScript; /* The script to be run */ + Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */ + int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */ + char *zName; /* Name of this function */ SqlFunc *pNext; /* Next function on the list of them all */ }; @@ -54,7 +57,7 @@ typedef struct SqlCollate SqlCollate; struct SqlCollate { Tcl_Interp *interp; /* The TCL interpret to execute the function */ char *zScript; /* The script to be run */ - SqlCollate *pNext; /* Next function on the list of them all */ + SqlCollate *pNext; /* Next function on the list of them all */ }; /* @@ -76,24 +79,76 @@ struct SqlPreparedStmt { */ typedef struct SqliteDb SqliteDb; struct SqliteDb { - sqlite3 *db; /* The "real" database structure */ - Tcl_Interp *interp; /* The interpreter used for this database */ - char *zBusy; /* The busy callback routine */ - char *zCommit; /* The commit hook callback routine */ - char *zTrace; /* The trace callback routine */ - char *zProgress; /* The progress callback routine */ - char *zAuth; /* The authorization callback routine */ - char *zNull; /* Text to substitute for an SQL NULL value */ - SqlFunc *pFunc; /* List of SQL functions */ - SqlCollate *pCollate; /* List of SQL collation functions */ - int rc; /* Return code of most recent sqlite3_exec() */ - Tcl_Obj *pCollateNeeded; /* Collation needed script */ + sqlite3 *db; /* The "real" database structure */ + Tcl_Interp *interp; /* The interpreter used for this database */ + char *zBusy; /* The busy callback routine */ + char *zCommit; /* The commit hook callback routine */ + char *zTrace; /* The trace callback routine */ + char *zProgress; /* The progress callback routine */ + char *zAuth; /* The authorization callback routine */ + char *zNull; /* Text to substitute for an SQL NULL value */ + SqlFunc *pFunc; /* List of SQL functions */ + SqlCollate *pCollate; /* List of SQL collation functions */ + int rc; /* Return code of most recent sqlite3_exec() */ + Tcl_Obj *pCollateNeeded; /* Collation needed script */ SqlPreparedStmt *stmtList; /* List of prepared statements*/ SqlPreparedStmt *stmtLast; /* Last statement in the list */ int maxStmt; /* The next maximum number of stmtList */ int nStmt; /* Number of statements in stmtList */ }; +/* +** Look at the script prefix in pCmd. We will be executing this script +** after first appending one or more arguments. This routine analyzes +** the script to see if it is safe to use Tcl_EvalObjv() on the script +** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much +** faster. +** +** Scripts that are safe to use with Tcl_EvalObjv() consists of a +** command name followed by zero or more arguments with no [...] or $ +** or {...} or ; to be seen anywhere. Most callback scripts consist +** of just a single procedure name and they meet this requirement. +*/ +static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ + /* We could try to do something with Tcl_Parse(). But we will instead + ** just do a search for forbidden characters. If any of the forbidden + ** characters appear in pCmd, we will report the string as unsafe. + */ + const char *z; + int n; + z = Tcl_GetStringFromObj(pCmd, &n); + while( n-- > 0 ){ + int c = *(z++); + if( c=='$' || c=='[' || c==';' ) return 0; + } + return 1; +} + +/* +** Find an SqlFunc structure with the given name. Or create a new +** one if an existing one cannot be found. Return a pointer to the +** structure. +*/ +static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ + SqlFunc *p, *pNew; + int i; + pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen(zName) + 1 ); + pNew->zName = (char*)&pNew[1]; + for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); } + pNew->zName[i] = 0; + for(p=pDb->pFunc; p; p=p->pNext){ + if( strcmp(p->zName, pNew->zName)==0 ){ + Tcl_Free((char*)pNew); + return p; + } + } + pNew->interp = pDb->interp; + pNew->pScript = 0; + pNew->pNext = pDb->pFunc; + pDb->pFunc = pNew; + return pNew; +} + /* ** Finalize and free a list of prepared statements */ @@ -121,6 +176,7 @@ static void DbDeleteCmd(void *db){ while( pDb->pFunc ){ SqlFunc *pFunc = pDb->pFunc; pDb->pFunc = pFunc->pNext; + Tcl_DecrRefCount(pFunc->pScript); Tcl_Free((char*)pFunc); } while( pDb->pCollate ){ @@ -151,16 +207,9 @@ static int DbBusyHandler(void *cd, int nTries){ SqliteDb *pDb = (SqliteDb*)cd; int rc; char zVal[30]; - char *zCmd; - Tcl_DString cmd; - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, pDb->zBusy, -1); sprintf(zVal, "%d", nTries); - Tcl_DStringAppendElement(&cmd, zVal); - zCmd = Tcl_DStringValue(&cmd); - rc = Tcl_Eval(pDb->interp, zCmd); - Tcl_DStringFree(&cmd); + rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0); if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ return 0; } @@ -247,7 +296,7 @@ static int tclSqlCollate( Tcl_IncrRefCount(pCmd); Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA)); Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB)); - Tcl_EvalObjEx(p->interp, pCmd, 0); + Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT); Tcl_DecrRefCount(pCmd); return (atoi(Tcl_GetStringResult(p->interp))); } @@ -258,22 +307,88 @@ static int tclSqlCollate( */ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ SqlFunc *p = sqlite3_user_data(context); - Tcl_DString cmd; + Tcl_Obj *pCmd; int i; int rc; - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, p->zScript, -1); - for(i=0; ipScript; + Tcl_IncrRefCount(pCmd); + rc = Tcl_EvalObjEx(p->interp, pCmd, 0); + Tcl_DecrRefCount(pCmd); + }else{ + /* If there are arguments to the function, make a shallow copy of the + ** script object, lappend the arguments, then evaluate the copy. + ** + ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated. + ** The new Tcl_Obj contains pointers to the original list elements. + ** That way, when Tcl_EvalObjv() is run and shimmers the first element + ** of the list to tclCmdNameType, that alternate representation will + ** be preserved and reused on the next invocation. + */ + Tcl_Obj **aArg; + int nArg; + if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ + sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); + return; + } + pCmd = Tcl_NewListObj(nArg, aArg); + Tcl_IncrRefCount(pCmd); + for(i=0; i=-2147483647 && v<=2147483647 ){ + pVal = Tcl_NewIntObj(v); + }else{ + pVal = Tcl_NewWideIntObj(v); + } + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_value_double(pIn); + pVal = Tcl_NewDoubleObj(r); + break; + } + case SQLITE_NULL: { + pVal = Tcl_NewStringObj("", 0); + break; + } + default: { + int bytes = sqlite3_value_bytes(pIn); + pVal = Tcl_NewStringObj(sqlite3_value_text(pIn), bytes); + break; + } + } + rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal); + if( rc ){ + Tcl_DecrRefCount(pCmd); + sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); + return; + } + } + if( !p->useEvalObjv ){ + /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd + ** is a list without a string representation. To prevent this from + ** happening, make sure pCmd has a valid string representation */ + Tcl_GetString(pCmd); } + rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT); + Tcl_DecrRefCount(pCmd); } - rc = Tcl_EvalEx(p->interp, Tcl_DStringValue(&cmd), Tcl_DStringLength(&cmd), - TCL_EVAL_DIRECT); - Tcl_DStringFree(&cmd); if( rc && rc!=TCL_RETURN ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); @@ -283,7 +398,9 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ u8 *data; char *zType = pVar->typePtr ? pVar->typePtr->name : ""; char c = zType[0]; - if( c=='b' && strcmp(zType,"bytearray")==0 ){ + if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ + /* Only return a BLOB type if the Tcl variable is a bytearray and + ** has no string representation. */ data = Tcl_GetByteArrayFromObj(pVar, &n); sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT); }else if( (c=='b' && strcmp(zType,"boolean")==0) || @@ -294,6 +411,10 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ double r; Tcl_GetDoubleFromObj(0, pVar, &r); sqlite3_result_double(context, r); + }else if( c=='w' && strcmp(zType,"wideInt")==0 ){ + Tcl_WideInt v; + Tcl_GetWideIntFromObj(0, pVar, &v); + sqlite3_result_int64(context, v); }else{ data = Tcl_GetStringFromObj(pVar, &n); sqlite3_result_text(context, data, n, SQLITE_TRANSIENT); @@ -351,6 +472,7 @@ static int auth_callback( case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; + case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; default : zCode="????"; break; } Tcl_DStringInit(&str); @@ -469,8 +591,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "function", "last_insert_rowid", "nullvalue", "onecolumn", "progress", "rekey", "timeout", "total_changes", "trace", - "version", - 0 + "transaction", "version", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BUSY, DB_CACHE, @@ -480,7 +601,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ DB_FUNCTION, DB_LAST_INSERT_ROWID,DB_NULLVALUE, DB_ONECOLUMN, DB_PROGRESS, DB_REKEY, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, - DB_VERSION + DB_TRANSACTION, DB_VERSION, }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -924,7 +1045,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ u8 *data; char *zType = pVar->typePtr ? pVar->typePtr->name : ""; char c = zType[0]; - if( c=='b' && strcmp(zType,"bytearray")==0 ){ + if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ + /* Only load a BLOB type if the Tcl variable is a bytearray and + ** has no string representation. */ data = Tcl_GetByteArrayFromObj(pVar, &n); sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); @@ -937,6 +1060,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ double r; Tcl_GetDoubleFromObj(interp, pVar, &r); sqlite3_bind_double(pStmt, i, r); + }else if( c=='w' && strcmp(zType,"wideInt")==0 ){ + Tcl_WideInt v; + Tcl_GetWideIntFromObj(interp, pVar, &v); + sqlite3_bind_int64(pStmt, i, v); }else{ data = Tcl_GetStringFromObj(pVar, &n); sqlite3_bind_text(pStmt, i, data, n, SQLITE_STATIC); @@ -1146,22 +1273,22 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ case DB_FUNCTION: { SqlFunc *pFunc; + Tcl_Obj *pScript; char *zName; - char *zScript; - int nScript; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); return TCL_ERROR; } zName = Tcl_GetStringFromObj(objv[2], 0); - zScript = Tcl_GetStringFromObj(objv[3], &nScript); - pFunc = (SqlFunc*)Tcl_Alloc( sizeof(*pFunc) + nScript + 1 ); + pScript = objv[3]; + pFunc = findSqlFunc(pDb, zName); if( pFunc==0 ) return TCL_ERROR; - pFunc->interp = interp; - pFunc->pNext = pDb->pFunc; - pFunc->zScript = (char*)&pFunc[1]; - pDb->pFunc = pFunc; - strcpy(pFunc->zScript, zScript); + if( pFunc->pScript ){ + Tcl_DecrRefCount(pFunc->pScript); + } + pFunc->pScript = pScript; + Tcl_IncrRefCount(pScript); + pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript); rc = sqlite3_create_function(pDb->db, zName, -1, SQLITE_UTF8, pFunc, tclSqlFunc, 0, 0); if( rc!=SQLITE_OK ){ @@ -1362,6 +1489,63 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } + /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT + ** + ** Start a new transaction (if we are not already in the midst of a + ** transaction) and execute the TCL script SCRIPT. After SCRIPT + ** completes, either commit the transaction or roll it back if SCRIPT + ** throws an exception. Or if no new transation was started, do nothing. + ** pass the exception on up the stack. + ** + ** This command was inspired by Dave Thomas's talk on Ruby at the + ** 2005 O'Reilly Open Source Convention (OSCON). + */ + case DB_TRANSACTION: { + int inTrans; + Tcl_Obj *pScript; + const char *zBegin = "BEGIN"; + if( objc!=3 && objc!=4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT"); + return TCL_ERROR; + } + if( objc==3 ){ + pScript = objv[2]; + } else { + static const char *TTYPE_strs[] = { + "deferred", "exclusive", "immediate", 0 + }; + enum TTYPE_enum { + TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE + }; + int ttype; + if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type", + 0, &ttype) ){ + return TCL_ERROR; + } + switch( (enum TTYPE_enum)ttype ){ + case TTYPE_DEFERRED: /* no-op */; break; + case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break; + case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break; + } + pScript = objv[3]; + } + inTrans = !sqlite3_get_autocommit(pDb->db); + if( !inTrans ){ + sqlite3_exec(pDb->db, zBegin, 0, 0, 0); + } + rc = Tcl_EvalObjEx(interp, pScript, 0); + if( !inTrans ){ + const char *zEnd; + if( rc==TCL_ERROR ){ + zEnd = "ROLLBACK"; + } else { + zEnd = "COMMIT"; + } + sqlite3_exec(pDb->db, zEnd, 0, 0, 0); + } + break; + } + /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? ** ** Copy data into table from filename, optionally using SEPARATOR diff --git a/ext/pdo_sqlite/sqlite/src/test1.c b/ext/pdo_sqlite/sqlite/src/test1.c index de1df80e1d..8cb4bf2bca 100644 --- a/ext/pdo_sqlite/sqlite/src/test1.c +++ b/ext/pdo_sqlite/sqlite/src/test1.c @@ -26,7 +26,6 @@ const char *sqlite3TestErrorName(int rc){ switch( rc ){ case SQLITE_OK: zName = "SQLITE_OK"; break; case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; - case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; case SQLITE_PERM: zName = "SQLITE_PERM"; break; case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; @@ -36,13 +35,11 @@ const char *sqlite3TestErrorName(int rc){ case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; - case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; case SQLITE_FULL: zName = "SQLITE_FULL"; break; case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; - case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; @@ -2759,12 +2756,24 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_CASE_SENSITIVE_LIKE + Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_ALTERTABLE Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_ANALYZE + Tcl_SetVar2(interp, "sqlite_options", "analyze", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_AUTHORIZATION Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY); #else @@ -2788,12 +2797,24 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION + Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_BLOB_LITERAL Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_CAST + Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_COMPLETE Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY); #else @@ -2854,12 +2875,24 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION + Tcl_SetVar2(interp, "sqlite_options", "like_opt", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "like_opt", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_MEMORYDB Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_OR_OPTIMIZATION + Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_PAGER_PRAGMAS Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY); #else @@ -3073,8 +3106,17 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ static int bitmask_size = sizeof(Bitmask)*8; int i; extern int sqlite3_os_trace; + extern int sqlite3_where_trace; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; + extern int sqlite3_memUsed; + extern int sqlite3_memMax; + extern char sqlite3_query_plan[]; + extern int sqlite3_like_count; +#ifdef SQLITE_DEBUG + extern int sqlite3_vdbe_addop_trace; +#endif + static char *query_plan = sqlite3_query_plan; for(i=0; i0x1f && isIdChar[c-0x20])) +#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20])) /* ** Return the length of the token that begins at z[0]. @@ -183,12 +183,9 @@ static int getToken(const unsigned char *z, int *tokenType){ *tokenType = TK_BITNOT; return 1; } - case '#': { - for(i=1; isdigit(z[i]) || (i==1 && z[1]=='-'); i++){} - *tokenType = TK_REGISTER; - return i; - } - case '\'': case '"': { + case '`': + case '\'': + case '"': { int delim = z[0]; for(i=1; (c=z[i])!=0; i++){ if( c==delim ){ @@ -204,16 +201,23 @@ static int getToken(const unsigned char *z, int *tokenType){ return i; } case '.': { - *tokenType = TK_DOT; - return 1; +#ifndef SQLITE_OMIT_FLOATING_POINT + if( !isdigit(z[1]) ) +#endif + { + *tokenType = TK_DOT; + return 1; + } + /* If the next character is a digit, this is a floating point + ** number that begins with ".". Fall thru into the next case */ } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { *tokenType = TK_INTEGER; - for(i=1; isdigit(z[i]); i++){} + for(i=0; isdigit(z[i]); i++){} #ifndef SQLITE_OMIT_FLOATING_POINT - if( z[i]=='.' && isdigit(z[i+1]) ){ - i += 2; + if( z[i]=='.' ){ + i++; while( isdigit(z[i]) ){ i++; } *tokenType = TK_FLOAT; } @@ -239,50 +243,47 @@ static int getToken(const unsigned char *z, int *tokenType){ for(i=1; isdigit(z[i]); i++){} return i; } - case ':': { - for(i=1; IdChar(z[i]); i++){} - *tokenType = i>1 ? TK_VARIABLE : TK_ILLEGAL; - return i; + case '#': { + for(i=1; isdigit(z[i]); i++){} + if( i>1 ){ + /* Parameters of the form #NNN (where NNN is a number) are used + ** internally by sqlite3NestedParse. */ + *tokenType = TK_REGISTER; + return i; + } + /* Fall through into the next case if the '#' is not followed by + ** a digit. Try to match #AAAA where AAAA is a parameter name. */ } #ifndef SQLITE_OMIT_TCL_VARIABLE - case '$': { + case '$': +#endif + case ':': { + int n = 0; *tokenType = TK_VARIABLE; - if( z[1]=='{' ){ - int nBrace = 1; - for(i=2; (c=z[i])!=0 && nBrace; i++){ - if( c=='{' ){ - nBrace++; - }else if( c=='}' ){ - nBrace--; - } - } - if( c==0 ) *tokenType = TK_ILLEGAL; - }else{ - int n = 0; - for(i=1; (c=z[i])!=0; i++){ - if( isalnum(c) || c=='_' ){ - n++; - }else if( c=='(' && n>0 ){ - do{ - i++; - }while( (c=z[i])!=0 && !isspace(c) && c!=')' ); - if( c==')' ){ - i++; - }else{ - *tokenType = TK_ILLEGAL; - } - break; - }else if( c==':' && z[i+1]==':' ){ + for(i=1; (c=z[i])!=0; i++){ + if( IdChar(c) ){ + n++; +#ifndef SQLITE_OMIT_TCL_VARIABLE + }else if( c=='(' && n>0 ){ + do{ + i++; + }while( (c=z[i])!=0 && !isspace(c) && c!=')' ); + if( c==')' ){ i++; }else{ - break; + *tokenType = TK_ILLEGAL; } + break; + }else if( c==':' && z[i+1]==':' ){ + i++; +#endif + }else{ + break; } - if( n==0 ) *tokenType = TK_ILLEGAL; } + if( n==0 ) *tokenType = TK_ILLEGAL; return i; } -#endif #ifndef SQLITE_OMIT_BLOB_LITERAL case 'x': case 'X': { if( (c=z[1])=='\'' || c=='"' ){ @@ -430,241 +431,3 @@ abort_parse: } return nErr; } - -/* The sqlite3_complete() API may be omitted (to save code space) by -** defining the following symbol. -*/ -#ifndef SQLITE_OMIT_COMPLETE - -/* -** Token types used by the sqlite3_complete() routine. See the header -** comments on that procedure for additional information. -*/ -#define tkSEMI 0 -#define tkWS 1 -#define tkOTHER 2 -#define tkEXPLAIN 3 -#define tkCREATE 4 -#define tkTEMP 5 -#define tkTRIGGER 6 -#define tkEND 7 - -/* -** Return TRUE if the given SQL string ends in a semicolon. -** -** Special handling is require for CREATE TRIGGER statements. -** Whenever the CREATE TRIGGER keywords are seen, the statement -** must end with ";END;". -** -** This implementation uses a state machine with 7 states: -** -** (0) START At the beginning or end of an SQL statement. This routine -** returns 1 if it ends in the START state and 0 if it ends -** in any other state. -** -** (1) NORMAL We are in the middle of statement which ends with a single -** semicolon. -** -** (2) EXPLAIN The keyword EXPLAIN has been seen at the beginning of -** a statement. -** -** (3) CREATE The keyword CREATE has been seen at the beginning of a -** statement, possibly preceeded by EXPLAIN and/or followed by -** TEMP or TEMPORARY -** -** (4) TRIGGER We are in the middle of a trigger definition that must be -** ended by a semicolon, the keyword END, and another semicolon. -** -** (5) SEMI We've seen the first semicolon in the ";END;" that occurs at -** the end of a trigger definition. -** -** (6) END We've seen the ";END" of the ";END;" that occurs at the end -** of a trigger difinition. -** -** Transitions between states above are determined by tokens extracted -** from the input. The following tokens are significant: -** -** (0) tkSEMI A semicolon. -** (1) tkWS Whitespace -** (2) tkOTHER Any other SQL token. -** (3) tkEXPLAIN The "explain" keyword. -** (4) tkCREATE The "create" keyword. -** (5) tkTEMP The "temp" or "temporary" keyword. -** (6) tkTRIGGER The "trigger" keyword. -** (7) tkEND The "end" keyword. -** -** Whitespace never causes a state transition and is always ignored. -** -** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed -** to recognize the end of a trigger can be omitted. All we have to do -** is look for a semicolon that is not part of an string or comment. -*/ -int sqlite3_complete(const char *zSql){ - u8 state = 0; /* Current state, using numbers defined in header comment */ - u8 token; /* Value of the next token */ - -#ifndef SQLITE_OMIT_TRIGGER - /* A complex statement machine used to detect the end of a CREATE TRIGGER - ** statement. This is the normal case. - */ - static const u8 trans[7][8] = { - /* Token: */ - /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ - /* 0 START: */ { 0, 0, 1, 2, 3, 1, 1, 1, }, - /* 1 NORMAL: */ { 0, 1, 1, 1, 1, 1, 1, 1, }, - /* 2 EXPLAIN: */ { 0, 2, 1, 1, 3, 1, 1, 1, }, - /* 3 CREATE: */ { 0, 3, 1, 1, 1, 3, 4, 1, }, - /* 4 TRIGGER: */ { 5, 4, 4, 4, 4, 4, 4, 4, }, - /* 5 SEMI: */ { 5, 5, 4, 4, 4, 4, 4, 6, }, - /* 6 END: */ { 0, 6, 4, 4, 4, 4, 4, 4, }, - }; -#else - /* If triggers are not suppored by this compile then the statement machine - ** used to detect the end of a statement is much simplier - */ - static const u8 trans[2][3] = { - /* Token: */ - /* State: ** SEMI WS OTHER */ - /* 0 START: */ { 0, 0, 1, }, - /* 1 NORMAL: */ { 0, 1, 1, }, - }; -#endif /* SQLITE_OMIT_TRIGGER */ - - while( *zSql ){ - switch( *zSql ){ - case ';': { /* A semicolon */ - token = tkSEMI; - break; - } - case ' ': - case '\r': - case '\t': - case '\n': - case '\f': { /* White space is ignored */ - token = tkWS; - break; - } - case '/': { /* C-style comments */ - if( zSql[1]!='*' ){ - token = tkOTHER; - break; - } - zSql += 2; - while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } - if( zSql[0]==0 ) return 0; - zSql++; - token = tkWS; - break; - } - case '-': { /* SQL-style comments from "--" to end of line */ - if( zSql[1]!='-' ){ - token = tkOTHER; - break; - } - while( *zSql && *zSql!='\n' ){ zSql++; } - if( *zSql==0 ) return state==0; - token = tkWS; - break; - } - case '[': { /* Microsoft-style identifiers in [...] */ - zSql++; - while( *zSql && *zSql!=']' ){ zSql++; } - if( *zSql==0 ) return 0; - token = tkOTHER; - break; - } - case '"': /* single- and double-quoted strings */ - case '\'': { - int c = *zSql; - zSql++; - while( *zSql && *zSql!=c ){ zSql++; } - if( *zSql==0 ) return 0; - token = tkOTHER; - break; - } - default: { - int c; - if( IdChar((u8)*zSql) ){ - /* Keywords and unquoted identifiers */ - int nId; - for(nId=1; IdChar(zSql[nId]); nId++){} -#ifdef SQLITE_OMIT_TRIGGER - token = tkOTHER; -#else - switch( *zSql ){ - case 'c': case 'C': { - if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ - token = tkCREATE; - }else{ - token = tkOTHER; - } - break; - } - case 't': case 'T': { - if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ - token = tkTRIGGER; - }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ - token = tkTEMP; - }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ - token = tkTEMP; - }else{ - token = tkOTHER; - } - break; - } - case 'e': case 'E': { - if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ - token = tkEND; - }else -#ifndef SQLITE_OMIT_EXPLAIN - if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ - token = tkEXPLAIN; - }else -#endif - { - token = tkOTHER; - } - break; - } - default: { - token = tkOTHER; - break; - } - } -#endif /* SQLITE_OMIT_TRIGGER */ - zSql += nId-1; - }else{ - /* Operators and special symbols */ - token = tkOTHER; - } - break; - } - } - state = trans[state][token]; - zSql++; - } - return state==0; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** This routine is the same as the sqlite3_complete() routine described -** above, except that the parameter is required to be UTF-16 encoded, not -** UTF-8. -*/ -int sqlite3_complete16(const void *zSql){ - sqlite3_value *pVal; - char const *zSql8; - int rc = 0; - - pVal = sqlite3ValueNew(); - sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); - zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); - if( zSql8 ){ - rc = sqlite3_complete(zSql8); - } - sqlite3ValueFree(pVal); - return rc; -} -#endif /* SQLITE_OMIT_UTF16 */ -#endif /* SQLITE_OMIT_COMPLETE */ diff --git a/ext/pdo_sqlite/sqlite/src/update.c b/ext/pdo_sqlite/sqlite/src/update.c index 9d96bec182..b1f28ad8cf 100644 --- a/ext/pdo_sqlite/sqlite/src/update.c +++ b/ext/pdo_sqlite/sqlite/src/update.c @@ -47,7 +47,11 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){ u8 enc = sqlite3VdbeDb(v)->enc; Column *pCol = &pTab->aCol[i]; sqlite3ValueFromExpr(pCol->pDflt, enc, pCol->affinity, &pValue); - sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM); + if( pValue ){ + sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM); + }else{ + VdbeComment((v, "# %s.%s", pTab->zName, pCol->zName)); + } } } @@ -273,7 +277,7 @@ void sqlite3Update( /* Remember the index of every item to be updated. */ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); - sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); + sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0); /* End the database scan loop. */ @@ -295,8 +299,7 @@ void sqlite3Update( /* The top of the update loop for when there are triggers. */ - sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0); - addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0); + addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0); if( !isView ){ sqlite3VdbeAddOp(v, OP_Dup, 0, 0); @@ -389,8 +392,7 @@ void sqlite3Update( ** So make the cursor point at the old record. */ if( !triggers_exist ){ - sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0); - addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0); + addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); } sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr); @@ -468,7 +470,6 @@ void sqlite3Update( */ sqlite3VdbeAddOp(v, OP_Goto, 0, addr); sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v)); - sqlite3VdbeAddOp(v, OP_ListReset, 0, 0); /* Close all tables if there were no FOR EACH ROW triggers */ if( !triggers_exist ){ diff --git a/ext/pdo_sqlite/sqlite/src/util.c b/ext/pdo_sqlite/sqlite/src/util.c index 90edb98a09..a35a43fce3 100644 --- a/ext/pdo_sqlite/sqlite/src/util.c +++ b/ext/pdo_sqlite/sqlite/src/util.c @@ -58,6 +58,8 @@ int sqlite3_malloc_failed = 0; */ int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ int sqlite3_nFree; /* Number of sqliteFree() calls */ +int sqlite3_memUsed; /* Total memory obtained from malloc */ +int sqlite3_memMax; /* Mem usage high-water mark */ int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */ int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */ #if SQLITE_MEMDEBUG>1 @@ -72,13 +74,10 @@ static int memcnt = 0; #define N_GUARD 2 /* -** Allocate new memory and set it to zero. Return NULL if -** no memory is available. +** Check for a simulated memory allocation failure. Return true if +** the failure should be simulated. Return false to proceed as normal. */ -void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){ - void *p; - int *pi; - int i, k; +static int simulatedMallocFailure(int n, char *zFile, int line){ if( sqlite3_iMallocFail>=0 ){ sqlite3_iMallocFail--; if( sqlite3_iMallocFail==0 ){ @@ -88,10 +87,28 @@ void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){ n, zFile,line); #endif sqlite3_iMallocFail = sqlite3_iMallocReset; - return 0; + return 1; } } - if( n==0 ) return 0; + return 0; +} + +/* +** Allocate new memory and set it to zero. Return NULL if +** no memory is available. +*/ +void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){ + void *p; + int *pi; + int i, k; + if( n==0 ){ + return 0; + } + if( simulatedMallocFailure(n, zFile, line) ){ + return 0; + } + sqlite3_memUsed += n; + if( sqlite3_memMaxoldN ? oldN : n); @@ -268,6 +292,7 @@ void sqlite3FreeX(void *p){ */ void *sqlite3Malloc(int n){ void *p; + if( n==0 ) return 0; if( (p = malloc(n))==0 ){ if( n>0 ) sqlite3_malloc_failed++; }else{ @@ -282,6 +307,7 @@ void *sqlite3Malloc(int n){ */ void *sqlite3MallocRaw(int n){ void *p; + if( n==0 ) return 0; if( (p = malloc(n))==0 ){ if( n>0 ) sqlite3_malloc_failed++; } @@ -372,8 +398,8 @@ void sqlite3SetString(char **pz, ...){ zResult += strlen(zResult); } va_end(ap); -#ifdef SQLITE_DEBUG -#if SQLITE_DEBUG>1 +#ifdef SQLITE_MEMDEBUG +#if SQLITE_MEMDEBUG>1 fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz); #endif #endif @@ -460,7 +486,8 @@ void sqlite3Dequote(char *z){ switch( quote ){ case '\'': break; case '"': break; - case '[': quote = ']'; break; + case '`': break; /* For MySQL compatibility */ + case '[': quote = ']'; break; /* For MS SqlServer compatibility */ default: return; } for(i=1, j=0; z[i]; i++){ @@ -565,8 +592,9 @@ int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ ** of "." depending on how locale is set. But that would cause problems ** for SQL. So this routine always uses "." regardless of locale. */ -double sqlite3AtoF(const char *z, const char **pzEnd){ +int sqlite3AtoF(const char *z, double *pResult){ int sign = 1; + const char *zBegin = z; LONGDOUBLE_TYPE v1 = 0.0; if( *z=='-' ){ sign = -1; @@ -613,8 +641,8 @@ double sqlite3AtoF(const char *z, const char **pzEnd){ v1 *= scale; } } - if( pzEnd ) *pzEnd = z; - return sign<0 ? -v1 : v1; + *pResult = sign<0 ? -v1 : v1; + return z - zBegin; } /* @@ -720,7 +748,7 @@ int sqlite3SafetyOn(sqlite3 *db){ if( db->magic==SQLITE_MAGIC_OPEN ){ db->magic = SQLITE_MAGIC_BUSY; return 0; - }else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR ){ + }else if( db->magic==SQLITE_MAGIC_BUSY ){ db->magic = SQLITE_MAGIC_ERROR; db->flags |= SQLITE_Interrupt; } @@ -736,7 +764,7 @@ int sqlite3SafetyOff(sqlite3 *db){ if( db->magic==SQLITE_MAGIC_BUSY ){ db->magic = SQLITE_MAGIC_OPEN; return 0; - }else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR ){ + }else if( db->magic==SQLITE_MAGIC_OPEN ){ db->magic = SQLITE_MAGIC_ERROR; db->flags |= SQLITE_Interrupt; } diff --git a/ext/pdo_sqlite/sqlite/src/vdbe.c b/ext/pdo_sqlite/sqlite/src/vdbe.c index fe44eed405..ae33e39961 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbe.c +++ b/ext/pdo_sqlite/sqlite/src/vdbe.c @@ -454,7 +454,6 @@ int sqlite3VdbeExec( int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ Mem *pTos; /* Top entry in the operand stack */ - char zBuf[100]; /* Space to sprintf() an integer */ #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ @@ -478,6 +477,7 @@ int sqlite3VdbeExec( p->popStack = 0; } p->resOnStack = 0; + db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pcnOp ); @@ -633,7 +633,7 @@ case OP_Return: { /* no-push */ break; } -/* Opcode: Halt P1 P2 * +/* Opcode: Halt P1 P2 P3 ** ** Exit immediately. All open cursors, Lists, Sorts, etc are closed ** automatically. @@ -646,6 +646,8 @@ case OP_Return: { /* no-push */ ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** +** If P3 is not null then it is an error message string. +** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program ** is the same as executing Halt. @@ -667,28 +669,31 @@ case OP_Halt: { /* no-push */ return p->rc ? SQLITE_ERROR : SQLITE_DONE; } -/* Opcode: Integer P1 * P3 -** -** The integer value P1 is pushed onto the stack. If P3 is not zero -** then it is assumed to be a string representation of the same integer. -** If P1 is zero and P3 is not zero, then the value is derived from P3. +/* Opcode: Integer P1 * * ** -** If the value cannot be represented as a 32-bits then its value -** will be in P3. +** The 32-bit integer value P1 is pushed onto the stack. */ case OP_Integer: { pTos++; - if( pOp->p3==0 ){ - pTos->flags = MEM_Int; - pTos->i = pOp->p1; - }else{ - pTos->flags = MEM_Str|MEM_Static|MEM_Term; - pTos->z = pOp->p3; - pTos->n = strlen(pTos->z); - pTos->enc = SQLITE_UTF8; - pTos->i = sqlite3VdbeIntValue(pTos); - pTos->flags |= MEM_Int; - } + pTos->flags = MEM_Int; + pTos->i = pOp->p1; + break; +} + +/* Opcode: Int64 * * P3 +** +** P3 is a string representation of an integer. Convert that integer +** to a 64-bit value and push it onto the stack. +*/ +case OP_Int64: { + pTos++; + assert( pOp->p3!=0 ); + pTos->flags = MEM_Str|MEM_Static|MEM_Term; + pTos->z = pOp->p3; + pTos->n = strlen(pTos->z); + pTos->enc = SQLITE_UTF8; + pTos->i = sqlite3VdbeIntValue(pTos); + pTos->flags |= MEM_Int; break; } @@ -1000,7 +1005,7 @@ case OP_Concat: { /* same as TK_CONCAT */ pTerm = &pTos[1-nField]; for(i=j=0; in; - assert( pTerm->flags & MEM_Str ); + assert( pTerm->flags & (MEM_Str|MEM_Blob) ); memcpy(&zNew[j], pTerm->z, n); j += n; } @@ -1377,6 +1382,94 @@ case OP_MustBeInt: { /* no-push */ break; } +#ifndef SQLITE_OMIT_CAST +/* Opcode: ToInt * * * +** +** Force the value on the top of the stack to be an integer. If +** The value is currently a real number, drop its fractional part. +** If the value is text or blob, try to convert it to an integer using the +** equivalent of atoi() and store 0 if no such conversion is possible. +** +** A NULL value is not changed by this routine. It remains NULL. +*/ +case OP_ToInt: { /* no-push */ + assert( pTos>=p->aStack ); + if( pTos->flags & MEM_Null ) break; + assert( MEM_Str==(MEM_Blob>>3) ); + pTos->flags |= (pTos->flags&MEM_Blob)>>3; + applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc); + sqlite3VdbeMemIntegerify(pTos); + break; +} + +/* Opcode: ToNumeric * * * +** +** Force the value on the top of the stack to be numeric (either an +** integer or a floating-point number. +** If the value is text or blob, try to convert it to an using the +** equivalent of atoi() or atof() and store 0 if no such conversion +** is possible. +** +** A NULL value is not changed by this routine. It remains NULL. +*/ +case OP_ToNumeric: { /* no-push */ + assert( pTos>=p->aStack ); + if( pTos->flags & MEM_Null ) break; + assert( MEM_Str==(MEM_Blob>>3) ); + pTos->flags |= (pTos->flags&MEM_Blob)>>3; + applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc); + if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){ + sqlite3VdbeMemRealify(pTos); + }else{ + sqlite3VdbeMemRelease(pTos); + } + assert( (pTos->flags & MEM_Dyn)==0 ); + pTos->flags &= (MEM_Int|MEM_Real); + break; +} + +/* Opcode: ToText * * * +** +** Force the value on the top of the stack to be text. +** If the value is numeric, convert it to an using the +** equivalent of printf(). Blob values are unchanged and +** are afterwards simply interpreted as text. +** +** A NULL value is not changed by this routine. It remains NULL. +*/ +case OP_ToText: { /* no-push */ + assert( pTos>=p->aStack ); + if( pTos->flags & MEM_Null ) break; + assert( MEM_Str==(MEM_Blob>>3) ); + pTos->flags |= (pTos->flags&MEM_Blob)>>3; + applyAffinity(pTos, SQLITE_AFF_TEXT, db->enc); + assert( pTos->flags & MEM_Str ); + pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob); + break; +} + +/* Opcode: ToBlob * * * +** +** Force the value on the top of the stack to be a BLOB. +** If the value is numeric, convert it to a string first. +** Strings are simply reinterpreted as blobs with no change +** to the underlying data. +** +** A NULL value is not changed by this routine. It remains NULL. +*/ +case OP_ToBlob: { /* no-push */ + assert( pTos>=p->aStack ); + if( pTos->flags & MEM_Null ) break; + if( (pTos->flags & MEM_Blob)==0 ){ + applyAffinity(pTos, SQLITE_AFF_TEXT, db->enc); + assert( pTos->flags & MEM_Str ); + pTos->flags |= MEM_Blob; + } + pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Str); + break; +} +#endif /* SQLITE_OMIT_CAST */ + /* Opcode: Eq P1 P2 P3 ** ** Pop the top two elements from the stack. If they are equal, then @@ -1737,6 +1830,13 @@ case OP_SetNumColumns: { /* no-push */ ** just a pointer into the record which is stored further down on the ** stack. The column value is not copied. The number of columns in the ** record is stored on the stack just above the record itself. +** +** If the column contains fewer than P2 fields, then push a NULL. Or +** if P3 is of type P3_MEM, then push the P3 value. The P3 value will +** be default value for a column that has been added using the ALTER TABLE +** ADD COLUMN command. If P3 is an ordinary string, just push a NULL. +** When P3 is a string it is really just a comment describing the value +** to be pushed, not a default value. */ case OP_Column: { u32 payloadSize; /* Number of bytes in the record */ @@ -1937,7 +2037,8 @@ case OP_Column: { /* Get the column information. If aOffset[p2] is non-zero, then ** deserialize the value from the record. If aOffset[p2] is zero, ** then there are not enough fields in the record to satisfy the - ** request. The value is NULL in this case. + ** request. In this case, set the value NULL or to P3 if P3 is + ** a pointer to a Mem object. */ if( aOffset[p2] ){ assert( rc==SQLITE_OK ); @@ -1954,7 +2055,7 @@ case OP_Column: { sqlite3VdbeSerialGet(zData, aType[p2], pTos); pTos->enc = db->enc; }else{ - if( pOp->p3 ){ + if( pOp->p3type==P3_MEM ){ sqlite3VdbeMemShallowCopy(pTos, (Mem *)(pOp->p3), MEM_Static); }else{ pTos->flags = MEM_Null; @@ -2000,12 +2101,9 @@ op_column_out: ** The original stack entries are popped from the stack if P1>0 but ** remain on the stack if P1<0. ** -** The P2 argument is divided into two 16-bit words before it is processed. -** If the hi-word is non-zero, then an extra integer is read from the stack -** and appended to the record as a varint. If the low-word of P2 is not -** zero and one or more of the entries are NULL, then jump to the value of -** the low-word of P2. This feature can be used to skip a uniqueness test -** on indices. +** If P2 is not zero and one or more of the entries are NULL, then jump +** to the address given by P2. This feature can be used to skip a +** uniqueness test on indices. ** ** P3 may be a string that is P1 characters long. The nth character of the ** string indicates the column affinity that should be used for the nth @@ -2019,7 +2117,17 @@ op_column_out: ** 'o' = NONE. ** ** If P3 is NULL then all index fields have the affinity NONE. +** +** See also OP_MakeIdxRec +*/ +/* Opcode: MakeRecordI P1 P2 P3 +** +** This opcode works just OP_MakeRecord except that it reads an extra +** integer from the stack (thus reading a total of abs(P1+1) entries) +** and appends that extra integer to the end of the record as a varint. +** This results in an index key. */ +case OP_MakeIdxRec: case OP_MakeRecord: { /* Assuming the record contains N fields, the record format looks ** like this: @@ -2057,8 +2165,8 @@ case OP_MakeRecord: { leaveOnStack = ((pOp->p1<0)?1:0); nField = pOp->p1 * (leaveOnStack?-1:1); - jumpIfNull = (pOp->p2 & 0x00FFFFFF); - addRowid = ((pOp->p2>>24) & 0x0000FFFF)?1:0; + jumpIfNull = pOp->p2; + addRowid = pOp->opcode==OP_MakeIdxRec; zAffinity = pOp->p3; pData0 = &pTos[1-nField]; @@ -2145,6 +2253,7 @@ case OP_MakeRecord: { pTos->flags = MEM_Blob | MEM_Dyn; pTos->xDel = 0; } + pTos->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */ if( jumpIfNull && containsNull ){ @@ -2429,11 +2538,7 @@ case OP_OpenWrite: { /* no-push */ p2 = pTos->i; assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; - if( p2<2 ){ - sqlite3SetString(&p->zErrMsg, "root page number less than 2", (char*)0); - rc = SQLITE_INTERNAL; - break; - } + assert( p2>=2 ); } assert( i>=0 ); pCur = allocateCursor(p, i); @@ -2498,25 +2603,18 @@ case OP_OpenWrite: { /* no-push */ break; } -/* Opcode: OpenTemp P1 * P3 +/* Opcode: OpenVirtual P1 * P3 ** -** Open a new cursor to a transient table. -** The transient cursor is always opened read/write even if -** the main database is read-only. The transient table is deleted -** automatically when the cursor is closed. +** Open a new cursor to a transient or virtual table. +** The cursor is always opened read/write even if +** the main database is read-only. The transient or virtual +** table is deleted automatically when the cursor is closed. ** ** The cursor points to a BTree table if P3==0 and to a BTree index ** if P3 is not 0. If P3 is not NULL, it points to a KeyInfo structure ** that defines the format of keys in the index. -** -** This opcode is used for tables that exist for the duration of a single -** SQL statement only. Tables created using CREATE TEMPORARY TABLE -** are opened using OP_OpenRead or OP_OpenWrite. "Temporary" in the -** context of this opcode means for the duration of a single SQL statement -** whereas "Temporary" in the context of CREATE TABLE means for the duration -** of the connection to the database. Same word; different meanings. */ -case OP_OpenTemp: { /* no-push */ +case OP_OpenVirtual: { /* no-push */ int i = pOp->p1; Cursor *pCx; assert( i>=0 ); @@ -3280,6 +3378,7 @@ case OP_RowData: { }else{ pTos->flags = MEM_Null; } + pTos->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ break; } @@ -3444,17 +3543,12 @@ case OP_Next: { /* no-push */ break; } -/* Opcode: IdxInsert P1 P2 P3 +/* Opcode: IdxInsert P1 * * ** ** The top of the stack holds a SQL index key made using the ** MakeIdxKey instruction. This opcode writes that key into the ** index P1. Data for the entry is nil. ** -** If P2==1, then the key must be unique. If the key is not unique, -** the program aborts with a SQLITE_CONSTRAINT error and the database -** is rolled back. If P3 is not null, then it becomes part of the -** error message returned with the SQLITE_CONSTRAINT. -** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ @@ -3466,35 +3560,10 @@ case OP_IdxInsert: { /* no-push */ assert( i>=0 && inCursor ); assert( p->apCsr[i]!=0 ); assert( pTos->flags & MEM_Blob ); + assert( pOp->p2==0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int nKey = pTos->n; const char *zKey = pTos->z; - if( pOp->p2 ){ - int res; - int len; - - /* 'len' is the length of the key minus the rowid at the end */ - len = nKey - sqlite3VdbeIdxRowidLen(nKey, zKey); - - rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - while( res!=0 && !sqlite3BtreeEof(pCrsr) ){ - int c; - if( sqlite3VdbeIdxKeyCompare(pC, len, zKey, &c)==SQLITE_OK && c==0 ){ - rc = SQLITE_CONSTRAINT; - if( pOp->p3 && pOp->p3[0] ){ - sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0); - } - goto abort_due_to_error; - } - if( res<0 ){ - sqlite3BtreeNext(pCrsr, &res); - res = +1; - }else{ - break; - } - } - } assert( pC->isTable==0 ); rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0); assert( pC->deferredMoveto==0 ); @@ -3815,6 +3884,21 @@ case OP_ParseSchema: { /* no-push */ break; } +#ifndef SQLITE_OMIT_ANALYZE +/* Opcode: LoadAnalysis P1 * * +** +** Read the sqlite_stat1 table for database P1 and load the content +** of that table into the internal index hash table. This will cause +** the analysis to be used when preparing all subsequent queries. +*/ +case OP_LoadAnalysis: { /* no-push */ + int iDb = pOp->p1; + assert( iDb>=0 && iDbnDb ); + sqlite3AnalysisLoad(db, iDb); + break; +} +#endif /* SQLITE_OMIT_ANALYZE */ + /* Opcode: DropTable P1 * P3 ** ** Remove the internal (in-memory) data structures that describe @@ -3906,86 +3990,35 @@ case OP_IntegrityCk: { } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ -/* Opcode: ListWrite * * * +/* Opcode: FifoWrite * * * ** ** Write the integer on the top of the stack -** into the temporary storage list. +** into the Fifo. */ -case OP_ListWrite: { /* no-push */ - Keylist *pKeylist; +case OP_FifoWrite: { /* no-push */ assert( pTos>=p->aStack ); - pKeylist = p->pList; - if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){ - pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) ); - if( pKeylist==0 ) goto no_mem; - pKeylist->nKey = 1000; - pKeylist->nRead = 0; - pKeylist->nUsed = 0; - pKeylist->pNext = p->pList; - p->pList = pKeylist; - } Integerify(pTos); - pKeylist->aKey[pKeylist->nUsed++] = pTos->i; + sqlite3VdbeFifoPush(&p->sFifo, pTos->i); assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; break; } -/* Opcode: ListRewind * * * -** -** Rewind the temporary buffer back to the beginning. -*/ -case OP_ListRewind: { /* no-push */ - /* What this opcode codes, really, is reverse the order of the - ** linked list of Keylist structures so that they are read out - ** in the same order that they were read in. */ - Keylist *pRev, *pTop; - pRev = 0; - while( p->pList ){ - pTop = p->pList; - p->pList = pTop->pNext; - pTop->pNext = pRev; - pRev = pTop; - } - p->pList = pRev; - break; -} - -/* Opcode: ListRead * P2 * +/* Opcode: FifoRead * P2 * ** -** Attempt to read an integer from the temporary storage buffer -** and push it onto the stack. If the storage buffer is empty, +** Attempt to read a single integer from the Fifo +** and push it onto the stack. If the Fifo is empty ** push nothing but instead jump to P2. */ -case OP_ListRead: { - Keylist *pKeylist; +case OP_FifoRead: { + i64 v; CHECK_FOR_INTERRUPT; - pKeylist = p->pList; - if( pKeylist!=0 ){ - assert( pKeylist->nRead>=0 ); - assert( pKeylist->nReadnUsed ); - assert( pKeylist->nReadnKey ); + if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){ + pc = pOp->p2 - 1; + }else{ pTos++; - pTos->i = pKeylist->aKey[pKeylist->nRead++]; + pTos->i = v; pTos->flags = MEM_Int; - if( pKeylist->nRead>=pKeylist->nUsed ){ - p->pList = pKeylist->pNext; - sqliteFree(pKeylist); - } - }else{ - pc = pOp->p2 - 1; - } - break; -} - -/* Opcode: ListReset * * * -** -** Reset the temporary storage buffer so that it holds nothing. -*/ -case OP_ListReset: { /* no-push */ - if( p->pList ){ - sqlite3VdbeKeylistFree(p->pList); - p->pList = 0; } break; } @@ -4036,8 +4069,8 @@ case OP_ContextPush: { /* no-push */ pContext = &p->contextStack[i]; pContext->lastRowid = db->lastRowid; pContext->nChange = p->nChange; - pContext->pList = p->pList; - p->pList = 0; + pContext->sFifo = p->sFifo; + sqlite3VdbeFifoInit(&p->sFifo); break; } @@ -4052,8 +4085,8 @@ case OP_ContextPop: { /* no-push */ assert( p->contextStackTop>=0 ); db->lastRowid = pContext->lastRowid; p->nChange = pContext->nChange; - sqlite3VdbeKeylistFree(p->pList); - p->pList = pContext->pList; + sqlite3VdbeFifoClear(&p->sFifo); + p->sFifo = pContext->sFifo; break; } #endif /* #ifndef SQLITE_OMIT_TRIGGER */ @@ -4567,9 +4600,7 @@ case OP_Expire: { /* no-push */ /* An other opcode is illegal... */ default: { - sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode); - sqlite3SetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0); - rc = SQLITE_INTERNAL; + assert( 0 ); break; } @@ -4606,10 +4637,7 @@ default: { if( pTos>=p->aStack ){ sqlite3VdbeMemSanity(pTos, db->enc); } - if( pc<-1 || pc>=p->nOp ){ - sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0); - rc = SQLITE_INTERNAL; - } + assert( pc>=-1 && pcnOp ); #ifdef SQLITE_DEBUG /* Code for tracing the vdbe stack. */ if( p->trace && pTos>=p->aStack ){ diff --git a/ext/pdo_sqlite/sqlite/src/vdbe.h b/ext/pdo_sqlite/sqlite/src/vdbe.h index c88a75c134..77695d1cda 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbe.h +++ b/ext/pdo_sqlite/sqlite/src/vdbe.h @@ -105,8 +105,6 @@ int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N); -void sqlite3VdbeDequoteP3(Vdbe*, int addr); -int sqlite3VdbeFindOp(Vdbe*, int, int, int); VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); int sqlite3VdbeMakeLabel(Vdbe*); void sqlite3VdbeDelete(Vdbe*); diff --git a/ext/pdo_sqlite/sqlite/src/vdbeInt.h b/ext/pdo_sqlite/sqlite/src/vdbeInt.h index 1feb9bab45..7bf2a0ec5d 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbeInt.h +++ b/ext/pdo_sqlite/sqlite/src/vdbeInt.h @@ -260,17 +260,29 @@ struct Set { }; /* -** A Keylist is a bunch of keys into a table. The keylist can -** grow without bound. The keylist stores the ROWIDs of database -** records that need to be deleted or updated. +** A FifoPage structure holds a single page of valves. Pages are arranged +** in a list. */ -typedef struct Keylist Keylist; -struct Keylist { - int nKey; /* Number of slots in aKey[] */ - int nUsed; /* Next unwritten slot in aKey[] */ - int nRead; /* Next unread slot in aKey[] */ - Keylist *pNext; /* Next block of keys */ - i64 aKey[1]; /* One or more keys. Extra space allocated as needed */ +typedef struct FifoPage FifoPage; +struct FifoPage { + int nSlot; /* Number of entries aSlot[] */ + int iWrite; /* Push the next value into this entry in aSlot[] */ + int iRead; /* Read the next value from this entry in aSlot[] */ + FifoPage *pNext; /* Next page in the fifo */ + i64 aSlot[1]; /* One or more slots for rowid values */ +}; + +/* +** The Fifo structure is typedef-ed in vdbeInt.h. But the implementation +** of that structure is private to this file. +** +** The Fifo structure describes the entire fifo. +*/ +typedef struct Fifo Fifo; +struct Fifo { + int nEntry; /* Total number of entries */ + FifoPage *pFirst; /* First page on the list */ + FifoPage *pLast; /* Last page on the list */ }; /* @@ -286,7 +298,7 @@ typedef struct Context Context; struct Context { int lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ int nChange; /* Statement changes (Vdbe.nChanges) */ - Keylist *pList; /* Records that will participate in a DELETE or UPDATE */ + Fifo sFifo; /* Records that will participate in a DELETE or UPDATE */ }; /* @@ -325,7 +337,7 @@ struct Vdbe { Agg *apAgg; /* Array of aggregate contexts */ Agg *pAgg; /* Current aggregate context */ int nCallback; /* Number of callbacks invoked so far */ - Keylist *pList; /* A list of ROWIDs */ + Fifo sFifo; /* A list of ROWIDs */ int contextStackTop; /* Index of top element in the context stack */ int contextStackDepth; /* The size of the "context" stack */ Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/ @@ -362,7 +374,6 @@ struct Vdbe { void sqlite3VdbeFreeCursor(Cursor*); void sqlite3VdbeSorterReset(Vdbe*); int sqlite3VdbeAggReset(sqlite3*, Agg *, KeyInfo *); -void sqlite3VdbeKeylistFree(Keylist*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(Cursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) @@ -411,3 +422,7 @@ int sqlite3VdbeOpcodeNoPush(u8); int sqlite3VdbeMemTranslate(Mem*, u8); void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf); int sqlite3VdbeMemHandleBom(Mem *pMem); +void sqlite3VdbeFifoInit(Fifo*); +int sqlite3VdbeFifoPush(Fifo*, i64); +int sqlite3VdbeFifoPop(Fifo*, i64*); +void sqlite3VdbeFifoClear(Fifo*); diff --git a/ext/pdo_sqlite/sqlite/src/vdbeapi.c b/ext/pdo_sqlite/sqlite/src/vdbeapi.c index f07bc88992..dfe8f12c41 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbeapi.c +++ b/ext/pdo_sqlite/sqlite/src/vdbeapi.c @@ -84,7 +84,7 @@ void sqlite3_result_blob( int n, void (*xDel)(void *) ){ - assert( n>0 ); + assert( n>=0 ); sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel); } void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ @@ -213,7 +213,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ rc = SQLITE_MISUSE; } - sqlite3Error(p->db, rc, p->zErrMsg); + sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); return rc; } @@ -230,10 +230,6 @@ void *sqlite3_user_data(sqlite3_context *p){ ** Allocate or return the aggregate context for a user function. A new ** context is allocated on the first call. Subsequent calls return the ** same context that was returned on prior calls. -** -** This routine is defined here in vdbe.c because it depends on knowing -** the internals of the sqlite3_context structure which is only defined in -** this source file. */ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ assert( p && p->pFunc && p->pFunc->xStep ); @@ -369,6 +365,11 @@ sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ return sqlite3_value_text( columnMem(pStmt,i) ); } +#if 0 +sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ + return columnMem(pStmt, i); +} +#endif #ifndef SQLITE_OMIT_UTF16 const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ return sqlite3_value_text16( columnMem(pStmt,i) ); diff --git a/ext/pdo_sqlite/sqlite/src/vdbeaux.c b/ext/pdo_sqlite/sqlite/src/vdbeaux.c index e64831e754..d9541a3fee 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbeaux.c +++ b/ext/pdo_sqlite/sqlite/src/vdbeaux.c @@ -25,7 +25,7 @@ ** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed ** as they are added to the instruction stream. */ -#ifndef NDEBUG +#ifdef SQLITE_DEBUG int sqlite3_vdbe_addop_trace = 0; #endif @@ -109,6 +109,7 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){ pOp->p2 = p2; pOp->p3 = 0; pOp->p3type = P3_NOTUSED; + p->expired = 0; #ifdef SQLITE_DEBUG if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]); #endif @@ -442,47 +443,6 @@ void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ } #endif -/* -** If the P3 operand to the specified instruction appears -** to be a quoted string token, then this procedure removes -** the quotes. -** -** The quoting operator can be either a grave ascent (ASCII 0x27) -** or a double quote character (ASCII 0x22). Two quotes in a row -** resolve to be a single actual quote character within the string. -*/ -void sqlite3VdbeDequoteP3(Vdbe *p, int addr){ - Op *pOp; - assert( p->magic==VDBE_MAGIC_INIT ); - if( p->aOp==0 ) return; - if( addr<0 || addr>=p->nOp ){ - addr = p->nOp - 1; - if( addr<0 ) return; - } - pOp = &p->aOp[addr]; - if( pOp->p3==0 || pOp->p3[0]==0 ) return; - if( pOp->p3type==P3_STATIC ){ - pOp->p3 = sqliteStrDup(pOp->p3); - pOp->p3type = P3_DYNAMIC; - } - assert( pOp->p3type==P3_DYNAMIC ); - sqlite3Dequote(pOp->p3); -} - -/* -** Search the current program starting at instruction addr for the given -** opcode and P2 value. Return the address plus 1 if found and 0 if not -** found. -*/ -int sqlite3VdbeFindOp(Vdbe *p, int addr, int op, int p2){ - int i; - assert( p->magic==VDBE_MAGIC_INIT ); - for(i=addr; inOp; i++){ - if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1; - } - return 0; -} - /* ** Return the opcode for a given address. */ @@ -952,18 +912,6 @@ int sqlite3VdbeAggReset(sqlite3 *db, Agg *pAgg, KeyInfo *pKeyInfo){ return SQLITE_OK; } - -/* -** Delete a keylist -*/ -void sqlite3VdbeKeylistFree(Keylist *p){ - while( p ){ - Keylist *pNext = p->pNext; - sqliteFree(p); - p = pNext; - } -} - /* ** Close a cursor and release all the resources that cursor happens ** to hold. @@ -1010,13 +958,10 @@ static void Cleanup(Vdbe *p){ } closeAllCursors(p); releaseMemArray(p->aMem, p->nMem); - if( p->pList ){ - sqlite3VdbeKeylistFree(p->pList); - p->pList = 0; - } + sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; icontextStackTop; i++){ - sqlite3VdbeKeylistFree(p->contextStack[i].pList); + sqlite3VdbeFifoClear(&p->contextStack[i].sFifo); } sqliteFree(p->contextStack); } @@ -1145,6 +1090,7 @@ static int vdbeCommit(sqlite3 *db){ */ #ifndef SQLITE_OMIT_DISKIO else{ + int needSync = 0; char *zMaster = 0; /* File-name for the master journal */ char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); OsFile master; @@ -1180,6 +1126,9 @@ static int vdbeCommit(sqlite3 *db){ if( pBt && sqlite3BtreeIsInTrans(pBt) ){ char const *zFile = sqlite3BtreeGetJournalname(pBt); if( zFile[0]==0 ) continue; /* Ignore :memory: databases */ + if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ + needSync = 1; + } rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); @@ -1196,7 +1145,7 @@ static int vdbeCommit(sqlite3 *db){ */ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); rc = sqlite3OsOpenDirectory(zMainFile, &master); - if( rc!=SQLITE_OK || (rc = sqlite3OsSync(&master))!=SQLITE_OK ){ + if( rc!=SQLITE_OK || (needSync && (rc=sqlite3OsSync(&master))!=SQLITE_OK) ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); @@ -1763,7 +1712,7 @@ int sqlite3VdbeSerialGet( pMem->flags = MEM_Int; return 6; } - case 6: /* 6-byte signed integer */ + case 6: /* 8-byte signed integer */ case 7: { /* IEEE floating point */ u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7]; diff --git a/ext/pdo_sqlite/sqlite/src/vdbefifo.c b/ext/pdo_sqlite/sqlite/src/vdbefifo.c new file mode 100644 index 0000000000..7ea6c050f9 --- /dev/null +++ b/ext/pdo_sqlite/sqlite/src/vdbefifo.c @@ -0,0 +1,114 @@ +/* +** 2005 June 16 +** +** 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 implements a FIFO queue of rowids used for processing +** UPDATE and DELETE statements. +*/ +#include "sqliteInt.h" +#include "vdbeInt.h" + +/* +** Allocate a new FifoPage and return a pointer to it. Return NULL if +** we run out of memory. Leave space on the page for nEntry entries. +*/ +static FifoPage *allocatePage(int nEntry){ + FifoPage *pPage; + if( nEntry>32767 ){ + nEntry = 32767; + } + pPage = sqliteMallocRaw( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) ); + if( pPage ){ + pPage->nSlot = nEntry; + pPage->iWrite = 0; + pPage->iRead = 0; + pPage->pNext = 0; + } + return pPage; +} + +/* +** Initialize a Fifo structure. +*/ +void sqlite3VdbeFifoInit(Fifo *pFifo){ + memset(pFifo, 0, sizeof(*pFifo)); +} + +/* +** Push a single 64-bit integer value into the Fifo. Return SQLITE_OK +** normally. SQLITE_NOMEM is returned if we are unable to allocate +** memory. +*/ +int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){ + FifoPage *pPage; + pPage = pFifo->pLast; + if( pPage==0 ){ + pPage = pFifo->pLast = pFifo->pFirst = allocatePage(20); + if( pPage==0 ){ + return SQLITE_NOMEM; + } + }else if( pPage->iWrite>=pPage->nSlot ){ + pPage->pNext = allocatePage(pFifo->nEntry); + if( pPage->pNext==0 ){ + return SQLITE_NOMEM; + } + pPage = pFifo->pLast = pPage->pNext; + } + pPage->aSlot[pPage->iWrite++] = val; + pFifo->nEntry++; + return SQLITE_OK; +} + +/* +** Extract a single 64-bit integer value from the Fifo. The integer +** extracted is the one least recently inserted. If the Fifo is empty +** return SQLITE_DONE. +*/ +int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){ + FifoPage *pPage; + if( pFifo->nEntry==0 ){ + return SQLITE_DONE; + } + assert( pFifo->nEntry>0 ); + pPage = pFifo->pFirst; + assert( pPage!=0 ); + assert( pPage->iWrite>pPage->iRead ); + assert( pPage->iWrite<=pPage->nSlot ); + assert( pPage->iReadnSlot ); + assert( pPage->iRead>=0 ); + *pVal = pPage->aSlot[pPage->iRead++]; + pFifo->nEntry--; + if( pPage->iRead>=pPage->iWrite ){ + pFifo->pFirst = pPage->pNext; + sqliteFree(pPage); + if( pFifo->nEntry==0 ){ + assert( pFifo->pLast==pPage ); + pFifo->pLast = 0; + }else{ + assert( pFifo->pFirst!=0 ); + } + }else{ + assert( pFifo->nEntry>0 ); + } + return SQLITE_OK; +} + +/* +** Delete all information from a Fifo object. Free all memory held +** by the Fifo. +*/ +void sqlite3VdbeFifoClear(Fifo *pFifo){ + FifoPage *pPage, *pNextPage; + for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){ + pNextPage = pPage->pNext; + sqliteFree(pPage); + } + sqlite3VdbeFifoInit(pFifo); +} diff --git a/ext/pdo_sqlite/sqlite/src/vdbemem.c b/ext/pdo_sqlite/sqlite/src/vdbemem.c index f08671f249..416beb6c78 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbemem.c +++ b/ext/pdo_sqlite/sqlite/src/vdbemem.c @@ -174,7 +174,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. */ if( fg & MEM_Real ){ - sqlite3_snprintf(NBFS, z, "%.15g", pMem->r); + sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r); }else{ assert( fg & MEM_Int ); sqlite3_snprintf(NBFS, z, "%lld", pMem->i); @@ -256,12 +256,14 @@ double sqlite3VdbeRealValue(Mem *pMem){ }else if( pMem->flags & MEM_Int ){ return (double)pMem->i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ + double val = 0.0; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ return SQLITE_NOMEM; } assert( pMem->z ); - return sqlite3AtoF(pMem->z, 0); + sqlite3AtoF(pMem->z, &val); + return val; }else{ return 0.0; } @@ -406,6 +408,7 @@ int sqlite3VdbeMemSetStr( switch( enc ){ case 0: pMem->flags |= MEM_Blob; + pMem->enc = SQLITE_UTF8; break; case SQLITE_UTF8: @@ -666,9 +669,9 @@ void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){ /* MEM_Null excludes all other types */ assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0 || (pMem->flags&MEM_Null)==0 ); - if( (pMem->flags & (MEM_Int|MEM_Real))==(MEM_Int|MEM_Real) ){ - assert( pMem->r==pMem->i ); - } + /* If the MEM is both real and integer, the values are equal */ + assert( (pMem->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) + || pMem->r==pMem->i ); } #endif diff --git a/ext/pdo_sqlite/sqlite/src/where.c b/ext/pdo_sqlite/sqlite/src/where.c index 553de70a25..fddc1f0155 100644 --- a/ext/pdo_sqlite/sqlite/src/where.c +++ b/ext/pdo_sqlite/sqlite/src/where.c @@ -20,21 +20,52 @@ */ #include "sqliteInt.h" +/* +** The number of bits in a Bitmask. "BMS" means "BitMask Size". +*/ +#define BMS (sizeof(Bitmask)*8) + +/* +** Determine the number of elements in an array. +*/ +#define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0])) + +/* +** Trace output macros +*/ +#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) +int sqlite3_where_trace = 0; +# define TRACE(X) if(sqlite3_where_trace) sqlite3DebugPrintf X +#else +# define TRACE(X) +#endif + +/* Forward reference +*/ +typedef struct WhereClause WhereClause; + /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. ** -** The idxLeft and idxRight fields are the VDBE cursor numbers for the -** table that contains the column that appears on the left-hand and -** right-hand side of ExprInfo.p. If either side of ExprInfo.p is -** something other than a simple column reference, then idxLeft or -** idxRight are -1. +** All WhereTerms are collected into a single WhereClause structure. +** The following identity holds: +** +** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm +** +** When a term is of the form: ** -** It is the VDBE cursor number is the value stored in Expr.iTable -** when Expr.op==TK_COLUMN and the value stored in SrcList.a[].iCursor. +** X ** -** prereqLeft, prereqRight, and prereqAll record sets of cursor numbers, +** where X is a column name and is one of certain operators, +** then WhereTerm.leftCursor and WhereTerm.leftColumn record the +** cursor number and column number for X. WhereTerm.operator records +** the using a bitmask encoding defined by WO_xxx below. The +** use of a bitmask encoding for the operator allows us to search +** quickly for terms that match any of several different operators. +** +** prereqRight and prereqAll record sets of cursor numbers, ** but they do so indirectly. A single ExprMaskSet structure translates ** cursor number into bits and the translated bit is stored in the prereq ** fields. The translation is used in order to maximize the number of @@ -45,39 +76,45 @@ ** beginning with 0 in order to make the best possible use of the available ** bits in the Bitmask. So, in the example above, the cursor numbers ** would be mapped into integers 0 through 7. -** -** prereqLeft tells us every VDBE cursor that is referenced on the -** left-hand side of ExprInfo.p. prereqRight does the same for the -** right-hand side of the expression. The following identity always -** holds: -** -** prereqAll = prereqLeft | prereqRight -** -** The ExprInfo.indexable field is true if the ExprInfo.p expression -** is of a form that might control an index. Indexable expressions -** look like this: -** -** -** -** Where is a simple column name and is on of the operators -** that allowedOp() recognizes. */ -typedef struct ExprInfo ExprInfo; -struct ExprInfo { - Expr *p; /* Pointer to the subexpression */ - u8 indexable; /* True if this subexprssion is usable by an index */ - short int idxLeft; /* p->pLeft is a column in this table number. -1 if - ** p->pLeft is not the column of any table */ - short int idxRight; /* p->pRight is a column in this table number. -1 if - ** p->pRight is not the column of any table */ - Bitmask prereqLeft; /* Bitmask of tables referenced by p->pLeft */ - Bitmask prereqRight; /* Bitmask of tables referenced by p->pRight */ +typedef struct WhereTerm WhereTerm; +struct WhereTerm { + Expr *pExpr; /* Pointer to the subexpression */ + i16 iParent; /* Disable pWC->a[iParent] when this term disabled */ + i16 leftCursor; /* Cursor number of X in "X " */ + i16 leftColumn; /* Column number of X in "X " */ + u16 operator; /* A WO_xx value describing */ + u8 flags; /* Bit flags. See below */ + u8 nChild; /* Number of children that must disable us */ + WhereClause *pWC; /* The clause this term is part of */ + Bitmask prereqRight; /* Bitmask of tables used by pRight */ Bitmask prereqAll; /* Bitmask of tables referenced by p */ }; +/* +** Allowed values of WhereTerm.flags +*/ +#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(pExpr) */ +#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */ +#define TERM_CODED 0x04 /* This term is already coded */ +#define TERM_COPIED 0x08 /* Has a child */ +#define TERM_OR_OK 0x10 /* Used during OR-clause processing */ + +/* +** An instance of the following structure holds all information about a +** WHERE clause. Mostly this is a container for one or more WhereTerms. +*/ +struct WhereClause { + Parse *pParse; /* The parser context */ + int nTerm; /* Number of terms */ + int nSlot; /* Number of entries in a[] */ + WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ + WhereTerm aStatic[10]; /* Initial static space for a[] */ +}; + /* ** An instance of the following structure keeps track of a mapping -** between VDBE cursor numbers and bits of the bitmasks in ExprInfo. +** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. ** ** The VDBE cursor numbers are small integers contained in ** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE @@ -107,43 +144,117 @@ struct ExprMaskSet { int ix[sizeof(Bitmask)*8]; /* Cursor assigned to each bit */ }; + /* -** Determine the number of elements in an array. +** Bitmasks for the operators that indices are able to exploit. An +** OR-ed combination of these values can be used when searching for +** terms in the where clause. */ -#define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0])) +#define WO_IN 1 +#define WO_EQ 2 +#define WO_LT (WO_EQ<<(TK_LT-TK_EQ)) +#define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) +#define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) +#define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) + +/* +** Value for flags returned by bestIndex() +*/ +#define WHERE_ROWID_EQ 0x0001 /* rowid=EXPR or rowid IN (...) */ +#define WHERE_ROWID_RANGE 0x0002 /* rowidEXPR */ +#define WHERE_COLUMN_EQ 0x0010 /* x=EXPR or x IN (...) */ +#define WHERE_COLUMN_RANGE 0x0020 /* xEXPR */ +#define WHERE_COLUMN_IN 0x0040 /* x IN (...) */ +#define WHERE_TOP_LIMIT 0x0100 /* xEXPR or x>=EXPR constraint */ +#define WHERE_IDX_ONLY 0x0800 /* Use index only - omit table */ +#define WHERE_ORDERBY 0x1000 /* Output will appear in correct order */ +#define WHERE_REVERSE 0x2000 /* Scan in reverse order */ +#define WHERE_UNIQUE 0x4000 /* Selects no more than one row */ + +/* +** Initialize a preallocated WhereClause structure. +*/ +static void whereClauseInit(WhereClause *pWC, Parse *pParse){ + pWC->pParse = pParse; + pWC->nTerm = 0; + pWC->nSlot = ARRAYSIZE(pWC->aStatic); + pWC->a = pWC->aStatic; +} + +/* +** Deallocate a WhereClause structure. The WhereClause structure +** itself is not freed. This routine is the inverse of whereClauseInit(). +*/ +static void whereClauseClear(WhereClause *pWC){ + int i; + WhereTerm *a; + for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ + if( a->flags & TERM_DYNAMIC ){ + sqlite3ExprDelete(a->pExpr); + } + } + if( pWC->a!=pWC->aStatic ){ + sqliteFree(pWC->a); + } +} + +/* +** Add a new entries to the WhereClause structure. Increase the allocated +** space as necessary. +** +** WARNING: This routine might reallocate the space used to store +** WhereTerms. All pointers to WhereTerms should be invalided after +** calling this routine. Such pointers may be reinitialized by referencing +** the pWC->a[] array. +*/ +static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){ + WhereTerm *pTerm; + int idx; + if( pWC->nTerm>=pWC->nSlot ){ + WhereTerm *pOld = pWC->a; + pWC->a = sqliteMalloc( sizeof(pWC->a[0])*pWC->nSlot*2 ); + if( pWC->a==0 ) return 0; + memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); + if( pOld!=pWC->aStatic ){ + sqliteFree(pOld); + } + pWC->nSlot *= 2; + } + pTerm = &pWC->a[idx = pWC->nTerm]; + pWC->nTerm++; + pTerm->pExpr = p; + pTerm->flags = flags; + pTerm->pWC = pWC; + pTerm->iParent = -1; + return idx; +} /* ** This routine identifies subexpressions in the WHERE clause where -** each subexpression is separate by the AND operator. aSlot is -** filled with pointers to the subexpressions. For example: +** each subexpression is separate by the AND operator or some other +** operator specified in the op parameter. The WhereClause structure +** is filled with pointers to subexpressions. For example: ** ** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22) ** \________/ \_______________/ \________________/ ** slot[0] slot[1] slot[2] ** ** The original WHERE clause in pExpr is unaltered. All this routine -** does is make aSlot[] entries point to substructure within pExpr. +** does is make slot[] entries point to substructure within pExpr. ** -** aSlot[] is an array of subexpressions structures. There are nSlot -** spaces left in this array. This routine finds as many AND-separated -** subexpressions as it can and puts pointers to those subexpressions -** into aSlot[] entries. The return value is the number of slots filled. +** In the previous sentence and in the diagram, "slot[]" refers to +** the WhereClause.a[] array. This array grows as needed to contain +** all terms of the WHERE clause. */ -static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){ - int cnt = 0; - if( pExpr==0 || nSlot<1 ) return 0; - if( nSlot==1 || pExpr->op!=TK_AND ){ - aSlot[0].p = pExpr; - return 1; - } - if( pExpr->pLeft->op!=TK_AND ){ - aSlot[0].p = pExpr->pLeft; - cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight); +static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){ + if( pExpr==0 ) return; + if( pExpr->op!=op ){ + whereClauseInsert(pWC, pExpr, 0); }else{ - cnt = exprSplit(nSlot, aSlot, pExpr->pLeft); - cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight); + whereSplit(pWC, pExpr->pLeft, op); + whereSplit(pWC, pExpr->pRight, op); } - return cnt; } /* @@ -167,18 +278,17 @@ static Bitmask getMask(ExprMaskSet *pMaskSet, int iCursor){ /* ** Create a new mask for cursor iCursor. +** +** There is one cursor per table in the FROM clause. The number of +** tables in the FROM clause is limited by a test early in the +** sqlite3WhereBegin() routien. So we know that the pMaskSet->ix[] +** array will never overflow. */ static void createMask(ExprMaskSet *pMaskSet, int iCursor){ - if( pMaskSet->nix) ){ - pMaskSet->ix[pMaskSet->n++] = iCursor; - } + assert( pMaskSet->n < ARRAYSIZE(pMaskSet->ix) ); + pMaskSet->ix[pMaskSet->n++] = iCursor; } -/* -** Destroy an expression mask set -*/ -#define freeMaskSet(P) /* NO-OP */ - /* ** This routine walks (recursively) an expression tree and generates ** a bitmask indicating which tables are used in that expression @@ -189,7 +299,9 @@ static void createMask(ExprMaskSet *pMaskSet, int iCursor){ ** the header comment on that routine for additional information. ** The sqlite3ExprResolveNames() routines looks for column names and ** sets their opcodes to TK_COLUMN and their Expr.iTable fields to -** the VDBE cursor number of the table. +** the VDBE cursor number of the table. This routine just has to +** translate the cursor numbers into bitmask values and OR all +** the bitmasks together. */ static Bitmask exprListTableUsage(ExprMaskSet *, ExprList *); static Bitmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){ @@ -229,7 +341,10 @@ static Bitmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){ ** "=", "<", ">", "<=", ">=", and "IN". */ static int allowedOp(int op){ - assert( TK_GT==TK_LE-1 && TK_LE==TK_LT-1 && TK_LT==TK_GE-1 && TK_EQ==TK_GT-1); + assert( TK_GT>TK_EQ && TK_GTTK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE); } @@ -239,76 +354,349 @@ static int allowedOp(int op){ #define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} /* -** Return the index in the SrcList that uses cursor iCur. If iCur is -** used by the first entry in SrcList return 0. If iCur is used by -** the second entry return 1. And so forth. +** Commute a comparision operator. Expressions of the form "X op Y" +** are converted into "Y op X". +*/ +static void exprCommute(Expr *pExpr){ + assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); + SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl); + SWAP(Expr*,pExpr->pRight,pExpr->pLeft); + if( pExpr->op>=TK_GT ){ + assert( TK_LT==TK_GT+2 ); + assert( TK_GE==TK_LE+2 ); + assert( TK_GT>TK_EQ ); + assert( TK_GTop>=TK_GT && pExpr->op<=TK_GE ); + pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; + } +} + +/* +** Translate from TK_xx operator to WO_xx bitmask. +*/ +static int operatorMask(int op){ + int c; + assert( allowedOp(op) ); + if( op==TK_IN ){ + c = WO_IN; + }else{ + c = WO_EQ<<(op-TK_EQ); + } + assert( op!=TK_IN || c==WO_IN ); + assert( op!=TK_EQ || c==WO_EQ ); + assert( op!=TK_LT || c==WO_LT ); + assert( op!=TK_LE || c==WO_LE ); + assert( op!=TK_GT || c==WO_GT ); + assert( op!=TK_GE || c==WO_GE ); + return c; +} + +/* +** Search for a term in the WHERE clause that is of the form "X " +** where X is a reference to the iColumn of table iCur and is one of +** the WO_xx operator codes specified by the op parameter. +** Return a pointer to the term. Return 0 if not found. +*/ +static WhereTerm *findTerm( + WhereClause *pWC, /* The WHERE clause to be searched */ + int iCur, /* Cursor number of LHS */ + int iColumn, /* Column number of LHS */ + Bitmask notReady, /* RHS must not overlap with this mask */ + u16 op, /* Mask of WO_xx values describing operator */ + Index *pIdx /* Must be compatible with this index, if not NULL */ +){ + WhereTerm *pTerm; + int k; + for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ + if( pTerm->leftCursor==iCur + && (pTerm->prereqRight & notReady)==0 + && pTerm->leftColumn==iColumn + && (pTerm->operator & op)!=0 + ){ + if( iCur>=0 && pIdx ){ + Expr *pX = pTerm->pExpr; + CollSeq *pColl; + char idxaff; + int k; + Parse *pParse = pWC->pParse; + + idxaff = pIdx->pTable->aCol[iColumn].affinity; + if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue; + pColl = sqlite3ExprCollSeq(pParse, pX->pLeft); + if( !pColl ){ + if( pX->pRight ){ + pColl = sqlite3ExprCollSeq(pParse, pX->pRight); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + } + for(k=0; knColumn && pIdx->aiColumn[k]!=iColumn; k++){} + assert( knColumn ); + if( pColl!=pIdx->keyInfo.aColl[k] ) continue; + } + return pTerm; + } + } + return 0; +} + +/* Forward reference */ +static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int); + +/* +** Call exprAnalyze on all terms in a WHERE clause. +** ** -** SrcList is the set of tables in the FROM clause in the order that -** they will be processed. The value returned here gives us an index -** of which tables will be processed first. */ -static int tableOrder(SrcList *pList, int iCur){ +static void exprAnalyzeAll( + SrcList *pTabList, /* the FROM clause */ + ExprMaskSet *pMaskSet, /* table masks */ + WhereClause *pWC /* the WHERE clause to be analyzed */ +){ int i; - struct SrcList_item *pItem; - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->iCursor==iCur ) return i; + for(i=pWC->nTerm-1; i>=0; i--){ + exprAnalyze(pTabList, pMaskSet, pWC, i); } - return -1; } +#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* -** The input to this routine is an ExprInfo structure with only the -** "p" field filled in. The job of this routine is to analyze the -** subexpression and populate all the other fields of the ExprInfo +** Check to see if the given expression is a LIKE or GLOB operator that +** can be optimized using inequality constraints. Return TRUE if it is +** so and false if not. +** +** In order for the operator to be optimizible, the RHS must be a string +** literal that does not begin with a wildcard. +*/ +static int isLikeOrGlob( + sqlite3 *db, /* The database */ + Expr *pExpr, /* Test this expression */ + int *pnPattern, /* Number of non-wildcard prefix characters */ + int *pisComplete /* True if the only wildcard is % in the last character */ +){ + const char *z; + Expr *pRight, *pLeft; + ExprList *pList; + int c, cnt; + char wc[3]; + if( !sqlite3IsLikeFunction(db, pExpr, wc) ){ + return 0; + } + pList = pExpr->pList; + pRight = pList->a[0].pExpr; + if( pRight->op!=TK_STRING ){ + return 0; + } + pLeft = pList->a[1].pExpr; + if( pLeft->op!=TK_COLUMN ){ + return 0; + } + sqlite3DequoteExpr(pRight); + z = pRight->token.z; + for(cnt=0; (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2]; cnt++){} + if( cnt==0 || 255==(u8)z[cnt] ){ + return 0; + } + *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; + *pnPattern = cnt; + return 1; +} +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + +/* +** The input to this routine is an WhereTerm structure with only the +** "pExpr" field filled in. The job of this routine is to analyze the +** subexpression and populate all the other fields of the WhereTerm ** structure. +** +** If the expression is of the form " X" it gets commuted +** to the standard form of "X ". If the expression is of +** the form "X Y" where both X and Y are columns, then the original +** expression is unchanged and a new virtual expression of the form +** "Y X" is added to the WHERE clause. */ -static void exprAnalyze(SrcList *pSrc, ExprMaskSet *pMaskSet, ExprInfo *pInfo){ - Expr *pExpr = pInfo->p; - pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); - pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight); - pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr); - pInfo->indexable = 0; - pInfo->idxLeft = -1; - pInfo->idxRight = -1; - if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){ - if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){ - pInfo->idxRight = pExpr->pRight->iTable; - pInfo->indexable = 1; +static void exprAnalyze( + SrcList *pSrc, /* the FROM clause */ + ExprMaskSet *pMaskSet, /* table masks */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + WhereTerm *pTerm = &pWC->a[idxTerm]; + Expr *pExpr = pTerm->pExpr; + Bitmask prereqLeft; + Bitmask prereqAll; + int idxRight; + int nPattern; + int isComplete; + + if( sqlite3_malloc_failed ) return; + prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); + pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight); + pTerm->prereqAll = prereqAll = exprTableUsage(pMaskSet, pExpr); + pTerm->leftCursor = -1; + pTerm->iParent = -1; + pTerm->operator = 0; + idxRight = -1; + if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){ + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + if( pLeft->op==TK_COLUMN ){ + pTerm->leftCursor = pLeft->iTable; + pTerm->leftColumn = pLeft->iColumn; + pTerm->operator = operatorMask(pExpr->op); } - if( pExpr->pLeft->op==TK_COLUMN ){ - pInfo->idxLeft = pExpr->pLeft->iTable; - pInfo->indexable = 1; + if( pRight && pRight->op==TK_COLUMN ){ + WhereTerm *pNew; + Expr *pDup; + if( pTerm->leftCursor>=0 ){ + int idxNew; + pDup = sqlite3ExprDup(pExpr); + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + if( idxNew==0 ) return; + pNew = &pWC->a[idxNew]; + pNew->iParent = idxTerm; + pTerm = &pWC->a[idxTerm]; + pTerm->nChild = 1; + pTerm->flags |= TERM_COPIED; + }else{ + pDup = pExpr; + pNew = pTerm; + } + exprCommute(pDup); + pLeft = pDup->pLeft; + pNew->leftCursor = pLeft->iTable; + pNew->leftColumn = pLeft->iColumn; + pNew->prereqRight = prereqLeft; + pNew->prereqAll = prereqAll; + pNew->operator = operatorMask(pDup->op); } } - if( pInfo->indexable ){ - assert( pInfo->idxLeft!=pInfo->idxRight ); - - /* We want the expression to be of the form "X = expr", not "expr = X". - ** So flip it over if necessary. If the expression is "X = Y", then - ** we want Y to come from an earlier table than X. - ** - ** The collating sequence rule is to always choose the left expression. - ** So if we do a flip, we also have to move the collating sequence. - */ - if( tableOrder(pSrc,pInfo->idxLeft)idxRight) ){ - assert( pExpr->op!=TK_IN ); - SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl); - SWAP(Expr*,pExpr->pRight,pExpr->pLeft); - if( pExpr->op>=TK_GT ){ - assert( TK_LT==TK_GT+2 ); - assert( TK_GE==TK_LE+2 ); - assert( TK_GT>TK_EQ ); - assert( TK_GTop>=TK_GT && pExpr->op<=TK_GE ); - pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; + +#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION + /* If a term is the BETWEEN operator, create two new virtual terms + ** that define the range that the BETWEEN implements. + */ + else if( pExpr->op==TK_BETWEEN ){ + ExprList *pList = pExpr->pList; + int i; + static const u8 ops[] = {TK_GE, TK_LE}; + assert( pList!=0 ); + assert( pList->nExpr==2 ); + for(i=0; i<2; i++){ + Expr *pNewExpr; + int idxNew; + pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(pExpr->pLeft), + sqlite3ExprDup(pList->a[i].pExpr), 0); + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pMaskSet, pWC, idxNew); + pTerm = &pWC->a[idxTerm]; + pWC->a[idxNew].iParent = idxTerm; + } + pTerm->nChild = 2; + } +#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */ + +#ifndef SQLITE_OMIT_OR_OPTIMIZATION + /* Attempt to convert OR-connected terms into an IN operator so that + ** they can make use of indices. + */ + else if( pExpr->op==TK_OR ){ + int ok; + int i, j; + int iColumn, iCursor; + WhereClause sOr; + WhereTerm *pOrTerm; + + assert( (pTerm->flags & TERM_DYNAMIC)==0 ); + whereClauseInit(&sOr, pWC->pParse); + whereSplit(&sOr, pExpr, TK_OR); + exprAnalyzeAll(pSrc, pMaskSet, &sOr); + assert( sOr.nTerm>0 ); + j = 0; + do{ + iColumn = sOr.a[j].leftColumn; + iCursor = sOr.a[j].leftCursor; + ok = iCursor>=0; + for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){ + if( pOrTerm->operator!=WO_EQ ){ + goto or_not_possible; + } + if( pOrTerm->leftCursor==iCursor && pOrTerm->leftColumn==iColumn ){ + pOrTerm->flags |= TERM_OR_OK; + }else if( (pOrTerm->flags & TERM_COPIED)!=0 || + ((pOrTerm->flags & TERM_VIRTUAL)!=0 && + (sOr.a[pOrTerm->iParent].flags & TERM_OR_OK)!=0) ){ + pOrTerm->flags &= ~TERM_OR_OK; + }else{ + ok = 0; + } + } + }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j=0 && ok; i--, pOrTerm++){ + if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue; + pDup = sqlite3ExprDup(pOrTerm->pExpr->pRight); + pList = sqlite3ExprListAppend(pList, pDup, 0); + } + pDup = sqlite3Expr(TK_COLUMN, 0, 0, 0); + if( pDup ){ + pDup->iTable = iCursor; + pDup->iColumn = iColumn; } - SWAP(unsigned, pInfo->prereqLeft, pInfo->prereqRight); - SWAP(short int, pInfo->idxLeft, pInfo->idxRight); + pNew = sqlite3Expr(TK_IN, pDup, 0, 0); + if( pNew ) pNew->pList = pList; + pTerm->pExpr = pNew; + pTerm->flags |= TERM_DYNAMIC; + exprAnalyze(pSrc, pMaskSet, pWC, idxTerm); + pTerm = &pWC->a[idxTerm]; } - } +or_not_possible: + whereClauseClear(&sOr); + } +#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ +#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION + /* Add constraints to reduce the search space on a LIKE or GLOB + ** operator. + */ + if( isLikeOrGlob(pWC->pParse->db, pExpr, &nPattern, &isComplete) ){ + Expr *pLeft, *pRight; + Expr *pStr1, *pStr2; + Expr *pNewExpr1, *pNewExpr2; + int idxNew1, idxNew2; + + pLeft = pExpr->pList->a[1].pExpr; + pRight = pExpr->pList->a[0].pExpr; + pStr1 = sqlite3Expr(TK_STRING, 0, 0, 0); + if( pStr1 ){ + sqlite3TokenCopy(&pStr1->token, &pRight->token); + pStr1->token.n = nPattern; + } + pStr2 = sqlite3ExprDup(pStr1); + if( pStr2 ){ + assert( pStr2->token.dyn ); + ++*(u8*)&pStr2->token.z[nPattern-1]; + } + pNewExpr1 = sqlite3Expr(TK_GE, sqlite3ExprDup(pLeft), pStr1, 0); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pMaskSet, pWC, idxNew1); + pNewExpr2 = sqlite3Expr(TK_LT, sqlite3ExprDup(pLeft), pStr2, 0); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pMaskSet, pWC, idxNew2); + pTerm = &pWC->a[idxTerm]; + if( isComplete ){ + pWC->a[idxNew1].iParent = idxTerm; + pWC->a[idxNew2].iParent = idxTerm; + pTerm->nChild = 2; + } + } +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ } + /* ** This routine decides if pIdx can be used to satisfy the ORDER BY ** clause. If it can, it returns 1. If pIdx cannot satisfy the @@ -322,10 +710,6 @@ static void exprAnalyze(SrcList *pSrc, ExprMaskSet *pMaskSet, ExprInfo *pInfo){ ** constraints. Any of these columns may be missing from the ORDER BY ** clause and the match can still be a success. ** -** If the index is UNIQUE, then the ORDER BY clause is allowed to have -** additional terms past the end of the index and the match will still -** be a success. -** ** All terms of the ORDER BY that match against the index must be either ** ASC or DESC. (Terms of the ORDER BY clause past the end of a UNIQUE ** index do not need to satisfy this constraint.) The *pbRev value is @@ -394,10 +778,9 @@ static int isSortingIndex( } /* The index can be used for sorting if all terms of the ORDER BY clause - ** or covered or if we ran out of index columns and the it is a UNIQUE - ** index. + ** are covered. */ - if( j>=nTerm || (i>=pIdx->nColumn && pIdx->onError!=OE_None) ){ + if( j>=nTerm ){ *pbRev = sortOrder==SQLITE_SO_DESC; return 1; } @@ -426,6 +809,249 @@ static int sortableByRowid( return 0; } +/* +** Prepare a crude estimate of the logorithm of the input value. +** The results need not be exact. This is only used for estimating +** the total cost of performing operatings with O(logN) or O(NlogN) +** complexity. Because N is just a guess, it is no great tragedy if +** logN is a little off. +*/ +static double estLog(double N){ + double logN = 1.0; + double x = 10.0; + while( N>x ){ + logN += 1.0; + x *= 10; + } + return logN; +} + +/* +** Find the best index for accessing a particular table. Return a pointer +** to the index, flags that describe how the index should be used, the +** number of equality constraints, and the "cost" for this index. +** +** The lowest cost index wins. The cost is an estimate of the amount of +** CPU and disk I/O need to process the request using the selected index. +** Factors that influence cost include: +** +** * The estimated number of rows that will be retrieved. (The +** fewer the better.) +** +** * Whether or not sorting must occur. +** +** * Whether or not there must be separate lookups in the +** index and in the main table. +** +*/ +static double bestIndex( + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause */ + struct SrcList_item *pSrc, /* The FROM clause term to search */ + Bitmask notReady, /* Mask of cursors that are not available */ + ExprList *pOrderBy, /* The order by clause */ + Index **ppIndex, /* Make *ppIndex point to the best index */ + int *pFlags, /* Put flags describing this choice in *pFlags */ + int *pnEq /* Put the number of == or IN constraints here */ +){ + WhereTerm *pTerm; + Index *bestIdx = 0; /* Index that gives the lowest cost */ + double lowestCost = 1.0e99; /* The cost of using bestIdx */ + int bestFlags = 0; /* Flags associated with bestIdx */ + int bestNEq = 0; /* Best value for nEq */ + int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ + Index *pProbe; /* An index we are evaluating */ + int rev; /* True to scan in reverse order */ + int flags; /* Flags associated with pProbe */ + int nEq; /* Number of == or IN constraints */ + double cost; /* Cost of using pProbe */ + + TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady)); + + /* Check for a rowid=EXPR or rowid IN (...) constraints + */ + pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0); + if( pTerm ){ + Expr *pExpr; + *ppIndex = 0; + bestFlags = WHERE_ROWID_EQ; + if( pTerm->operator & WO_EQ ){ + /* Rowid== is always the best pick. Look no further. Because only + ** a single row is generated, output is always in sorted order */ + *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE; + *pnEq = 1; + TRACE(("... best is rowid\n")); + return 0.0; + }else if( (pExpr = pTerm->pExpr)->pList!=0 ){ + /* Rowid IN (LIST): cost is NlogN where N is the number of list + ** elements. */ + lowestCost = pExpr->pList->nExpr; + lowestCost *= estLog(lowestCost); + }else{ + /* Rowid IN (SELECT): cost is NlogN where N is the number of rows + ** in the result of the inner select. We have no way to estimate + ** that value so make a wild guess. */ + lowestCost = 200.0; + } + TRACE(("... rowid IN cost: %.9g\n", lowestCost)); + } + + /* Estimate the cost of a table scan. If we do not know how many + ** entries are in the table, use 1 million as a guess. + */ + pProbe = pSrc->pTab->pIndex; + cost = pProbe ? pProbe->aiRowEst[0] : 1000000.0; + TRACE(("... table scan base cost: %.9g\n", cost)); + flags = WHERE_ROWID_RANGE; + + /* Check for constraints on a range of rowids in a table scan. + */ + pTerm = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE|WO_GT|WO_GE, 0); + if( pTerm ){ + if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){ + flags |= WHERE_TOP_LIMIT; + cost *= 0.333; /* Guess that rowidEXPR eliminates two-thirds of rows */ + } + TRACE(("... rowid range reduces cost to %.9g\n", cost)); + }else{ + flags = 0; + } + + /* If the table scan does not satisfy the ORDER BY clause, increase + ** the cost by NlogN to cover the expense of sorting. */ + if( pOrderBy ){ + if( sortableByRowid(iCur, pOrderBy, &rev) ){ + flags |= WHERE_ORDERBY|WHERE_ROWID_RANGE; + if( rev ){ + flags |= WHERE_REVERSE; + } + }else{ + cost += cost*estLog(cost); + TRACE(("... sorting increases cost to %.9g\n", cost)); + } + } + if( costpNext){ + int i; /* Loop counter */ + double inMultiplier = 1.0; + + TRACE(("... index %s:\n", pProbe->zName)); + + /* Count the number of columns in the index that are satisfied + ** by x=EXPR constraints or x IN (...) constraints. + */ + flags = 0; + for(i=0; inColumn; i++){ + int j = pProbe->aiColumn[i]; + pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe); + if( pTerm==0 ) break; + flags |= WHERE_COLUMN_EQ; + if( pTerm->operator & WO_IN ){ + Expr *pExpr = pTerm->pExpr; + flags |= WHERE_COLUMN_IN; + if( pExpr->pSelect!=0 ){ + inMultiplier *= 100.0; + }else if( pExpr->pList!=0 ){ + inMultiplier *= pExpr->pList->nExpr + 1.0; + } + } + } + cost = pProbe->aiRowEst[i] * inMultiplier * estLog(inMultiplier); + nEq = i; + if( pProbe->onError!=OE_None && (flags & WHERE_COLUMN_IN)==0 + && nEq==pProbe->nColumn ){ + flags |= WHERE_UNIQUE; + } + TRACE(("...... nEq=%d inMult=%.9g cost=%.9g\n", nEq, inMultiplier, cost)); + + /* Look for range constraints + */ + if( nEqnColumn ){ + int j = pProbe->aiColumn[nEq]; + pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe); + if( pTerm ){ + flags |= WHERE_COLUMN_RANGE; + if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){ + flags |= WHERE_TOP_LIMIT; + cost *= 0.333; + } + if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){ + flags |= WHERE_BTM_LIMIT; + cost *= 0.333; + } + TRACE(("...... range reduces cost to %.9g\n", cost)); + } + } + + /* Add the additional cost of sorting if that is a factor. + */ + if( pOrderBy ){ + if( (flags & WHERE_COLUMN_IN)==0 && + isSortingIndex(pParse,pProbe,pSrc->pTab,iCur,pOrderBy,nEq,&rev) ){ + if( flags==0 ){ + flags = WHERE_COLUMN_RANGE; + } + flags |= WHERE_ORDERBY; + if( rev ){ + flags |= WHERE_REVERSE; + } + }else{ + cost += cost*estLog(cost); + TRACE(("...... orderby increases cost to %.9g\n", cost)); + } + } + + /* Check to see if we can get away with using just the index without + ** ever reading the table. If that is the case, then halve the + ** cost of this index. + */ + if( flags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){ + Bitmask m = pSrc->colUsed; + int j; + for(j=0; jnColumn; j++){ + int x = pProbe->aiColumn[j]; + if( xzName : "(none)", lowestCost, bestFlags, bestNEq)); + *pFlags = bestFlags; + *pnEq = bestNEq; + return lowestCost; +} + /* ** Disable a term in the WHERE clause. Except, do not disable the term @@ -449,10 +1075,18 @@ static int sortableByRowid( ** too much. If we disabled in (1), we'd get the wrong answer. ** See ticket #813. */ -static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){ - Expr *pExpr = *ppExpr; - if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){ - *ppExpr = 0; +static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ + if( pTerm + && (pTerm->flags & TERM_CODED)==0 + && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) + ){ + pTerm->flags |= TERM_CODED; + if( pTerm->iParent>=0 ){ + WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent]; + if( (--pOther->nChild)==0 ){ + disableTerm(pLevel, pOther); + } + } } } @@ -475,41 +1109,138 @@ static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){ sqlite3IndexAffinityStr(v, pIdx); } + /* -** Generate code for an equality term of the WHERE clause. An equality -** term can be either X=expr or X IN (...). pTerm is the X. +** Generate code for a single equality term of the WHERE clause. An equality +** term can be either X=expr or X IN (...). pTerm is the term to be +** coded. +** +** The current value for the constraint is left on the top of the stack. +** +** For a constraint of the form X=expr, the expression is evaluated and its +** result is left on the stack. For constraints of the form X IN (...) +** this routine sets up a loop that will iterate over all values of X. */ static void codeEqualityTerm( Parse *pParse, /* The parsing context */ - ExprInfo *pTerm, /* The term of the WHERE clause to be coded */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ int brk, /* Jump here to abandon the loop */ WhereLevel *pLevel /* When level of the FROM clause we are working on */ ){ - Expr *pX = pTerm->p; + Expr *pX = pTerm->pExpr; if( pX->op!=TK_IN ){ assert( pX->op==TK_EQ ); sqlite3ExprCode(pParse, pX->pRight); #ifndef SQLITE_OMIT_SUBQUERY }else{ int iTab; + int *aIn; Vdbe *v = pParse->pVdbe; sqlite3CodeSubselect(pParse, pX); iTab = pX->iTable; sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk); VdbeComment((v, "# %.*s", pX->span.n, pX->span.z)); - pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); - pLevel->inOp = OP_Next; - pLevel->inP1 = iTab; + pLevel->nIn++; + pLevel->aInLoop = aIn = sqliteRealloc(pLevel->aInLoop, + sizeof(pLevel->aInLoop[0])*3*pLevel->nIn); + if( aIn ){ + aIn += pLevel->nIn*3 - 3; + aIn[0] = OP_Next; + aIn[1] = iTab; + aIn[2] = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); + }else{ + pLevel->nIn = 0; + } #endif } - disableTerm(pLevel, &pTerm->p); + disableTerm(pLevel, pTerm); } /* -** The number of bits in a Bitmask +** Generate code that will evaluate all == and IN constraints for an +** index. The values for all constraints are left on the stack. +** +** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). +** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 +** The index has as many as three equality constraints, but in this +** example, the third "c" value is an inequality. So only two +** constraints are coded. This routine will generate code to evaluate +** a==5 and b IN (1,2,3). The current values for a and b will be left +** on the stack - a is the deepest and b the shallowest. +** +** In the example above nEq==2. But this subroutine works for any value +** of nEq including 0. If nEq==0, this routine is nearly a no-op. +** The only thing it does is allocate the pLevel->iMem memory cell. +** +** This routine always allocates at least one memory cell and puts +** the address of that memory cell in pLevel->iMem. The code that +** calls this routine will use pLevel->iMem to store the termination +** key value of the loop. If one or more IN operators appear, then +** this routine allocates an additional nEq memory cells for internal +** use. */ -#define BMS (sizeof(Bitmask)*8-1) +static void codeAllEqualityTerms( + Parse *pParse, /* Parsing context */ + WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ + WhereClause *pWC, /* The WHERE clause */ + Bitmask notReady, /* Which parts of FROM have not yet been coded */ + int brk /* Jump here to end the loop */ +){ + int nEq = pLevel->nEq; /* The number of == or IN constraints to code */ + int termsInMem = 0; /* If true, store value in mem[] cells */ + Vdbe *v = pParse->pVdbe; /* The virtual machine under construction */ + Index *pIdx = pLevel->pIdx; /* The index being used for this loop */ + int iCur = pLevel->iTabCur; /* The cursor of the table */ + WhereTerm *pTerm; /* A single constraint term */ + int j; /* Loop counter */ + + /* Figure out how many memory cells we will need then allocate them. + ** We always need at least one used to store the loop terminator + ** value. If there are IN operators we'll need one for each == or + ** IN constraint. + */ + pLevel->iMem = pParse->nMem++; + if( pLevel->flags & WHERE_COLUMN_IN ){ + pParse->nMem += pLevel->nEq; + termsInMem = 1; + } + + /* Evaluate the equality constraints + */ + for(j=0; jnColumn; j++){ + int k = pIdx->aiColumn[j]; + pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN, pIdx); + if( pTerm==0 ) break; + assert( (pTerm->flags & TERM_CODED)==0 ); + codeEqualityTerm(pParse, pTerm, brk, pLevel); + if( termsInMem ){ + sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1); + } + } + assert( j==nEq ); + + /* Make sure all the constraint values are on the top of the stack + */ + if( termsInMem ){ + for(j=0; jiMem+j+1, 0); + } + } +} + +#ifdef SQLITE_TEST +/* +** The following variable holds a text description of query plan generated +** by the most recent call to sqlite3WhereBegin(). Each call to WhereBegin +** overwrites the previous. This information is used for testing and +** analysis only. +*/ +char sqlite3_query_plan[BMS*2*40]; /* Text of the join */ +static int nQPlan = 0; /* Next free slow in _query_plan[] */ + +#endif /* SQLITE_TEST */ + /* @@ -538,6 +1269,12 @@ static void codeEqualityTerm( ** end |-- by sqlite3WhereEnd() ** end / ** +** Note that the loops might not be nested in the order in which they +** appear in the FROM clause if a different order is better able to make +** use of indices. Note also that when the IN operator appears in +** the WHERE clause, it might result in additional nested loops for +** scanning through all values on the right-hand side of the IN. +** ** There are Btree cursors associated with each table. t1 uses cursor ** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. ** And so forth. This routine generates code to open those VDBE cursors @@ -604,47 +1341,36 @@ WhereInfo *sqlite3WhereBegin( WhereInfo *pWInfo; /* Will become the return value of this function */ Vdbe *v = pParse->pVdbe; /* The virtual database engine */ int brk, cont = 0; /* Addresses used during code generation */ - int nExpr; /* Number of subexpressions in the WHERE clause */ - Bitmask loopMask; /* One bit set for each outer loop */ - ExprInfo *pTerm; /* A single term in the WHERE clause; ptr to aExpr[] */ - ExprMaskSet maskSet; /* The expression mask set */ - int iDirectEq[BMS]; /* Term of the form ROWID==X for the N-th table */ - int iDirectLt[BMS]; /* Term of the form ROWIDX or ROWID>=X */ - ExprInfo aExpr[101]; /* The WHERE clause is divided into these terms */ + Bitmask notReady; /* Cursors that are not yet positioned */ + WhereTerm *pTerm; /* A single term in the WHERE clause */ + ExprMaskSet maskSet; /* The expression mask set */ + WhereClause wc; /* The WHERE clause is divided into these terms */ struct SrcList_item *pTabItem; /* A single entry from pTabList */ WhereLevel *pLevel; /* A single level in the pWInfo list */ + int iFrom; /* First unused FROM clause element */ + int andFlags; /* AND-ed combination of all wc.a[].flags */ - /* The number of terms in the FROM clause is limited by the number of + /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask */ - if( pTabList->nSrc>sizeof(Bitmask)*8 ){ - sqlite3ErrorMsg(pParse, "at most %d tables in a join", - sizeof(Bitmask)*8); + if( pTabList->nSrc>BMS ){ + sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); return 0; } /* Split the WHERE clause into separate subexpressions where each - ** subexpression is separated by an AND operator. If the aExpr[] - ** array fills up, the last entry might point to an expression which - ** contains additional unfactored AND operators. + ** subexpression is separated by an AND operator. */ initMaskSet(&maskSet); - memset(aExpr, 0, sizeof(aExpr)); - nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere); - if( nExpr==ARRAYSIZE(aExpr) ){ - sqlite3ErrorMsg(pParse, "WHERE clause too complex - no more " - "than %d terms allowed", (int)ARRAYSIZE(aExpr)-1); - return 0; - } + whereClauseInit(&wc, pParse); + whereSplit(&wc, pWhere, TK_AND); /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); if( sqlite3_malloc_failed ){ - sqliteFree(pWInfo); /* Avoid leaking memory when malloc fails */ - return 0; + goto whereBeginNoMem; } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; @@ -658,272 +1384,95 @@ WhereInfo *sqlite3WhereBegin( pWhere = 0; } - /* Analyze all of the subexpressions. + /* Analyze all of the subexpressions. Note that exprAnalyze() might + ** add new virtual terms onto the end of the WHERE clause. We do not + ** want to analyze these virtual terms, so start analyzing at the end + ** and work forward so that they added virtual terms are never processed. */ for(i=0; inSrc; i++){ createMask(&maskSet, pTabList->a[i].iCursor); } - for(pTerm=aExpr, i=0; ia[i].pIdx point to the index to use for the i-th nested - ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner - ** loop. + /* Chose the best index to use for each table in the FROM clause. ** - ** If terms exist that use the ROWID of any table, then set the - ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table - ** to the index of the term containing the ROWID. We always prefer - ** to use a ROWID which can directly access a table rather than an - ** index which requires reading an index first to get the rowid then - ** doing a second read of the actual database table. + ** This loop fills in the following fields: ** - ** Actually, if there are more than 32 tables in the join, only the - ** first 32 tables are candidates for indices. This is (again) due - ** to the limit of 32 bits in an integer bitmask. + ** pWInfo->a[].pIdx The index to use for this level of the loop. + ** pWInfo->a[].flags WHERE_xxx flags associated with pIdx + ** pWInfo->a[].nEq The number of == and IN constraints + ** pWInfo->a[].iFrom When term of the FROM clause is being coded + ** pWInfo->a[].iTabCur The VDBE cursor for the database table + ** pWInfo->a[].iIdxCur The VDBE cursor for the index + ** + ** This loop also figures out the nesting order of tables in the FROM + ** clause. */ - loopMask = 0; + notReady = ~(Bitmask)0; pTabItem = pTabList->a; pLevel = pWInfo->a; - for(i=0; inSrc && iiCursor; /* The cursor for this table */ - Bitmask mask = getMask(&maskSet, iCur); /* Cursor mask for this table */ - Table *pTab = pTabItem->pTab; - Index *pIdx; - Index *pBestIdx = 0; - int bestScore = 0; - int bestRev = 0; - - /* Check to see if there is an expression that uses only the - ** ROWID field of this table. For terms of the form ROWID==expr - ** set iDirectEq[i] to the index of the term. For terms of the - ** form ROWIDexpr or ROWID>=expr set iDirectGt[i]. - ** - ** (Added:) Treat ROWID IN expr like ROWID=expr. - */ - pLevel->iIdxCur = -1; - iDirectEq[i] = -1; - iDirectLt[i] = -1; - iDirectGt[i] = -1; - for(pTerm=aExpr, j=0; jp; - if( pTerm->idxLeft==iCur && pX->pLeft->iColumn<0 - && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){ - switch( pX->op ){ - case TK_IN: - case TK_EQ: iDirectEq[i] = j; break; - case TK_LE: - case TK_LT: iDirectLt[i] = j; break; - case TK_GE: - case TK_GT: iDirectGt[i] = j; break; - } - } - } - - /* If we found a term that tests ROWID with == or IN, that term - ** will be used to locate the rows in the database table. There - ** is not need to continue into the code below that looks for - ** an index. We will always use the ROWID over an index. - */ - if( iDirectEq[i]>=0 ){ - loopMask |= mask; - pLevel->pIdx = 0; - continue; - } - - /* Do a search for usable indices. Leave pBestIdx pointing to - ** the "best" index. pBestIdx is left set to NULL if no indices - ** are usable. - ** - ** The best index is the one with the highest score. The score - ** for the index is determined as follows. For each of the - ** left-most terms that is fixed by an equality operator, add - ** 32 to the score. The right-most term of the index may be - ** constrained by an inequality. Add 4 if for an "x<..." constraint - ** and add 8 for an "x>..." constraint. If both constraints - ** are present, add 12. - ** - ** If the left-most term of the index uses an IN operator - ** (ex: "x IN (...)") then add 16 to the score. - ** - ** If an index can be used for sorting, add 2 to the score. - ** If an index contains all the terms of a table that are ever - ** used by any expression in the SQL statement, then add 1 to - ** the score. - ** - ** This scoring system is designed so that the score can later be - ** used to determine how the index is used. If the score&0x1c is 0 - ** then all constraints are equalities. If score&0x4 is not 0 then - ** there is an inequality used as a termination key. (ex: "x<...") - ** If score&0x8 is not 0 then there is an inequality used as the - ** start key. (ex: "x>..."). A score or 0x10 is the special case - ** of an IN operator constraint. (ex: "x IN ..."). - ** - ** The IN operator (as in " IN (...)") is treated the same as - ** an equality comparison except that it can only be used on the - ** left-most column of an index and other terms of the WHERE clause - ** cannot be used in conjunction with the IN operator to help satisfy - ** other columns of the index. - */ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - Bitmask eqMask = 0; /* Index columns covered by an x=... term */ - Bitmask ltMask = 0; /* Index columns covered by an x<... term */ - Bitmask gtMask = 0; /* Index columns covered by an x>... term */ - Bitmask inMask = 0; /* Index columns covered by an x IN .. term */ - Bitmask m; - int nEq, score, bRev = 0; - - if( pIdx->nColumn>sizeof(eqMask)*8 ){ - continue; /* Ignore indices with too many columns to analyze */ - } - for(pTerm=aExpr, j=0; jp; - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pX->pLeft); - if( !pColl && pX->pRight ){ - pColl = sqlite3ExprCollSeq(pParse, pX->pRight); - } - if( !pColl ){ - pColl = pParse->db->pDfltColl; - } - if( pTerm->idxLeft==iCur - && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){ - int iColumn = pX->pLeft->iColumn; - int k; - char idxaff = iColumn>=0 ? pIdx->pTable->aCol[iColumn].affinity : 0; - for(k=0; knColumn; k++){ - /* If the collating sequences or affinities don't match, - ** ignore this index. */ - if( pColl!=pIdx->keyInfo.aColl[k] ) continue; - if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue; - if( pIdx->aiColumn[k]==iColumn ){ - switch( pX->op ){ - case TK_IN: { - if( k==0 ) inMask |= 1; - break; - } - case TK_EQ: { - eqMask |= ((Bitmask)1)<nColumn; nEq++){ - m = (((Bitmask)1)<<(nEq+1))-1; - if( (m & eqMask)!=m ) break; + andFlags = ~0; + for(i=iFrom=0, pLevel=pWInfo->a; inSrc; i++, pLevel++){ + Index *pIdx; /* Index for FROM table at pTabItem */ + int flags; /* Flags asssociated with pIdx */ + int nEq; /* Number of == or IN constraints */ + double cost; /* The cost for pIdx */ + int j; /* For looping over FROM tables */ + Index *pBest = 0; /* The best index seen so far */ + int bestFlags = 0; /* Flags associated with pBest */ + int bestNEq = 0; /* nEq associated with pBest */ + double lowestCost = 1.0e99; /* Cost of the pBest */ + int bestJ; /* The value of j */ + Bitmask m; /* Bitmask value for j or bestJ */ + + for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){ + m = getMask(&maskSet, pTabItem->iCursor); + if( (m & notReady)==0 ){ + if( j==iFrom ) iFrom++; + continue; } - - /* Begin assemblying the score - */ - score = nEq*32; /* Base score is 32 times number of == constraints */ - m = ((Bitmask)1)< constraint */ - if( score==0 && inMask ) score = 16; /* Default score for IN constraint */ - - /* Give bonus points if this index can be used for sorting - */ - if( i==0 && score!=16 && ppOrderBy && *ppOrderBy ){ - int base = pTabList->a[0].iCursor; - if( isSortingIndex(pParse, pIdx, pTab, base, *ppOrderBy, nEq, &bRev) ){ - score += 2; - } + cost = bestIndex(pParse, &wc, pTabItem, notReady, + (j==0 && ppOrderBy) ? *ppOrderBy : 0, + &pIdx, &flags, &nEq); + if( costcolUsed < (((Bitmask)1)<<(BMS-1)) ){ - for(m=0, j=0; jnColumn; j++){ - int x = pIdx->aiColumn[j]; - if( xcolUsed & m)==pTabItem->colUsed ){ - score++; - } - } - - /* If the score for this index is the best we have seen so far, then - ** save it - */ - if( score>bestScore ){ - pBestIdx = pIdx; - bestScore = score; - bestRev = bRev; + if( (pTabItem->jointype & JT_LEFT)!=0 + || (j>0 && (pTabItem[-1].jointype & JT_LEFT)!=0) + ){ + break; } } - pLevel->pIdx = pBestIdx; - pLevel->score = bestScore; - pLevel->bRev = bestRev; - loopMask |= mask; - if( pBestIdx ){ + if( (bestFlags & WHERE_ORDERBY)!=0 ){ + *ppOrderBy = 0; + } + andFlags &= bestFlags; + pLevel->flags = bestFlags; + pLevel->pIdx = pBest; + pLevel->nEq = bestNEq; + pLevel->aInLoop = 0; + pLevel->nIn = 0; + if( pBest ){ pLevel->iIdxCur = pParse->nTab++; + }else{ + pLevel->iIdxCur = -1; } + notReady &= ~getMask(&maskSet, pTabList->a[bestJ].iCursor); + pLevel->iFrom = bestJ; } - /* Check to see if the ORDER BY clause is or can be satisfied by the - ** use of an index on the first table. + /* If the total query only selects a single row, then the ORDER BY + ** clause is irrelevant. */ - if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){ - Index *pIdx; /* Index derived from the WHERE clause */ - Table *pTab; /* Left-most table in the FROM clause */ - int bRev = 0; /* True to reverse the output order */ - int iCur; /* Btree-cursor that will be used by pTab */ - WhereLevel *pLevel0 = &pWInfo->a[0]; - - pTab = pTabList->a[0].pTab; - pIdx = pLevel0->pIdx; - iCur = pTabList->a[0].iCursor; - if( pIdx==0 && sortableByRowid(iCur, *ppOrderBy, &bRev) ){ - /* The ORDER BY clause specifies ROWID order, which is what we - ** were going to be doing anyway... - */ - *ppOrderBy = 0; - pLevel0->bRev = bRev; - }else if( pLevel0->score==16 ){ - /* If there is already an IN index on the left-most table, - ** it will not give the correct sort order. - ** So, pretend that no suitable index is found. - */ - }else if( iDirectEq[0]>=0 || iDirectLt[0]>=0 || iDirectGt[0]>=0 ){ - /* If the left-most column is accessed using its ROWID, then do - ** not try to sort by index. But do delete the ORDER BY clause - ** if it is redundant. - */ - }else if( (pLevel0->score&2)!=0 ){ - /* The index that was selected for searching will cause rows to - ** appear in sorted order. - */ - *ppOrderBy = 0; - } + if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){ + *ppOrderBy = 0; } /* Open all tables in the pTabList and any indices selected for @@ -931,55 +1480,64 @@ WhereInfo *sqlite3WhereBegin( */ sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ pLevel = pWInfo->a; - for(i=0, pTabItem=pTabList->a; inSrc; i++, pTabItem++, pLevel++){ + for(i=0, pLevel=pWInfo->a; inSrc; i++, pLevel++){ Table *pTab; Index *pIx; int iIdxCur = pLevel->iIdxCur; + pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; if( pTab->isTransient || pTab->pSelect ) continue; - if( (pLevel->score & 1)==0 ){ + if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3OpenTableForReading(v, pTabItem->iCursor, pTab); } pLevel->iTabCur = pTabItem->iCursor; if( (pIx = pLevel->pIdx)!=0 ){ sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0); + VdbeComment((v, "# %s", pIx->zName)); sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum, (char*)&pIx->keyInfo, P3_KEYINFO); } - if( (pLevel->score & 1)!=0 ){ + if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){ sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1); } sqlite3CodeVerifySchema(pParse, pTab->iDb); } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); - /* Generate the code to do the search + /* Generate the code to do the search. Each iteration of the for + ** loop below generates code for a single nested loop of the VM + ** program. */ - loopMask = 0; - pLevel = pWInfo->a; - pTabItem = pTabList->a; - for(i=0; inSrc; i++, pTabItem++, pLevel++){ - int j, k; + notReady = ~(Bitmask)0; + for(i=0, pLevel=pWInfo->a; inSrc; i++, pLevel++){ + int j; int iCur = pTabItem->iCursor; /* The VDBE cursor for the table */ Index *pIdx; /* The index we will be using */ int iIdxCur; /* The VDBE cursor for the index */ int omitTable; /* True if we use the index only */ + int bRev; /* True if we need to scan in reverse order */ + pTabItem = &pTabList->a[pLevel->iFrom]; + iCur = pTabItem->iCursor; pIdx = pLevel->pIdx; iIdxCur = pLevel->iIdxCur; - pLevel->inOp = OP_Noop; + bRev = (pLevel->flags & WHERE_REVERSE)!=0; + omitTable = (pLevel->flags & WHERE_IDX_ONLY)!=0; - /* Check to see if it is appropriate to omit the use of the table - ** here and use its index instead. + /* Create labels for the "break" and "continue" instructions + ** for the current loop. Jump to brk to break out of a loop. + ** Jump to cont to go immediately to the next iteration of the + ** loop. */ - omitTable = (pLevel->score&1)!=0; + brk = pLevel->brk = sqlite3VdbeMakeLabel(v); + cont = pLevel->cont = sqlite3VdbeMakeLabel(v); /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ - if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){ + if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){ if( !pParse->nMem ) pParse->nMem++; pLevel->iLeftJoin = pParse->nMem++; sqlite3VdbeAddOp(v, OP_Null, 0, 0); @@ -987,122 +1545,55 @@ WhereInfo *sqlite3WhereBegin( VdbeComment((v, "# init LEFT JOIN no-match flag")); } - if( i=0 ){ + if( pLevel->flags & WHERE_ROWID_EQ ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ - assert( kp!=0 ); - assert( pTerm->idxLeft==iCur ); + pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0); + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + assert( pTerm->leftCursor==iCur ); assert( omitTable==0 ); - brk = pLevel->brk = sqlite3VdbeMakeLabel(v); codeEqualityTerm(pParse, pTerm, brk, pLevel); - cont = pLevel->cont = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk); sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk); VdbeComment((v, "pk")); pLevel->op = OP_Noop; - }else if( pIdx!=0 && pLevel->score>3 && (pLevel->score&0x0c)==0 ){ - /* Case 2: There is an index and all terms of the WHERE clause that - ** refer to the index using the "==" or "IN" operators. - */ - int start; - int nColumn = (pLevel->score+16)/32; - brk = pLevel->brk = sqlite3VdbeMakeLabel(v); - - /* For each column of the index, find the term of the WHERE clause that - ** constraints that column. If the WHERE clause term is X=expr, then - ** evaluation expr and leave the result on the stack */ - for(j=0; jp; - if( pX==0 ) continue; - if( pTerm->idxLeft==iCur - && (pTerm->prereqRight & loopMask)==pTerm->prereqRight - && pX->pLeft->iColumn==pIdx->aiColumn[j] - && (pX->op==TK_EQ || pX->op==TK_IN) - ){ - char idxaff = pIdx->pTable->aCol[pX->pLeft->iColumn].affinity; - if( sqlite3IndexAffinityOk(pX, idxaff) ){ - codeEqualityTerm(pParse, pTerm, brk, pLevel); - break; - } - } - } - } - pLevel->iMem = pParse->nMem++; - cont = pLevel->cont = sqlite3VdbeMakeLabel(v); - buildIndexProbe(v, nColumn, brk, pIdx); - sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); - - /* Generate code (1) to move to the first matching element of the table. - ** Then generate code (2) that jumps to "brk" after the cursor is past - ** the last matching element of the table. The code (1) is executed - ** once to initialize the search, the code (2) is executed before each - ** iteration of the scan to see if the scan has finished. */ - if( pLevel->bRev ){ - /* Scan in reverse order */ - sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, brk); - start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); - sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, brk); - pLevel->op = OP_Prev; - }else{ - /* Scan in the forward order */ - sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, brk); - start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); - sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC); - pLevel->op = OP_Next; - } - sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0); - sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont); - if( !omitTable ){ - sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0); - sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); - } - pLevel->p1 = iIdxCur; - pLevel->p2 = start; - }else if( i=0 || iDirectGt[i]>=0) ){ - /* Case 3: We have an inequality comparison against the ROWID field. + }else if( pLevel->flags & WHERE_ROWID_RANGE ){ + /* Case 2: We have an inequality comparison against the ROWID field. */ int testOp = OP_Noop; int start; - int bRev = pLevel->bRev; + WhereTerm *pStart, *pEnd; assert( omitTable==0 ); - brk = pLevel->brk = sqlite3VdbeMakeLabel(v); - cont = pLevel->cont = sqlite3VdbeMakeLabel(v); + pStart = findTerm(&wc, iCur, -1, notReady, WO_GT|WO_GE, 0); + pEnd = findTerm(&wc, iCur, -1, notReady, WO_LT|WO_LE, 0); if( bRev ){ - int t = iDirectGt[i]; - iDirectGt[i] = iDirectLt[i]; - iDirectLt[i] = t; + pTerm = pStart; + pStart = pEnd; + pEnd = pTerm; } - if( iDirectGt[i]>=0 ){ + if( pStart ){ Expr *pX; - k = iDirectGt[i]; - assert( kp; + pX = pStart->pExpr; assert( pX!=0 ); - assert( pTerm->idxLeft==iCur ); + assert( pStart->leftCursor==iCur ); sqlite3ExprCode(pParse, pX->pRight); sqlite3VdbeAddOp(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk); sqlite3VdbeAddOp(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk); VdbeComment((v, "pk")); - disableTerm(pLevel, &pTerm->p); + disableTerm(pLevel, pStart); }else{ sqlite3VdbeAddOp(v, bRev ? OP_Last : OP_Rewind, iCur, brk); } - if( iDirectLt[i]>=0 ){ + if( pEnd ){ Expr *pX; - k = iDirectLt[i]; - assert( kp; + pX = pEnd->pExpr; assert( pX!=0 ); - assert( pTerm->idxLeft==iCur ); + assert( pEnd->leftCursor==iCur ); sqlite3ExprCode(pParse, pX->pRight); pLevel->iMem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); @@ -1111,7 +1602,7 @@ WhereInfo *sqlite3WhereBegin( }else{ testOp = bRev ? OP_Lt : OP_Gt; } - disableTerm(pLevel, &pTerm->p); + disableTerm(pLevel, pEnd); } start = sqlite3VdbeCurrentAddr(v); pLevel->op = bRev ? OP_Prev : OP_Next; @@ -1122,77 +1613,38 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqlite3VdbeAddOp(v, testOp, 'n', brk); } - }else if( pIdx==0 ){ - /* Case 4: There is no usable index. We must do a complete - ** scan of the entire database table. - */ - int start; - int opRewind; - - assert( omitTable==0 ); - brk = pLevel->brk = sqlite3VdbeMakeLabel(v); - cont = pLevel->cont = sqlite3VdbeMakeLabel(v); - if( pLevel->bRev ){ - opRewind = OP_Last; - pLevel->op = OP_Prev; - }else{ - opRewind = OP_Rewind; - pLevel->op = OP_Next; - } - sqlite3VdbeAddOp(v, opRewind, iCur, brk); - start = sqlite3VdbeCurrentAddr(v); - pLevel->p1 = iCur; - pLevel->p2 = start; - }else{ - /* Case 5: The WHERE clause term that refers to the right-most + }else if( pLevel->flags & WHERE_COLUMN_RANGE ){ + /* Case 3: The WHERE clause term that refers to the right-most ** column of the index is an inequality. For example, if ** the index is on (x,y,z) and the WHERE clause is of the ** form "x=5 AND y<10" then this case is used. Only the ** right-most column can be an inequality - the rest must - ** use the "==" operator. + ** use the "==" and "IN" operators. ** ** This case is also used when there are no WHERE clause ** constraints but an index is selected anyway, in order ** to force the output order to conform to an ORDER BY. */ - int score = pLevel->score; - int nEqColumn = score/32; int start; + int nEq = pLevel->nEq; int leFlag=0, geFlag=0; int testOp; + int topLimit = (pLevel->flags & WHERE_TOP_LIMIT)!=0; + int btmLimit = (pLevel->flags & WHERE_BTM_LIMIT)!=0; - /* Evaluate the equality constraints + /* Generate code to evaluate all constraint terms using == or IN + ** and level the values of those terms on the stack. */ - for(j=0; jaiColumn[j]; - for(pTerm=aExpr, k=0; kp; - if( pX==0 ) continue; - if( pTerm->idxLeft==iCur - && pX->op==TK_EQ - && (pTerm->prereqRight & loopMask)==pTerm->prereqRight - && pX->pLeft->iColumn==iIdxCol - ){ - sqlite3ExprCode(pParse, pX->pRight); - disableTerm(pLevel, &pTerm->p); - break; - } - } - } + codeAllEqualityTerms(pParse, pLevel, &wc, notReady, brk); /* Duplicate the equality term values because they will all be ** used twice: once to make the termination key and once to make the ** start key. */ - for(j=0; jcont = sqlite3VdbeMakeLabel(v); - brk = pLevel->brk = sqlite3VdbeMakeLabel(v); - /* Generate the termination key. This is the key value that ** will end the search. There is no termination key if there ** are no equality terms and no "X<..." term. @@ -1200,37 +1652,32 @@ WhereInfo *sqlite3WhereBegin( ** 2002-Dec-04: On a reverse-order scan, the so-called "termination" ** key computed here really ends up being the start key. */ - if( (score & 4)!=0 ){ - for(pTerm=aExpr, k=0; kp; - if( pX==0 ) continue; - if( pTerm->idxLeft==iCur - && (pX->op==TK_LT || pX->op==TK_LE) - && (pTerm->prereqRight & loopMask)==pTerm->prereqRight - && pX->pLeft->iColumn==pIdx->aiColumn[j] - ){ - sqlite3ExprCode(pParse, pX->pRight); - leFlag = pX->op==TK_LE; - disableTerm(pLevel, &pTerm->p); - break; - } - } + if( topLimit ){ + Expr *pX; + int k = pIdx->aiColumn[j]; + pTerm = findTerm(&wc, iCur, k, notReady, WO_LT|WO_LE, pIdx); + assert( pTerm!=0 ); + pX = pTerm->pExpr; + assert( (pTerm->flags & TERM_CODED)==0 ); + sqlite3ExprCode(pParse, pX->pRight); + leFlag = pX->op==TK_LE; + disableTerm(pLevel, pTerm); testOp = OP_IdxGE; }else{ - testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop; + testOp = nEq>0 ? OP_IdxGE : OP_Noop; leFlag = 1; } if( testOp!=OP_Noop ){ - int nCol = nEqColumn + ((score & 4)!=0); + int nCol = nEq + topLimit; pLevel->iMem = pParse->nMem++; buildIndexProbe(v, nCol, brk, pIdx); - if( pLevel->bRev ){ + if( bRev ){ int op = leFlag ? OP_MoveLe : OP_MoveLt; sqlite3VdbeAddOp(v, op, iIdxCur, brk); }else{ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); } - }else if( pLevel->bRev ){ + }else if( bRev ){ sqlite3VdbeAddOp(v, OP_Last, iIdxCur, brk); } @@ -1243,28 +1690,23 @@ WhereInfo *sqlite3WhereBegin( ** 2002-Dec-04: In the case of a reverse-order search, the so-called ** "start" key really ends up being used as the termination key. */ - if( (score & 8)!=0 ){ - for(pTerm=aExpr, k=0; kp; - if( pX==0 ) continue; - if( pTerm->idxLeft==iCur - && (pX->op==TK_GT || pX->op==TK_GE) - && (pTerm->prereqRight & loopMask)==pTerm->prereqRight - && pX->pLeft->iColumn==pIdx->aiColumn[j] - ){ - sqlite3ExprCode(pParse, pX->pRight); - geFlag = pX->op==TK_GE; - disableTerm(pLevel, &pTerm->p); - break; - } - } + if( btmLimit ){ + Expr *pX; + int k = pIdx->aiColumn[j]; + pTerm = findTerm(&wc, iCur, k, notReady, WO_GT|WO_GE, pIdx); + assert( pTerm!=0 ); + pX = pTerm->pExpr; + assert( (pTerm->flags & TERM_CODED)==0 ); + sqlite3ExprCode(pParse, pX->pRight); + geFlag = pX->op==TK_GE; + disableTerm(pLevel, pTerm); }else{ geFlag = 1; } - if( nEqColumn>0 || (score&8)!=0 ){ - int nCol = nEqColumn + ((score&8)!=0); + if( nEq>0 || btmLimit ){ + int nCol = nEq + btmLimit; buildIndexProbe(v, nCol, brk, pIdx); - if( pLevel->bRev ){ + if( bRev ){ pLevel->iMem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); testOp = OP_IdxLT; @@ -1272,7 +1714,7 @@ WhereInfo *sqlite3WhereBegin( int op = geFlag ? OP_MoveGe : OP_MoveGt; sqlite3VdbeAddOp(v, op, iIdxCur, brk); } - }else if( pLevel->bRev ){ + }else if( bRev ){ testOp = OP_Noop; }else{ sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, brk); @@ -1286,12 +1728,12 @@ WhereInfo *sqlite3WhereBegin( if( testOp!=OP_Noop ){ sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqlite3VdbeAddOp(v, testOp, iIdxCur, brk); - if( (leFlag && !pLevel->bRev) || (!geFlag && pLevel->bRev) ){ + if( (leFlag && !bRev) || (!geFlag && bRev) ){ sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC); } } sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0); - sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont); + sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq + topLimit, cont); if( !omitTable ){ sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0); sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); @@ -1299,25 +1741,80 @@ WhereInfo *sqlite3WhereBegin( /* Record the instruction used to terminate the loop. */ - pLevel->op = pLevel->bRev ? OP_Prev : OP_Next; + pLevel->op = bRev ? OP_Prev : OP_Next; + pLevel->p1 = iIdxCur; + pLevel->p2 = start; + }else if( pLevel->flags & WHERE_COLUMN_EQ ){ + /* Case 4: There is an index and all terms of the WHERE clause that + ** refer to the index using the "==" or "IN" operators. + */ + int start; + int nEq = pLevel->nEq; + + /* Generate code to evaluate all constraint terms using == or IN + ** and leave the values of those terms on the stack. + */ + codeAllEqualityTerms(pParse, pLevel, &wc, notReady, brk); + + /* Generate a single key that will be used to both start and terminate + ** the search + */ + buildIndexProbe(v, nEq, brk, pIdx); + sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); + + /* Generate code (1) to move to the first matching element of the table. + ** Then generate code (2) that jumps to "brk" after the cursor is past + ** the last matching element of the table. The code (1) is executed + ** once to initialize the search, the code (2) is executed before each + ** iteration of the scan to see if the scan has finished. */ + if( bRev ){ + /* Scan in reverse order */ + sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, brk); + start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); + sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, brk); + pLevel->op = OP_Prev; + }else{ + /* Scan in the forward order */ + sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, brk); + start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); + sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC); + pLevel->op = OP_Next; + } + sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0); + sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq, cont); + if( !omitTable ){ + sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); + } pLevel->p1 = iIdxCur; pLevel->p2 = start; + }else{ + /* Case 5: There is no usable index. We must do a complete + ** scan of the entire table. + */ + assert( omitTable==0 ); + assert( bRev==0 ); + pLevel->op = OP_Next; + pLevel->p1 = iCur; + pLevel->p2 = 1 + sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk); } - loopMask |= getMask(&maskSet, iCur); + notReady &= ~getMask(&maskSet, iCur); /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. */ - for(pTerm=aExpr, j=0; jp==0 ) continue; - if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue; - if( pLevel->iLeftJoin && !ExprHasProperty(pTerm->p,EP_FromJoin) ){ + for(pTerm=wc.a, j=wc.nTerm; j>0; j--, pTerm++){ + Expr *pE; + if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & notReady)!=0 ) continue; + pE = pTerm->pExpr; + assert( pE!=0 ); + if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ continue; } - sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1); - pTerm->p = 0; + sqlite3ExprIfFalse(pParse, pE, cont, 1); + pTerm->flags |= TERM_CODED; } - brk = cont; /* For a LEFT OUTER JOIN, generate code that will record the fact that ** at least one row of the right table has matched the left table. @@ -1327,17 +1824,75 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp(v, OP_Integer, 1, 0); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1); VdbeComment((v, "# record LEFT JOIN hit")); - for(pTerm=aExpr, j=0; jp==0 ) continue; - if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue; - sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1); - pTerm->p = 0; + for(pTerm=wc.a, j=0; jflags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & notReady)!=0 ) continue; + assert( pTerm->pExpr ); + sqlite3ExprIfFalse(pParse, pTerm->pExpr, cont, 1); + pTerm->flags |= TERM_CODED; + } + } + } + +#ifdef SQLITE_TEST /* For testing and debugging use only */ + /* Record in the query plan information about the current table + ** and the index used to access it (if any). If the table itself + ** is not used, its name is just '{}'. If no index is used + ** the index is listed as "{}". If the primary key is used the + ** index name is '*'. + */ + for(i=0; inSrc; i++){ + char *z; + int n; + pLevel = &pWInfo->a[i]; + pTabItem = &pTabList->a[pLevel->iFrom]; + z = pTabItem->zAlias; + if( z==0 ) z = pTabItem->pTab->zName; + n = strlen(z); + if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){ + if( pLevel->flags & WHERE_IDX_ONLY ){ + strcpy(&sqlite3_query_plan[nQPlan], "{}"); + nQPlan += 2; + }else{ + strcpy(&sqlite3_query_plan[nQPlan], z); + nQPlan += n; + } + sqlite3_query_plan[nQPlan++] = ' '; + } + if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ + strcpy(&sqlite3_query_plan[nQPlan], "* "); + nQPlan += 2; + }else if( pLevel->pIdx==0 ){ + strcpy(&sqlite3_query_plan[nQPlan], "{} "); + nQPlan += 3; + }else{ + n = strlen(pLevel->pIdx->zName); + if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){ + strcpy(&sqlite3_query_plan[nQPlan], pLevel->pIdx->zName); + nQPlan += n; + sqlite3_query_plan[nQPlan++] = ' '; } } } + while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){ + sqlite3_query_plan[--nQPlan] = 0; + } + sqlite3_query_plan[nQPlan] = 0; + nQPlan = 0; +#endif /* SQLITE_TEST // Testing and debugging use only */ + + /* Record the continuation address in the WhereInfo structure. Then + ** clean up and return. + */ pWInfo->iContinue = cont; - freeMaskSet(&maskSet); + whereClauseClear(&wc); return pWInfo; + + /* Jump here if malloc fails */ +whereBeginNoMem: + whereClauseClear(&wc); + sqliteFree(pWInfo); + return 0; } /* @@ -1349,7 +1904,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ int i; WhereLevel *pLevel; SrcList *pTabList = pWInfo->pTabList; - struct SrcList_item *pTabItem; /* Generate loop termination code. */ @@ -1360,8 +1914,13 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2); } sqlite3VdbeResolveLabel(v, pLevel->brk); - if( pLevel->inOp!=OP_Noop ){ - sqlite3VdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2); + if( pLevel->nIn ){ + int *a; + int j; + for(j=pLevel->nIn, a=&pLevel->aInLoop[j*3-3]; j>0; j--, a-=3){ + sqlite3VdbeAddOp(v, a[0], a[1], a[2]); + } + sqliteFree(pLevel->aInLoop); } if( pLevel->iLeftJoin ){ int addr; @@ -1380,15 +1939,14 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ */ sqlite3VdbeResolveLabel(v, pWInfo->iBreak); - /* Close all of the cursors that were opend by sqlite3WhereBegin. + /* Close all of the cursors that were opened by sqlite3WhereBegin. */ - pLevel = pWInfo->a; - pTabItem = pTabList->a; - for(i=0; inSrc; i++, pTabItem++, pLevel++){ + for(i=0, pLevel=pWInfo->a; inSrc; i++, pLevel++){ + struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); if( pTab->isTransient || pTab->pSelect ) continue; - if( (pLevel->score & 1)==0 ){ + if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3VdbeAddOp(v, OP_Close, pTabItem->iCursor, 0); } if( pLevel->pIdx!=0 ){ @@ -1404,7 +1962,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** that reference the table and converts them into opcodes that ** reference the index. */ - if( pLevel->score & 1 ){ + if( pLevel->flags & WHERE_IDX_ONLY ){ int i, j, last; VdbeOp *pOp; Index *pIdx = pLevel->pIdx; diff --git a/ext/pdo_sqlite/sqlite/tool/lemon.c b/ext/pdo_sqlite/sqlite/tool/lemon.c index 708b3538d7..8f6e87330a 100644 --- a/ext/pdo_sqlite/sqlite/tool/lemon.c +++ b/ext/pdo_sqlite/sqlite/tool/lemon.c @@ -1606,12 +1606,11 @@ int k; FILE *err; { int spcnt, i; - spcnt = 0; if( argv[0] ) fprintf(err,"%s",argv[0]); spcnt = strlen(argv[0]) + 1; for(i=1; ivardest ){ + struct symbol *dflt_sp = 0; + for(i=0; insymbol; i++){ + struct symbol *sp = lemp->symbols[i]; + if( sp==0 || sp->type==TERMINAL || + sp->index<=0 || sp->destructor!=0 ) continue; + fprintf(out," case %d:\n",sp->index); lineno++; + dflt_sp = sp; + } + if( dflt_sp!=0 ){ + emit_destructor_code(out,dflt_sp,lemp,&lineno); + fprintf(out," break;\n"); lineno++; + } + } for(i=0; insymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; @@ -3683,20 +3696,6 @@ int mhflag; /* Output in makeheaders format if true */ emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); fprintf(out," break;\n"); lineno++; } - if( lemp->vardest ){ - struct symbol *dflt_sp = 0; - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || - sp->index<=0 || sp->destructor!=0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - dflt_sp = sp; - } - if( dflt_sp!=0 ){ - emit_destructor_code(out,dflt_sp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } tplt_xfer(lemp->name,in,out,&lineno); /* Generate code which executes whenever the parser stack overflows */ diff --git a/ext/pdo_sqlite/sqlite/tool/lempar.c b/ext/pdo_sqlite/sqlite/tool/lempar.c index aac842f10c..57ec97f6a8 100644 --- a/ext/pdo_sqlite/sqlite/tool/lempar.c +++ b/ext/pdo_sqlite/sqlite/tool/lempar.c @@ -364,11 +364,11 @@ static int yy_find_shift_action( ** return YY_NO_ACTION. */ static int yy_find_reduce_action( - yyParser *pParser, /* The parser */ + int stateno, /* Current state number */ int iLookAhead /* The look-ahead token */ ){ int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; + /* int stateno = pParser->yystack[pParser->yyidx].stateno; */ i = yy_reduce_ofst[stateno]; if( i==YY_REDUCE_USE_DFLT ){ @@ -462,6 +462,18 @@ static void yy_reduce( } #endif /* NDEBUG */ +#ifndef NDEBUG + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + */ + memset(&yygotominor, 0, sizeof(yygotominor)); +#endif + switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example ** follows: @@ -476,9 +488,24 @@ static void yy_reduce( yygoto = yyRuleInfo[yyruleno].lhs; yysize = yyRuleInfo[yyruleno].nrhs; yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yypParser,yygoto); + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); if( yyact < YYNSTATE ){ - yy_shift(yypParser,yyact,yygoto,&yygotominor); +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = yyact; + yymsp->major = yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } }else if( yyact == YYNSTATE + YYNRULE + 1 ){ yy_accept(yypParser); } @@ -570,7 +597,7 @@ void Parse( /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; if( yypParser->yyidx<0 ){ - if( yymajor==0 ) return; + /* if( yymajor==0 ) return; // not sure why this was here... */ yypParser->yyidx = 0; yypParser->yyerrcnt = -1; yypParser->yystack[0].stateno = 0; diff --git a/ext/pdo_sqlite/sqlite/tool/memleak.awk b/ext/pdo_sqlite/sqlite/tool/memleak.awk index 185f174897..928d3b69dc 100644 --- a/ext/pdo_sqlite/sqlite/tool/memleak.awk +++ b/ext/pdo_sqlite/sqlite/tool/memleak.awk @@ -1,6 +1,6 @@ # # This script looks for memory leaks by analyzing the output of "sqlite" -# when compiled with the MEMORY_DEBUG=2 option. +# when compiled with the SQLITE_DEBUG=2 option. # /[0-9]+ malloc / { mem[$6] = $0 diff --git a/ext/pdo_sqlite/sqlite/tool/memleak3.tcl b/ext/pdo_sqlite/sqlite/tool/memleak3.tcl index 69bc4ae88e..2e3f43bc13 100644 --- a/ext/pdo_sqlite/sqlite/tool/memleak3.tcl +++ b/ext/pdo_sqlite/sqlite/tool/memleak3.tcl @@ -13,7 +13,8 @@ exec `which tclsh` $0 "$@" set doco " This script is a tool to help track down memory leaks in the sqlite library. The library must be compiled with the preprocessor symbol -SQLITE_DEBUG set to at least 2. It must be set to 3 to enable stack traces. +SQLITE_MEMDEBUG set to at least 2. It must be set to 3 to enable stack +traces. To use, run the leaky application and save the standard error output. Then, execute this program with the first argument the name of the @@ -24,29 +25,88 @@ If all goes well a summary of unfreed allocations is printed out. If the GNU C library is in use and SQLITE_DEBUG is 3 or greater a stack trace is printed out for each unmatched allocation. +If the \"-r \" option is passed, then the program stops and prints out +the state of the heap immediately after the th call to malloc() or +realloc(). + Example: $ ./testfixture ../sqlite/test/select1.test 2> memtrace.out -$ tclsh $argv0 ./testfixture memtrace.out +$ tclsh $argv0 ?-r ? ./testfixture memtrace.out " -# If stack traces are enabled, the 'addr2line' program is called to -# translate a binary stack address into a human-readable form. -set addr2line addr2line -if { [llength $argv]!=2 } { - puts "Usage: $argv0 " +proc usage {} { + set prg [file tail $::argv0] + puts "Usage: $prg ?-r ? " puts "" - puts [string trim $doco] + puts [string trim $::doco] exit -1 } +proc shift {listvar} { + upvar $listvar l + set ret [lindex $l 0] + set l [lrange $l 1 end] + return $ret +} + +# Argument handling. The following vars are set: +# +# $exe - the name of the executable (i.e. "testfixture" or "./sqlite3") +# $memfile - the name of the file containing the trace output. +# $report_at - The malloc number to stop and report at. Or -1 to read +# all of $memfile. +# +set report_at -1 +while {[llength $argv]>2} { + set arg [shift argv] + switch -- $arg { + "-r" { + set report_at [shift argv] + } + default { + usage + } + } +} +if {[llength $argv]!=2} usage +set exe [lindex $argv 0] +set memfile [lindex $argv 1] + +# If stack traces are enabled, the 'addr2line' program is called to +# translate a binary stack address into a human-readable form. +set addr2line addr2line + +# When the SQLITE_MEMDEBUG is set as described above, SQLite prints +# out a line for each malloc(), realloc() or free() call that the +# library makes. If SQLITE_MEMDEBUG is 3, then a stack trace is printed +# out before each malloc() and realloc() line. +# +# This program parses each line the SQLite library outputs and updates +# the following global Tcl variables to reflect the "current" state of +# the heap used by SQLite. +# +set nBytes 0 ;# Total number of bytes currently allocated. +set nMalloc 0 ;# Total number of malloc()/realloc() calls. +set nPeak 0 ;# Peak of nBytes. +set iPeak 0 ;# nMalloc when nPeak was set. +# +# More detailed state information is stored in the $memmap array. +# Each key in the memmap array is the address of a chunk of memory +# currently allocated from the heap. The value is a list of the +# following form +# +# { } +# +array unset memmap proc process_input {input_file array_name} { upvar $array_name mem set input [open $input_file] set MALLOC {([[:digit:]]+) malloc ([[:digit:]]+) bytes at 0x([[:xdigit:]]+)} + # set STACK {^[[:digit:]]+: STACK: (.*)$} set STACK {^STACK: (.*)$} set FREE {[[:digit:]]+ free ([[:digit:]]+) bytes at 0x([[:xdigit:]]+)} set REALLOC {([[:digit:]]+) realloc ([[:digit:]]+) to ([[:digit:]]+)} @@ -66,6 +126,17 @@ proc process_input {input_file array_name} { set mem($addr) [list $bytes "malloc $mallocid" $stack] set stack "" + # Increase the current heap usage + incr ::nBytes $bytes + + # Increase the number of malloc() calls + incr ::nMalloc + + if {$::nBytes > $::nPeak} { + set ::nPeak $::nBytes + set ::iPeak $::nMalloc + } + } elseif { [regexp $FREE $line dummy bytes addr] } { # If this is a 'free' line, remove the entry from the mem array. If the # entry does not exist, or is the wrong number of bytes, announce a @@ -76,31 +147,86 @@ proc process_input {input_file array_name} { } unset mem($addr) + # Decrease the current heap usage + incr ::nBytes [expr -1 * $bytes] + } elseif { [regexp $REALLOC $line dummy mallocid ob b oa a] } { - # If it is a realloc line, remove the old mem entry and add a new one. + # "free" the old allocation in the internal model: + incr ::nBytes [expr -1 * $ob] unset mem($oa); + + # "malloc" the new allocation set mem($a) [list $b "realloc $mallocid" $stack] + incr ::nBytes $b set stack "" + + # Increase the number of malloc() calls + incr ::nMalloc + + if {$::nBytes > $::nPeak} { + set ::nPeak $::nBytes + set ::iPeak $::nMalloc + } + } else { # puts "REJECT: $line" } + + if {$::nMalloc==$::report_at} report } close $input } -process_input [lindex $argv 1] mem -set exe [lindex $argv 0] - -foreach key [array names mem] { - set bytes [lindex $mem($key) 0] - set mallocid [lindex $mem($key) 1] - set stack [lindex $mem($key) 2] - puts "Leaked $bytes bytes at 0x$key: $mallocid" - foreach frame [lrange $stack 1 10] { - foreach {f l} [split [exec $addr2line -f --exe=$exe $frame] \n] {} +proc printstack {stack} { + set fcount 10 + if {[llength $stack]<10} { + set fcount [llength $stack] + } + foreach frame [lrange $stack 1 $fcount] { + foreach {f l} [split [exec $::addr2line -f --exe=$::exe $frame] \n] {} puts [format "%-30s %s" $f $l] } if {[llength $stack]>0 } {puts ""} } +proc report {} { + + foreach key [array names ::memmap] { + set stack [lindex $::memmap($key) 2] + set bytes [lindex $::memmap($key) 0] + lappend summarymap($stack) $bytes + } + + foreach stack [array names summarymap] { + set allocs $summarymap($stack) + set sum 0 + foreach a $allocs { + incr sum $a + } + lappend sorted [list $sum $stack] + } + + set sorted [lsort -integer -index 0 $sorted] + foreach s $sorted { + set sum [lindex $s 0] + set stack [lindex $s 1] + set allocs $summarymap($stack) + puts "$sum bytes in [llength $allocs] chunks ($allocs)" + printstack $stack + } + + # Print out summary statistics + puts "Total allocations : $::nMalloc" + puts "Total outstanding allocations: [array size ::memmap]" + puts "Current heap usage : $::nBytes bytes" + puts "Peak heap usage : $::nPeak bytes (malloc #$::iPeak)" + + exit +} + +process_input $memfile memmap +report + + + diff --git a/ext/pdo_sqlite/sqlite/tool/mkkeywordhash.c b/ext/pdo_sqlite/sqlite/tool/mkkeywordhash.c index 265e3d1ea2..58d4b9cb78 100644 --- a/ext/pdo_sqlite/sqlite/tool/mkkeywordhash.c +++ b/ext/pdo_sqlite/sqlite/tool/mkkeywordhash.c @@ -32,68 +32,78 @@ struct Keyword { #ifdef SQLITE_OMIT_ALTERTABLE # define ALTER 0 #else -# define ALTER 1 +# define ALTER 0x00000001 +#endif +#define ALWAYS 0x00000002 +#ifdef SQLITE_OMIT_ANALYZE +# define ANALYZE 0 +#else +# define ANALYZE 0x00000004 #endif -#define ALWAYS 2 #ifdef SQLITE_OMIT_ATTACH # define ATTACH 0 #else -# define ATTACH 4 +# define ATTACH 0x00000008 #endif #ifdef SQLITE_OMIT_AUTOINCREMENT # define AUTOINCR 0 #else -# define AUTOINCR 8 +# define AUTOINCR 0x00000010 +#endif +#ifdef SQLITE_OMIT_CAST +# define CAST 0 +#else +# define CAST 0x00000020 #endif #ifdef SQLITE_OMIT_COMPOUND_SELECT # define COMPOUND 0 #else -# define COMPOUND 16 +# define COMPOUND 0x00000040 #endif #ifdef SQLITE_OMIT_CONFLICT_CLAUSE # define CONFLICT 0 #else -# define CONFLICT 32 +# define CONFLICT 0x00000080 #endif #ifdef SQLITE_OMIT_EXPLAIN # define EXPLAIN 0 #else -# define EXPLAIN 128 +# define EXPLAIN 0x00000100 #endif #ifdef SQLITE_OMIT_FOREIGN_KEY # define FKEY 0 #else -# define FKEY 256 +# define FKEY 0x00000200 #endif #ifdef SQLITE_OMIT_PRAGMA # define PRAGMA 0 #else -# define PRAGMA 512 +# define PRAGMA 0x00000400 #endif #ifdef SQLITE_OMIT_REINDEX # define REINDEX 0 #else -# define REINDEX 1024 +# define REINDEX 0x00000800 #endif #ifdef SQLITE_OMIT_SUBQUERY # define SUBQUERY 0 #else -# define SUBQUERY 2048 +# define SUBQUERY 0x00001000 #endif #ifdef SQLITE_OMIT_TRIGGER # define TRIGGER 0 #else -# define TRIGGER 4096 +# define TRIGGER 0x00002000 #endif #ifdef SQLITE_OMIT_VACUUM # define VACUUM 0 #else -# define VACUUM 8192 +# define VACUUM 0x00004000 #endif #ifdef SQLITE_OMIT_VIEW # define VIEW 0 #else -# define VIEW 16384 +# define VIEW 0x00008000 #endif @@ -102,9 +112,11 @@ struct Keyword { */ static Keyword aKeywordTable[] = { { "ABORT", "TK_ABORT", CONFLICT|TRIGGER }, + { "ADD", "TK_ADD", ALTER }, { "AFTER", "TK_AFTER", TRIGGER }, { "ALL", "TK_ALL", ALWAYS }, { "ALTER", "TK_ALTER", ALTER }, + { "ANALYZE", "TK_ANALYZE", ANALYZE }, { "AND", "TK_AND", ALWAYS }, { "AS", "TK_AS", ALWAYS }, { "ASC", "TK_ASC", ALWAYS }, @@ -116,16 +128,18 @@ static Keyword aKeywordTable[] = { { "BY", "TK_BY", ALWAYS }, { "CASCADE", "TK_CASCADE", FKEY }, { "CASE", "TK_CASE", ALWAYS }, + { "CAST", "TK_CAST", CAST }, { "CHECK", "TK_CHECK", ALWAYS }, { "COLLATE", "TK_COLLATE", ALWAYS }, + { "COLUMN", "TK_COLUMNKW", ALTER }, { "COMMIT", "TK_COMMIT", ALWAYS }, { "CONFLICT", "TK_CONFLICT", CONFLICT }, { "CONSTRAINT", "TK_CONSTRAINT", ALWAYS }, { "CREATE", "TK_CREATE", ALWAYS }, { "CROSS", "TK_JOIN_KW", ALWAYS }, - { "CURRENT_DATE", "TK_CDATE", ALWAYS }, - { "CURRENT_TIME", "TK_CTIME", ALWAYS }, - { "CURRENT_TIMESTAMP","TK_CTIMESTAMP", ALWAYS }, + { "CURRENT_DATE", "TK_CTIME_KW", ALWAYS }, + { "CURRENT_TIME", "TK_CTIME_KW", ALWAYS }, + { "CURRENT_TIMESTAMP","TK_CTIME_KW", ALWAYS }, { "DATABASE", "TK_DATABASE", ATTACH }, { "DEFAULT", "TK_DEFAULT", ALWAYS }, { "DEFERRED", "TK_DEFERRED", ALWAYS }, @@ -148,7 +162,7 @@ static Keyword aKeywordTable[] = { { "FOREIGN", "TK_FOREIGN", FKEY }, { "FROM", "TK_FROM", ALWAYS }, { "FULL", "TK_JOIN_KW", ALWAYS }, - { "GLOB", "TK_GLOB", ALWAYS }, + { "GLOB", "TK_LIKE_KW", ALWAYS }, { "GROUP", "TK_GROUP", ALWAYS }, { "HAVING", "TK_HAVING", ALWAYS }, { "IGNORE", "TK_IGNORE", CONFLICT|TRIGGER }, @@ -166,7 +180,7 @@ static Keyword aKeywordTable[] = { { "JOIN", "TK_JOIN", ALWAYS }, { "KEY", "TK_KEY", ALWAYS }, { "LEFT", "TK_JOIN_KW", ALWAYS }, - { "LIKE", "TK_LIKE", ALWAYS }, + { "LIKE", "TK_LIKE_KW", ALWAYS }, { "LIMIT", "TK_LIMIT", ALWAYS }, { "MATCH", "TK_MATCH", ALWAYS }, { "NATURAL", "TK_JOIN_KW", ALWAYS }, @@ -183,6 +197,7 @@ static Keyword aKeywordTable[] = { { "PRIMARY", "TK_PRIMARY", ALWAYS }, { "RAISE", "TK_RAISE", TRIGGER }, { "REFERENCES", "TK_REFERENCES", FKEY }, + { "REGEXP", "TK_LIKE_KW", ALWAYS }, { "REINDEX", "TK_REINDEX", REINDEX }, { "RENAME", "TK_RENAME", ALTER }, { "REPLACE", "TK_REPLACE", CONFLICT }, diff --git a/ext/pdo_sqlite/sqlite/tool/spaceanal.tcl b/ext/pdo_sqlite/sqlite/tool/spaceanal.tcl index e42fb28de4..c9b8f92e25 100644 --- a/ext/pdo_sqlite/sqlite/tool/spaceanal.tcl +++ b/ext/pdo_sqlite/sqlite/tool/spaceanal.tcl @@ -5,7 +5,7 @@ # Get the name of the database to analyze # -set argv $argv0 +#set argv $argv0 if {[llength $argv]!=1} { puts stderr "Usage: $argv0 database-name" exit 1 @@ -29,7 +29,10 @@ if {[file size $file_to_analyze]<512} { sqlite3 db [lindex $argv 0] set DB [btree_open [lindex $argv 0] 1000 0] -# In-memory database for collecting statistics +# In-memory database for collecting statistics. This script loops through +# the tables and indices in the database being analyzed, adding a row for each +# to an in-memory database (for which the schema is shown below). It then +# queries the in-memory db to produce the space-analysis report. # sqlite3 mem :memory: set tabledef\ @@ -52,32 +55,80 @@ set tabledef\ );} mem eval $tabledef -# This query will be used to find the root page number for every table -# in the database. -# -set sql { - SELECT name, rootpage - FROM sqlite_master WHERE type='table' - UNION ALL - SELECT 'sqlite_master', 1 - ORDER BY 1 +proc integerify {real} { + return [expr int($real)] } +mem function int integerify -# Quote a string for SQL +# Quote a string for use in an SQL query. Examples: # -proc quote txt { +# [quote {hello world}] == {'hello world'} +# [quote {hello world's}] == {'hello world''s'} +# +proc quote {txt} { regsub -all ' $txt '' q return '$q' } -# Analyze every table in the database, one at a time. +# This proc is a wrapper around the btree_cursor_info command. The +# second argument is an open btree cursor returned by [btree_cursor]. +# The first argument is the name of an array variable that exists in +# the scope of the caller. If the third argument is non-zero, then +# info is returned for the page that lies $up entries upwards in the +# tree-structure. (i.e. $up==1 returns the parent page, $up==2 the +# grandparent etc.) +# +# The following entries in that array are filled in with information retrieved +# using [btree_cursor_info]: +# +# $arrayvar(page_no) = The page number +# $arrayvar(entry_no) = The entry number +# $arrayvar(page_entries) = Total number of entries on this page +# $arrayvar(cell_size) = Cell size (local payload + header) +# $arrayvar(page_freebytes) = Number of free bytes on this page +# $arrayvar(page_freeblocks) = Number of free blocks on the page +# $arrayvar(payload_bytes) = Total payload size (local + overflow) +# $arrayvar(header_bytes) = Header size in bytes +# $arrayvar(local_payload_bytes) = Local payload size +# $arrayvar(parent) = Parent page number +# +proc cursor_info {arrayvar csr {up 0}} { + upvar $arrayvar a + foreach [list a(page_no) \ + a(entry_no) \ + a(page_entries) \ + a(cell_size) \ + a(page_freebytes) \ + a(page_freeblocks) \ + a(payload_bytes) \ + a(header_bytes) \ + a(local_payload_bytes) \ + a(parent) ] [btree_cursor_info $csr $up] {} +} + +# Determine the page-size of the database. This global variable is used +# throughout the script. # set pageSize [db eval {PRAGMA page_size}] + +# Analyze every table in the database, one at a time. +# +# The following query returns the name and root-page of each table in the +# database, including the sqlite_master table. +# +set sql { + SELECT name, rootpage FROM sqlite_master WHERE type='table' + UNION ALL + SELECT 'sqlite_master', 1 + ORDER BY 1 +} foreach {name rootpage} [db eval $sql] { puts stderr "Analyzing table $name..." - set cursor [btree_cursor $DB $rootpage 0] - set go [btree_first $cursor] - catch {unset seen} + + # Code below traverses the table being analyzed (table name $name), using the + # btree cursor $cursor. Statistics related to table $name are accumulated in + # the following variables: + # set total_payload 0 ;# Payload space used by all entries set total_ovfl 0 ;# Payload space on overflow pages set unused_int 0 ;# Unused space on interior nodes @@ -90,14 +141,35 @@ foreach {name rootpage} [db eval $sql] { set ovfl_pages 0 ;# Number of overflow pages used set leaf_pages 0 ;# Number of leaf pages set int_pages 0 ;# Number of interior pages - while {$go==0} { + + # As the btree is traversed, the array variable $seen($pgno) is set to 1 + # the first time page $pgno is encountered. + # + catch {unset seen} + + # The following loop runs once for each entry in table $name. The table + # is traversed using the btree cursor stored in variable $csr + # + set csr [btree_cursor $DB $rootpage 0] + for {btree_first $csr} {![btree_eof $csr]} {btree_next $csr} { incr cnt_leaf_entry - set stat [btree_cursor_info $cursor] - set payload [lindex $stat 6] - if {$payload>$mx_payload} {set mx_payload $payload} - incr total_payload $payload - set local [lindex $stat 8] - set ovfl [expr {$payload-$local}] + + # Retrieve information about the entry the btree-cursor points to into + # the array variable $ci (cursor info). + # + cursor_info ci $csr + + # Check if the payload of this entry is greater than the current + # $mx_payload statistic for the table. Also increase the $total_payload + # statistic. + # + if {$ci(payload_bytes)>$mx_payload} {set mx_payload $ci(payload_bytes)} + incr total_payload $ci(payload_bytes) + + # If this entry uses overflow pages, then update the $cnt_ovfl, + # $total_ovfl, $ovfl_pages and $unused_ovfl statistics. + # + set ovfl [expr {$ci(payload_bytes)-$ci(local_payload_bytes)}] if {$ovfl} { incr cnt_ovfl incr total_ovfl $ovfl @@ -105,33 +177,59 @@ foreach {name rootpage} [db eval $sql] { incr ovfl_pages $n incr unused_ovfl [expr {$n*($pageSize-4) - $ovfl}] } - set pgno [lindex $stat 0] - if {![info exists seen($pgno)]} { - set seen($pgno) 1 + + # If this is the first table entry analyzed for the page, then update + # the page-related statistics $leaf_pages and $unused_leaf. Also, if + # this page has a parent page that has not been analyzed, retrieve + # info for the parent and update statistics for it too. + # + if {![info exists seen($ci(page_no))]} { + set seen($ci(page_no)) 1 incr leaf_pages - incr unused_leaf [lindex $stat 4] - set parent [lindex $stat 9] - set up 0 - while {$parent!=0 && ![info exists seen($parent)]} { - incr up - set stat [btree_cursor_info $cursor $up] - set seen($parent) 1 + incr unused_leaf $ci(page_freebytes) + + # Now check if the page has a parent that has not been analyzed. If + # so, update the $int_pages, $cnt_int_entry and $unused_int statistics + # accordingly. Then check if the parent page has a parent that has + # not yet been analyzed etc. + # + # set parent $ci(parent_page_no) + for {set up 1} \ + {$ci(parent)!=0 && ![info exists seen($ci(parent))]} {incr up} \ + { + # Mark the parent as seen. + # + set seen($ci(parent)) 1 + + # Retrieve info for the parent and update statistics. + cursor_info ci $csr $up incr int_pages - incr cnt_int_entry [lindex $stat 2] - incr unused_int [lindex $stat 4] - set parent [lindex $stat 9] + incr cnt_int_entry $ci(page_entries) + incr unused_int $ci(page_freebytes) } } - set go [btree_next $cursor] } - btree_close_cursor $cursor + btree_close_cursor $csr + + # Handle the special case where a table contains no data. In this case + # all statistics are zero, except for the number of leaf pages (1) and + # the unused bytes on leaf pages ($pageSize - 8). + # + # An exception to the above is the sqlite_master table. If it is empty + # then all statistics are zero except for the number of leaf pages (1), + # and the number of unused bytes on leaf pages ($pageSize - 112). + # if {[llength [array names seen]]==0} { set leaf_pages 1 - set unused_leaf [expr {$pageSize-8}] - } elseif {$rootpage==1 && ![info exists seen(1)]} { - incr int_pages - incr unused_int [expr {$pageSize-112}] + if {$rootpage==1} { + set unused_leaf [expr {$pageSize-112}] + } else { + set unused_leaf [expr {$pageSize-8}] + } } + + # Insert the statistics for the table analyzed into the in-memory database. + # set sql "INSERT INTO space_used VALUES(" append sql [quote $name] append sql ",[quote $name]" @@ -152,23 +250,22 @@ foreach {name rootpage} [db eval $sql] { mem eval $sql } -# This query will be used to find the root page number for every index -# in the database. +# Analyze every index in the database, one at a time. +# +# The query below returns the name, associated table and root-page number +# for every index in the database. # set sql { - SELECT name, tbl_name, rootpage - FROM sqlite_master WHERE type='index' + SELECT name, tbl_name, rootpage FROM sqlite_master WHERE type='index' ORDER BY 2, 1 } - -# Analyze every index in the database, one at a time. -# -set pageSize [db eval {PRAGMA page_size}] foreach {name tbl_name rootpage} [db eval $sql] { puts stderr "Analyzing index $name of table $tbl_name..." - set cursor [btree_cursor $DB $rootpage 0] - set go [btree_first $cursor] - catch {unset seen} + + # Code below traverses the index being analyzed (index name $name), using the + # btree cursor $cursor. Statistics related to index $name are accumulated in + # the following variables: + # set total_payload 0 ;# Payload space used by all entries set total_ovfl 0 ;# Payload space on overflow pages set unused_leaf 0 ;# Unused space on leaf nodes @@ -178,14 +275,36 @@ foreach {name tbl_name rootpage} [db eval $sql] { set mx_payload 0 ;# Maximum payload size set ovfl_pages 0 ;# Number of overflow pages used set leaf_pages 0 ;# Number of leaf pages - while {$go==0} { + + # As the btree is traversed, the array variable $seen($pgno) is set to 1 + # the first time page $pgno is encountered. + # + catch {unset seen} + + # The following loop runs once for each entry in index $name. The index + # is traversed using the btree cursor stored in variable $csr + # + set csr [btree_cursor $DB $rootpage 0] + for {btree_first $csr} {![btree_eof $csr]} {btree_next $csr} { incr cnt_leaf_entry - set stat [btree_cursor_info $cursor] - set payload [btree_keysize $cursor] + + # Retrieve information about the entry the btree-cursor points to into + # the array variable $ci (cursor info). + # + cursor_info ci $csr + + # Check if the payload of this entry is greater than the current + # $mx_payload statistic for the table. Also increase the $total_payload + # statistic. + # + set payload [btree_keysize $csr] if {$payload>$mx_payload} {set mx_payload $payload} incr total_payload $payload - set local [lindex $stat 8] - set ovfl [expr {$payload-$local}] + + # If this entry uses overflow pages, then update the $cnt_ovfl, + # $total_ovfl, $ovfl_pages and $unused_ovfl statistics. + # + set ovfl [expr {$payload-$ci(local_payload_bytes)}] if {$ovfl} { incr cnt_ovfl incr total_ovfl $ovfl @@ -193,19 +312,29 @@ foreach {name tbl_name rootpage} [db eval $sql] { incr ovfl_pages $n incr unused_ovfl [expr {$n*($pageSize-4) - $ovfl}] } - set pgno [lindex $stat 0] - if {![info exists seen($pgno)]} { - set seen($pgno) 1 + + # If this is the first table entry analyzed for the page, then update + # the page-related statistics $leaf_pages and $unused_leaf. + # + if {![info exists seen($ci(page_no))]} { + set seen($ci(page_no)) 1 incr leaf_pages - incr unused_leaf [lindex $stat 4] + incr unused_leaf $ci(page_freebytes) } - set go [btree_next $cursor] } - btree_close_cursor $cursor + btree_close_cursor $csr + + # Handle the special case where a index contains no data. In this case + # all statistics are zero, except for the number of leaf pages (1) and + # the unused bytes on leaf pages ($pageSize - 8). + # if {[llength [array names seen]]==0} { set leaf_pages 1 set unused_leaf [expr {$pageSize-8}] } + + # Insert the statistics for the index analyzed into the in-memory database. + # set sql "INSERT INTO space_used VALUES(" append sql [quote $name] append sql ",[quote $tbl_name]" @@ -246,7 +375,7 @@ proc percent {num denom {of {}}} { if {$denom==0.0} {return ""} set v [expr {$num*100.0/$denom}] set of {} - if {$v==1.0 || $v==0.0 || ($v>1.0 && $v<99.0)} { + if {$v==100.0 || $v<0.001 || ($v>1.0 && $v<99.0)} { return [format {%5.1f%% %s} $v $of] } elseif {$v<0.1 || $v>99.9} { return [format {%7.3f%% %s} $v $of] @@ -255,63 +384,106 @@ proc percent {num denom {of {}}} { } } +proc divide {num denom} { + if {$denom==0} {return 0.0} + return [format %.2f [expr double($num)/double($denom)]] +} + # Generate a subreport that covers some subset of the database. # the $where clause determines which subset to analyze. # proc subreport {title where} { - global pageSize - set hit 0 + global pageSize file_pgcnt + + # Query the in-memory database for the sum of various statistics + # for the subset of tables/indices identified by the WHERE clause in + # $where. Note that even if the WHERE clause matches no rows, the + # following query returns exactly one row (because it is an aggregate). + # + # The results of the query are stored directly by SQLite into local + # variables (i.e. $nentry, $nleaf etc.). + # mem eval " SELECT - sum(nentry) AS nentry, - sum(leaf_entries) AS nleaf, - sum(payload) AS payload, - sum(ovfl_payload) AS ovfl_payload, + int(sum(nentry)) AS nentry, + int(sum(leaf_entries)) AS nleaf, + int(sum(payload)) AS payload, + int(sum(ovfl_payload)) AS ovfl_payload, max(mx_payload) AS mx_payload, - sum(ovfl_cnt) as ovfl_cnt, - sum(leaf_pages) AS leaf_pages, - sum(int_pages) AS int_pages, - sum(ovfl_pages) AS ovfl_pages, - sum(leaf_unused) AS leaf_unused, - sum(int_unused) AS int_unused, - sum(ovfl_unused) AS ovfl_unused - FROM space_used WHERE $where" {} {set hit 1} - if {!$hit} {return 0} + int(sum(ovfl_cnt)) as ovfl_cnt, + int(sum(leaf_pages)) AS leaf_pages, + int(sum(int_pages)) AS int_pages, + int(sum(ovfl_pages)) AS ovfl_pages, + int(sum(leaf_unused)) AS leaf_unused, + int(sum(int_unused)) AS int_unused, + int(sum(ovfl_unused)) AS ovfl_unused + FROM space_used WHERE $where" {} {} + + # Output the sub-report title, nicely decorated with * characters. + # puts "" set len [string length $title] - incr len 5 - set stars "***********************************" - append stars $stars - set stars [string range $stars $len end] + set stars [string repeat * [expr 65-$len]] puts "*** $title $stars" puts "" + + # Calculate statistics and store the results in TCL variables, as follows: + # + # total_pages: Database pages consumed. + # total_pages_percent: Pages consumed as a percentage of the file. + # storage: Bytes consumed. + # payload_percent: Payload bytes used as a percentage of $storage. + # total_unused: Unused bytes on pages. + # avg_payload: Average payload per btree entry. + # avg_fanout: Average fanout for internal pages. + # avg_unused: Average unused bytes per btree entry. + # ovfl_cnt_percent: Percentage of btree entries that use overflow pages. + # set total_pages [expr {$leaf_pages+$int_pages+$ovfl_pages}] - statline "Percentage of total database" [percent $total_pages $::file_pgcnt] - statline "Number of entries" $nleaf - set total_unused [expr {$ovfl_unused+$int_unused+$leaf_unused}] + set total_pages_percent [percent $total_pages $file_pgcnt] set storage [expr {$total_pages*$pageSize}] - statline "Bytes of storage consumed" $storage - statline "Bytes of payload" $payload \ - [percent $payload $storage {of storage consumed}] - statline "Average payload per entry" [expr {$nleaf>0?$payload/$nleaf:0}] - set avgunused [expr {$nleaf>0?$total_unused/$nleaf:0}] - statline "Average unused bytes per entry" $avgunused - set nint [expr {$nentry-$nleaf}] + set payload_percent [percent $payload $storage {of storage consumed}] + set total_unused [expr {$ovfl_unused+$int_unused+$leaf_unused}] + set avg_payload [divide $payload $nleaf] + set avg_unused [divide $total_unused $nleaf] if {$int_pages>0} { - statline "Average fanout" [format %.2f [expr {($nint+0.0)/$int_pages}]] + # TODO: Is this formula correct? + set nTab [mem eval " + SELECT count(*) FROM ( + SELECT DISTINCT tblname FROM space_used WHERE $where AND is_index=0 + ) + "] + set avg_fanout [mem eval " + SELECT (sum(leaf_pages+int_pages)-$nTab)/sum(int_pages) FROM space_used + WHERE $where AND is_index = 0 + "] + set avg_fanout [format %.2f $avg_fanout] + } + set ovfl_cnt_percent [percent $ovfl_cnt $nleaf {of all entries}] + + # Print out the sub-report statistics. + # + statline {Percentage of total database} $total_pages_percent + statline {Number of entries} $nleaf + statline {Bytes of storage consumed} $storage + statline {Bytes of payload} $payload $payload_percent + statline {Average payload per entry} $avg_payload + statline {Average unused bytes per entry} $avg_unused + if {[info exists avg_fanout]} { + statline {Average fanout} $avg_fanout } - statline "Maximum payload per entry" $mx_payload - statline "Entries that use overflow" $ovfl_cnt \ - [percent $ovfl_cnt $nleaf {of all entries}] + statline {Maximum payload per entry} $mx_payload + statline {Entries that use overflow} $ovfl_cnt $ovfl_cnt_percent if {$int_pages>0} { - statline "Index pages used" $int_pages + statline {Index pages used} $int_pages } - statline "Primary pages used" $leaf_pages - statline "Overflow pages used" $ovfl_pages - statline "Total pages used" $total_pages + statline {Primary pages used} $leaf_pages + statline {Overflow pages used} $ovfl_pages + statline {Total pages used} $total_pages if {$int_unused>0} { - statline "Unused bytes on index pages" $int_unused \ + set int_unused_percent \ [percent $int_unused [expr {$int_pages*$pageSize}] {of index space}] + statline "Unused bytes on index pages" $int_unused $int_unused_percent } statline "Unused bytes on primary pages" $leaf_unused \ [percent $leaf_unused [expr {$leaf_pages*$pageSize}] {of primary space}] @@ -322,42 +494,106 @@ proc subreport {title where} { return 1 } -# Output summary statistics: +# Calculate the overhead in pages caused by auto-vacuum. +# +# This procedure calculates and returns the number of pages used by the +# auto-vacuum 'pointer-map'. If the database does not support auto-vacuum, +# then 0 is returned. The two arguments are the size of the database file in +# pages and the page size used by the database (in bytes). +proc autovacuum_overhead {filePages pageSize} { + + # Read the value of meta 4. If non-zero, then the database supports + # auto-vacuum. It would be possible to use "PRAGMA auto_vacuum" instead, + # but that would not work if the SQLITE_OMIT_PRAGMA macro was defined + # when the library was built. + set meta4 [lindex [btree_get_meta $::DB] 4] + + # If the database is not an auto-vacuum database or the file consists + # of one page only then there is no overhead for auto-vacuum. Return zero. + if {0==$meta4 || $filePages==1} { + return 0 + } + + # The number of entries on each pointer map page. The layout of the + # database file is one pointer-map page, followed by $ptrsPerPage other + # pages, followed by a pointer-map page etc. The first pointer-map page + # is the second page of the file overall. + set ptrsPerPage [expr double($pageSize/5)] + + # Return the number of pointer map pages in the database. + return [expr int(ceil( ($filePages-1.0)/($ptrsPerPage+1.0) ))] +} + + +# Calculate the summary statistics for the database and store the results +# in TCL variables. They are output below. Variables are as follows: +# +# pageSize: Size of each page in bytes. +# file_bytes: File size in bytes. +# file_pgcnt: Number of pages in the file. +# file_pgcnt2: Number of pages in the file (calculated). +# av_pgcnt: Pages consumed by the auto-vacuum pointer-map. +# av_percent: Percentage of the file consumed by auto-vacuum pointer-map. +# inuse_pgcnt: Data pages in the file. +# inuse_percent: Percentage of pages used to store data. +# free_pgcnt: Free pages calculated as ( - ) +# free_pgcnt2: Free pages in the file according to the file header. +# free_percent: Percentage of file consumed by free pages (calculated). +# free_percent2: Percentage of file consumed by free pages (header). +# ntable: Number of tables in the db. +# nindex: Number of indices in the db. +# nautoindex: Number of indices created automatically. +# nmanindex: Number of indices created manually. +# user_payload: Number of bytes of payload in table btrees +# (not including sqlite_master) +# user_percent: $user_payload as a percentage of total file size. + +set file_bytes [file size $file_to_analyze] +set file_pgcnt [expr {$file_bytes/$pageSize}] + +set av_pgcnt [autovacuum_overhead $file_pgcnt $pageSize] +set av_percent [percent $av_pgcnt $file_pgcnt] + +set sql {SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM space_used} +set inuse_pgcnt [expr int([mem eval $sql])] +set inuse_percent [percent $inuse_pgcnt $file_pgcnt] + +set free_pgcnt [expr $file_pgcnt-$inuse_pgcnt-$av_pgcnt] +set free_percent [percent $free_pgcnt $file_pgcnt] +set free_pgcnt2 [lindex [btree_get_meta $DB] 0] +set free_percent2 [percent $free_pgcnt2 $file_pgcnt] + +set file_pgcnt2 [expr {$inuse_pgcnt+$free_pgcnt2+$av_pgcnt}] + +set ntable [db eval {SELECT count(*)+1 FROM sqlite_master WHERE type='table'}] +set nindex [db eval {SELECT count(*) FROM sqlite_master WHERE type='index'}] +set sql {SELECT count(*) FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'} +set nautoindex [db eval $sql] +set nmanindex [expr {$nindex-$nautoindex}] + +# set total_payload [mem eval "SELECT sum(payload) FROM space_used"] +set user_payload [mem one {SELECT int(sum(payload)) FROM space_used + WHERE NOT is_index AND name NOT LIKE 'sqlite_master'}] +set user_percent [percent $user_payload $file_bytes] + +# Output the summary statistics calculated above. # puts "/** Disk-Space Utilization Report For $file_to_analyze" puts "*** As of [clock format [clock seconds] -format {%Y-%b-%d %H:%M:%S}]" puts "" statline {Page size in bytes} $pageSize -set fsize [file size $file_to_analyze] -set file_pgcnt [expr {$fsize/$pageSize}] -set usedcnt [mem eval \ - {SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM space_used}] -set freecnt [expr {$file_pgcnt-$usedcnt}] -set freecnt2 [lindex [btree_get_meta $DB] 0] statline {Pages in the whole file (measured)} $file_pgcnt -set file_pgcnt2 [expr {$usedcnt+$freecnt2}] statline {Pages in the whole file (calculated)} $file_pgcnt2 -statline {Pages that store data} $usedcnt [percent $usedcnt $file_pgcnt] -statline {Pages on the freelist (per header)}\ - $freecnt2 [percent $freecnt2 $file_pgcnt] -statline {Pages on the freelist (calculated)}\ - $freecnt [percent $freecnt $file_pgcnt] - -set ntable [db eval {SELECT count(*)+1 FROM sqlite_master WHERE type='table'}] +statline {Pages that store data} $inuse_pgcnt $inuse_percent +statline {Pages on the freelist (per header)} $free_pgcnt2 $free_percent2 +statline {Pages on the freelist (calculated)} $free_pgcnt $free_percent +statline {Pages of auto-vacuum overhead} $av_pgcnt $av_percent statline {Number of tables in the database} $ntable -set nindex [db eval {SELECT count(*) FROM sqlite_master WHERE type='index'}] -set autoindex [db eval {SELECT count(*) FROM sqlite_master - WHERE type='index' AND name LIKE '(% autoindex %)'}] -set manindex [expr {$nindex-$autoindex}] statline {Number of indices} $nindex -statline {Number of named indices} $manindex -statline {Automatically generated indices} $autoindex -set total_payload [mem eval "SELECT sum(payload) FROM space_used"] -statline "Size of the file in bytes" $fsize -set user_payload [mem one {SELECT sum(payload) FROM space_used - WHERE NOT is_index AND name NOT LIKE 'sqlite_master'}] -statline "Bytes of user payload stored" $user_payload \ - [percent $user_payload $fsize] +statline {Number of named indices} $nmanindex +statline {Automatically generated indices} $nautoindex +statline {Size of the file in bytes} $file_bytes +statline {Bytes of user payload stored} $user_payload $user_percent # Output table rankings # @@ -365,8 +601,8 @@ puts "" puts "*** Page counts for all tables with their indices ********************" puts "" mem eval {SELECT tblname, count(*) AS cnt, - sum(int_pages+leaf_pages+ovfl_pages) AS size - FROM space_used GROUP BY tblname ORDER BY size DESC, tblname} {} { + int(sum(int_pages+leaf_pages+ovfl_pages)) AS size + FROM space_used GROUP BY tblname ORDER BY size+0 DESC, tblname} {} { statline [string toupper $tblname] $size [percent $size $file_pgcnt] } @@ -422,6 +658,11 @@ Pages on the freelist future use. The percentage at the right is the number of freelist pages divided by the total number of pages in the file. +Pages of auto-vacuum overhead + + The number of pages that store data used by the database to facilitate + auto-vacuum. This is zero for databases that do not support auto-vacuum. + Number of tables in the database The number of tables in the database, including the SQLITE_MASTER table @@ -535,7 +776,8 @@ Unused bytes on all pages divided by the total number of bytes. } -# Output the database +# Output a dump of the in-memory database. This can be used for more +# complex offline analysis. # puts "**********************************************************************" puts "The entire text of this report can be sourced into any SQL database"