summaryrefslogtreecommitdiffstats
path: root/src/sqlite
diff options
context:
space:
mode:
authorMavridis Philippe <[email protected]>2021-01-13 19:26:24 +0200
committerMavridis Philippe <[email protected]>2021-01-13 19:26:24 +0200
commit8c20dc919f7d54eb48fb60f39ba5e1d466a70763 (patch)
tree44d89f278d5dd066603e5ab9c0b270bc8eb4ad51 /src/sqlite
downloadklamav-8c20dc919f7d54eb48fb60f39ba5e1d466a70763.tar.gz
klamav-8c20dc919f7d54eb48fb60f39ba5e1d466a70763.zip
Initial commit
Signed-off-by: Mavridis Philippe <[email protected]>
Diffstat (limited to 'src/sqlite')
-rw-r--r--src/sqlite/Makefile.am52
-rw-r--r--src/sqlite/Makefile.in1043
-rw-r--r--src/sqlite/alter.c553
-rw-r--r--src/sqlite/attach.c352
-rw-r--r--src/sqlite/auth.c224
-rw-r--r--src/sqlite/btree.c5812
-rw-r--r--src/sqlite/btree.h143
-rw-r--r--src/sqlite/build.c2881
-rw-r--r--src/sqlite/callback.c306
-rw-r--r--src/sqlite/date.c1000
-rw-r--r--src/sqlite/delete.c447
-rw-r--r--src/sqlite/expr.c2071
-rw-r--r--src/sqlite/func.c1043
-rw-r--r--src/sqlite/hash.c387
-rw-r--r--src/sqlite/hash.h109
-rw-r--r--src/sqlite/insert.c1111
-rw-r--r--src/sqlite/keywordhash.h96
-rw-r--r--src/sqlite/legacy.c138
-rw-r--r--src/sqlite/main.c1003
-rw-r--r--src/sqlite/opcodes.c135
-rw-r--r--src/sqlite/opcodes.h144
-rw-r--r--src/sqlite/os.h202
-rw-r--r--src/sqlite/os_common.h107
-rw-r--r--src/sqlite/os_unix.c1345
-rw-r--r--src/sqlite/os_unix.h102
-rw-r--r--src/sqlite/os_win.c767
-rw-r--r--src/sqlite/os_win.h40
-rw-r--r--src/sqlite/pager.c3604
-rw-r--r--src/sqlite/pager.h115
-rw-r--r--src/sqlite/parse.c3355
-rw-r--r--src/sqlite/parse.h140
-rw-r--r--src/sqlite/pragma.c933
-rw-r--r--src/sqlite/prepare.c529
-rw-r--r--src/sqlite/printf.c831
-rw-r--r--src/sqlite/random.c100
-rw-r--r--src/sqlite/select.c2868
-rw-r--r--src/sqlite/sqlite3.h1267
-rw-r--r--src/sqlite/sqliteInt.h1571
-rw-r--r--src/sqlite/table.c195
-rw-r--r--src/sqlite/tokenize.c670
-rw-r--r--src/sqlite/trigger.c802
-rw-r--r--src/sqlite/update.c505
-rw-r--r--src/sqlite/utf.c570
-rw-r--r--src/sqlite/util.c964
-rw-r--r--src/sqlite/vacuum.c310
-rw-r--r--src/sqlite/vdbe.c4692
-rw-r--r--src/sqlite/vdbe.h132
-rw-r--r--src/sqlite/vdbeInt.h413
-rw-r--r--src/sqlite/vdbeapi.c701
-rw-r--r--src/sqlite/vdbeaux.c1997
-rw-r--r--src/sqlite/vdbemem.c806
-rw-r--r--src/sqlite/where.c1439
52 files changed, 51122 insertions, 0 deletions
diff --git a/src/sqlite/Makefile.am b/src/sqlite/Makefile.am
new file mode 100644
index 0000000..a835329
--- /dev/null
+++ b/src/sqlite/Makefile.am
@@ -0,0 +1,52 @@
+noinst_LTLIBRARIES = \
+ libsqlite.la
+
+KDE_CFLAGS = \
+ -w
+
+libsqlite_la_CFLAGS = \
+ $(all_includes) \
+ -DTHREADSAFE=1 \
+ -DHAVE_USLEEP=1
+
+libsqlite_la_LDFLAGS = \
+ $(LIBPTHREAD)
+
+libsqlite_la_SOURCES = \
+ alter.c \
+ 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 \
+ opcodes.c \
+ os_unix.c \
+ os_win.c \
+ pager.c \
+ parse.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 \
+ vdbe.c \
+ vdbeapi.c \
+ vdbeaux.c \
+ vdbemem.c \
+ where.c
+
diff --git a/src/sqlite/Makefile.in b/src/sqlite/Makefile.in
new file mode 100644
index 0000000..93cff89
--- /dev/null
+++ b/src/sqlite/Makefile.in
@@ -0,0 +1,1043 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 1.3 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src/sqlite
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libsqlite_la_LIBADD =
+am_libsqlite_la_OBJECTS = libsqlite_la-alter.lo libsqlite_la-attach.lo \
+ libsqlite_la-auth.lo libsqlite_la-btree.lo \
+ libsqlite_la-build.lo libsqlite_la-callback.lo \
+ libsqlite_la-date.lo libsqlite_la-delete.lo \
+ libsqlite_la-expr.lo libsqlite_la-func.lo libsqlite_la-hash.lo \
+ libsqlite_la-insert.lo libsqlite_la-legacy.lo \
+ libsqlite_la-main.lo libsqlite_la-opcodes.lo \
+ libsqlite_la-os_unix.lo libsqlite_la-os_win.lo \
+ libsqlite_la-pager.lo libsqlite_la-parse.lo \
+ libsqlite_la-pragma.lo libsqlite_la-prepare.lo \
+ libsqlite_la-printf.lo libsqlite_la-random.lo \
+ libsqlite_la-select.lo libsqlite_la-table.lo \
+ libsqlite_la-tokenize.lo libsqlite_la-trigger.lo \
+ libsqlite_la-update.lo libsqlite_la-utf.lo \
+ libsqlite_la-util.lo libsqlite_la-vacuum.lo \
+ libsqlite_la-vdbe.lo libsqlite_la-vdbeapi.lo \
+ libsqlite_la-vdbeaux.lo libsqlite_la-vdbemem.lo \
+ libsqlite_la-where.lo
+#>- libsqlite_la_OBJECTS = $(am_libsqlite_la_OBJECTS)
+#>+ 21
+libsqlite_la_final_OBJECTS = alter.lo attach.lo auth.lo btree.lo build.lo callback.lo date.lo delete.lo expr.lo func.lo hash.lo insert.lo legacy.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 utf.lo util.lo vacuum.lo vdbe.lo vdbeapi.lo vdbeaux.lo vdbemem.lo where.lo
+libsqlite_la_nofinal_OBJECTS = libsqlite_la-alter.lo libsqlite_la-attach.lo \
+ libsqlite_la-auth.lo libsqlite_la-btree.lo \
+ libsqlite_la-build.lo libsqlite_la-callback.lo \
+ libsqlite_la-date.lo libsqlite_la-delete.lo \
+ libsqlite_la-expr.lo libsqlite_la-func.lo libsqlite_la-hash.lo \
+ libsqlite_la-insert.lo libsqlite_la-legacy.lo \
+ libsqlite_la-main.lo libsqlite_la-opcodes.lo \
+ libsqlite_la-os_unix.lo libsqlite_la-os_win.lo \
+ libsqlite_la-pager.lo libsqlite_la-parse.lo \
+ libsqlite_la-pragma.lo libsqlite_la-prepare.lo \
+ libsqlite_la-printf.lo libsqlite_la-random.lo \
+ libsqlite_la-select.lo libsqlite_la-table.lo \
+ libsqlite_la-tokenize.lo libsqlite_la-trigger.lo \
+ libsqlite_la-update.lo libsqlite_la-utf.lo \
+ libsqlite_la-util.lo libsqlite_la-vacuum.lo \
+ libsqlite_la-vdbe.lo libsqlite_la-vdbeapi.lo \
+ libsqlite_la-vdbeaux.lo libsqlite_la-vdbemem.lo \
+ libsqlite_la-where.lo
+@KDE_USE_FINAL_FALSE@libsqlite_la_OBJECTS = $(libsqlite_la_nofinal_OBJECTS)
+@KDE_USE_FINAL_TRUE@libsqlite_la_OBJECTS = $(libsqlite_la_final_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libsqlite_la_SOURCES)
+DIST_SOURCES = $(libsqlite_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_CLAM = @LIB_CLAM@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_SQLITE = @LIB_SQLITE@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKGCONFIGFOUND = @PKGCONFIGFOUND@
+PKG_CONFIG = @PKG_CONFIG@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SQLITE_CFLAGS = @SQLITE_CFLAGS@
+SQLITE_LIBS = @SQLITE_LIBS@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+include_ARTS_FALSE = @include_ARTS_FALSE@
+include_ARTS_TRUE = @include_ARTS_TRUE@
+include_x11_FALSE = @include_x11_FALSE@
+include_x11_TRUE = @include_x11_TRUE@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+unsermake_enable_pch_FALSE = @unsermake_enable_pch_FALSE@
+unsermake_enable_pch_TRUE = @unsermake_enable_pch_TRUE@
+with_included_sqlite_FALSE = @with_included_sqlite_FALSE@
+with_included_sqlite_TRUE = @with_included_sqlite_TRUE@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+noinst_LTLIBRARIES = \
+ libsqlite.la
+
+KDE_CFLAGS = \
+ -w
+
+libsqlite_la_CFLAGS = \
+ $(all_includes) \
+ -DTHREADSAFE=1 \
+ -DHAVE_USLEEP=1
+
+libsqlite_la_LDFLAGS = \
+ $(LIBPTHREAD)
+
+libsqlite_la_SOURCES = \
+ alter.c \
+ 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 \
+ opcodes.c \
+ os_unix.c \
+ os_win.c \
+ pager.c \
+ parse.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 \
+ vdbe.c \
+ vdbeapi.c \
+ vdbeaux.c \
+ vdbemem.c \
+ where.c
+
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sqlite/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu src/sqlite/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sqlite/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/sqlite/Makefile
+ cd $(top_srcdir) && perl admin/am_edit src/sqlite/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libsqlite.la: $(libsqlite_la_OBJECTS) $(libsqlite_la_DEPENDENCIES)
+ $(LINK) $(libsqlite_la_LDFLAGS) $(libsqlite_la_OBJECTS) $(libsqlite_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-alter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-attach.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-auth.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-btree.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-build.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-callback.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-date.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-delete.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-expr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-func.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-hash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-insert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-legacy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-opcodes.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-os_unix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-os_win.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-pager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-parse.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-pragma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-prepare.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-printf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-random.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-select.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-table.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-tokenize.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-trigger.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-update.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-utf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-vacuum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-vdbe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-vdbeapi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-vdbeaux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-vdbemem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsqlite_la-where.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libsqlite_la-alter.lo: alter.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-alter.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-alter.Tpo" -c -o libsqlite_la-alter.lo `test -f 'alter.c' || echo '$(srcdir)/'`alter.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-alter.Tpo" "$(DEPDIR)/libsqlite_la-alter.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-alter.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alter.c' object='libsqlite_la-alter.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-alter.lo `test -f 'alter.c' || echo '$(srcdir)/'`alter.c
+
+libsqlite_la-attach.lo: attach.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-attach.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-attach.Tpo" -c -o libsqlite_la-attach.lo `test -f 'attach.c' || echo '$(srcdir)/'`attach.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-attach.Tpo" "$(DEPDIR)/libsqlite_la-attach.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-attach.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='attach.c' object='libsqlite_la-attach.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-attach.lo `test -f 'attach.c' || echo '$(srcdir)/'`attach.c
+
+libsqlite_la-auth.lo: auth.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-auth.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-auth.Tpo" -c -o libsqlite_la-auth.lo `test -f 'auth.c' || echo '$(srcdir)/'`auth.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-auth.Tpo" "$(DEPDIR)/libsqlite_la-auth.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-auth.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth.c' object='libsqlite_la-auth.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-auth.lo `test -f 'auth.c' || echo '$(srcdir)/'`auth.c
+
+libsqlite_la-btree.lo: btree.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-btree.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-btree.Tpo" -c -o libsqlite_la-btree.lo `test -f 'btree.c' || echo '$(srcdir)/'`btree.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-btree.Tpo" "$(DEPDIR)/libsqlite_la-btree.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-btree.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='btree.c' object='libsqlite_la-btree.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-btree.lo `test -f 'btree.c' || echo '$(srcdir)/'`btree.c
+
+libsqlite_la-build.lo: build.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-build.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-build.Tpo" -c -o libsqlite_la-build.lo `test -f 'build.c' || echo '$(srcdir)/'`build.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-build.Tpo" "$(DEPDIR)/libsqlite_la-build.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-build.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='build.c' object='libsqlite_la-build.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-build.lo `test -f 'build.c' || echo '$(srcdir)/'`build.c
+
+libsqlite_la-callback.lo: callback.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-callback.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-callback.Tpo" -c -o libsqlite_la-callback.lo `test -f 'callback.c' || echo '$(srcdir)/'`callback.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-callback.Tpo" "$(DEPDIR)/libsqlite_la-callback.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-callback.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='callback.c' object='libsqlite_la-callback.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-callback.lo `test -f 'callback.c' || echo '$(srcdir)/'`callback.c
+
+libsqlite_la-date.lo: date.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-date.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-date.Tpo" -c -o libsqlite_la-date.lo `test -f 'date.c' || echo '$(srcdir)/'`date.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-date.Tpo" "$(DEPDIR)/libsqlite_la-date.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-date.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='date.c' object='libsqlite_la-date.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-date.lo `test -f 'date.c' || echo '$(srcdir)/'`date.c
+
+libsqlite_la-delete.lo: delete.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-delete.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-delete.Tpo" -c -o libsqlite_la-delete.lo `test -f 'delete.c' || echo '$(srcdir)/'`delete.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-delete.Tpo" "$(DEPDIR)/libsqlite_la-delete.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-delete.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='delete.c' object='libsqlite_la-delete.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-delete.lo `test -f 'delete.c' || echo '$(srcdir)/'`delete.c
+
+libsqlite_la-expr.lo: expr.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-expr.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-expr.Tpo" -c -o libsqlite_la-expr.lo `test -f 'expr.c' || echo '$(srcdir)/'`expr.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-expr.Tpo" "$(DEPDIR)/libsqlite_la-expr.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-expr.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='expr.c' object='libsqlite_la-expr.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-expr.lo `test -f 'expr.c' || echo '$(srcdir)/'`expr.c
+
+libsqlite_la-func.lo: func.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-func.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-func.Tpo" -c -o libsqlite_la-func.lo `test -f 'func.c' || echo '$(srcdir)/'`func.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-func.Tpo" "$(DEPDIR)/libsqlite_la-func.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-func.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='func.c' object='libsqlite_la-func.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-func.lo `test -f 'func.c' || echo '$(srcdir)/'`func.c
+
+libsqlite_la-hash.lo: hash.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-hash.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-hash.Tpo" -c -o libsqlite_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-hash.Tpo" "$(DEPDIR)/libsqlite_la-hash.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-hash.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hash.c' object='libsqlite_la-hash.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c
+
+libsqlite_la-insert.lo: insert.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-insert.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-insert.Tpo" -c -o libsqlite_la-insert.lo `test -f 'insert.c' || echo '$(srcdir)/'`insert.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-insert.Tpo" "$(DEPDIR)/libsqlite_la-insert.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-insert.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='insert.c' object='libsqlite_la-insert.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-insert.lo `test -f 'insert.c' || echo '$(srcdir)/'`insert.c
+
+libsqlite_la-legacy.lo: legacy.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-legacy.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-legacy.Tpo" -c -o libsqlite_la-legacy.lo `test -f 'legacy.c' || echo '$(srcdir)/'`legacy.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-legacy.Tpo" "$(DEPDIR)/libsqlite_la-legacy.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-legacy.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='legacy.c' object='libsqlite_la-legacy.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-legacy.lo `test -f 'legacy.c' || echo '$(srcdir)/'`legacy.c
+
+libsqlite_la-main.lo: main.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-main.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-main.Tpo" -c -o libsqlite_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-main.Tpo" "$(DEPDIR)/libsqlite_la-main.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-main.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='libsqlite_la-main.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+libsqlite_la-opcodes.lo: opcodes.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-opcodes.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-opcodes.Tpo" -c -o libsqlite_la-opcodes.lo `test -f 'opcodes.c' || echo '$(srcdir)/'`opcodes.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-opcodes.Tpo" "$(DEPDIR)/libsqlite_la-opcodes.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-opcodes.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='opcodes.c' object='libsqlite_la-opcodes.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-opcodes.lo `test -f 'opcodes.c' || echo '$(srcdir)/'`opcodes.c
+
+libsqlite_la-os_unix.lo: os_unix.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-os_unix.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-os_unix.Tpo" -c -o libsqlite_la-os_unix.lo `test -f 'os_unix.c' || echo '$(srcdir)/'`os_unix.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-os_unix.Tpo" "$(DEPDIR)/libsqlite_la-os_unix.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-os_unix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='os_unix.c' object='libsqlite_la-os_unix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-os_unix.lo `test -f 'os_unix.c' || echo '$(srcdir)/'`os_unix.c
+
+libsqlite_la-os_win.lo: os_win.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-os_win.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-os_win.Tpo" -c -o libsqlite_la-os_win.lo `test -f 'os_win.c' || echo '$(srcdir)/'`os_win.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-os_win.Tpo" "$(DEPDIR)/libsqlite_la-os_win.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-os_win.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='os_win.c' object='libsqlite_la-os_win.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-os_win.lo `test -f 'os_win.c' || echo '$(srcdir)/'`os_win.c
+
+libsqlite_la-pager.lo: pager.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-pager.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-pager.Tpo" -c -o libsqlite_la-pager.lo `test -f 'pager.c' || echo '$(srcdir)/'`pager.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-pager.Tpo" "$(DEPDIR)/libsqlite_la-pager.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-pager.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pager.c' object='libsqlite_la-pager.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-pager.lo `test -f 'pager.c' || echo '$(srcdir)/'`pager.c
+
+libsqlite_la-parse.lo: parse.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-parse.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-parse.Tpo" -c -o libsqlite_la-parse.lo `test -f 'parse.c' || echo '$(srcdir)/'`parse.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-parse.Tpo" "$(DEPDIR)/libsqlite_la-parse.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-parse.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='parse.c' object='libsqlite_la-parse.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-parse.lo `test -f 'parse.c' || echo '$(srcdir)/'`parse.c
+
+libsqlite_la-pragma.lo: pragma.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-pragma.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-pragma.Tpo" -c -o libsqlite_la-pragma.lo `test -f 'pragma.c' || echo '$(srcdir)/'`pragma.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-pragma.Tpo" "$(DEPDIR)/libsqlite_la-pragma.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-pragma.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pragma.c' object='libsqlite_la-pragma.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-pragma.lo `test -f 'pragma.c' || echo '$(srcdir)/'`pragma.c
+
+libsqlite_la-prepare.lo: prepare.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-prepare.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-prepare.Tpo" -c -o libsqlite_la-prepare.lo `test -f 'prepare.c' || echo '$(srcdir)/'`prepare.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-prepare.Tpo" "$(DEPDIR)/libsqlite_la-prepare.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-prepare.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='prepare.c' object='libsqlite_la-prepare.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-prepare.lo `test -f 'prepare.c' || echo '$(srcdir)/'`prepare.c
+
+libsqlite_la-printf.lo: printf.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-printf.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-printf.Tpo" -c -o libsqlite_la-printf.lo `test -f 'printf.c' || echo '$(srcdir)/'`printf.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-printf.Tpo" "$(DEPDIR)/libsqlite_la-printf.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-printf.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='printf.c' object='libsqlite_la-printf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-printf.lo `test -f 'printf.c' || echo '$(srcdir)/'`printf.c
+
+libsqlite_la-random.lo: random.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-random.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-random.Tpo" -c -o libsqlite_la-random.lo `test -f 'random.c' || echo '$(srcdir)/'`random.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-random.Tpo" "$(DEPDIR)/libsqlite_la-random.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-random.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='random.c' object='libsqlite_la-random.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-random.lo `test -f 'random.c' || echo '$(srcdir)/'`random.c
+
+libsqlite_la-select.lo: select.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-select.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-select.Tpo" -c -o libsqlite_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-select.Tpo" "$(DEPDIR)/libsqlite_la-select.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-select.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='select.c' object='libsqlite_la-select.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c
+
+libsqlite_la-table.lo: table.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-table.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-table.Tpo" -c -o libsqlite_la-table.lo `test -f 'table.c' || echo '$(srcdir)/'`table.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-table.Tpo" "$(DEPDIR)/libsqlite_la-table.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-table.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='table.c' object='libsqlite_la-table.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-table.lo `test -f 'table.c' || echo '$(srcdir)/'`table.c
+
+libsqlite_la-tokenize.lo: tokenize.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-tokenize.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-tokenize.Tpo" -c -o libsqlite_la-tokenize.lo `test -f 'tokenize.c' || echo '$(srcdir)/'`tokenize.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-tokenize.Tpo" "$(DEPDIR)/libsqlite_la-tokenize.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-tokenize.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tokenize.c' object='libsqlite_la-tokenize.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-tokenize.lo `test -f 'tokenize.c' || echo '$(srcdir)/'`tokenize.c
+
+libsqlite_la-trigger.lo: trigger.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-trigger.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-trigger.Tpo" -c -o libsqlite_la-trigger.lo `test -f 'trigger.c' || echo '$(srcdir)/'`trigger.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-trigger.Tpo" "$(DEPDIR)/libsqlite_la-trigger.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-trigger.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='trigger.c' object='libsqlite_la-trigger.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-trigger.lo `test -f 'trigger.c' || echo '$(srcdir)/'`trigger.c
+
+libsqlite_la-update.lo: update.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-update.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-update.Tpo" -c -o libsqlite_la-update.lo `test -f 'update.c' || echo '$(srcdir)/'`update.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-update.Tpo" "$(DEPDIR)/libsqlite_la-update.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-update.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='update.c' object='libsqlite_la-update.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-update.lo `test -f 'update.c' || echo '$(srcdir)/'`update.c
+
+libsqlite_la-utf.lo: utf.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-utf.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-utf.Tpo" -c -o libsqlite_la-utf.lo `test -f 'utf.c' || echo '$(srcdir)/'`utf.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-utf.Tpo" "$(DEPDIR)/libsqlite_la-utf.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-utf.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utf.c' object='libsqlite_la-utf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-utf.lo `test -f 'utf.c' || echo '$(srcdir)/'`utf.c
+
+libsqlite_la-util.lo: util.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-util.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-util.Tpo" -c -o libsqlite_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-util.Tpo" "$(DEPDIR)/libsqlite_la-util.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-util.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util.c' object='libsqlite_la-util.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c
+
+libsqlite_la-vacuum.lo: vacuum.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-vacuum.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-vacuum.Tpo" -c -o libsqlite_la-vacuum.lo `test -f 'vacuum.c' || echo '$(srcdir)/'`vacuum.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-vacuum.Tpo" "$(DEPDIR)/libsqlite_la-vacuum.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-vacuum.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vacuum.c' object='libsqlite_la-vacuum.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-vacuum.lo `test -f 'vacuum.c' || echo '$(srcdir)/'`vacuum.c
+
+libsqlite_la-vdbe.lo: vdbe.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-vdbe.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-vdbe.Tpo" -c -o libsqlite_la-vdbe.lo `test -f 'vdbe.c' || echo '$(srcdir)/'`vdbe.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-vdbe.Tpo" "$(DEPDIR)/libsqlite_la-vdbe.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-vdbe.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vdbe.c' object='libsqlite_la-vdbe.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-vdbe.lo `test -f 'vdbe.c' || echo '$(srcdir)/'`vdbe.c
+
+libsqlite_la-vdbeapi.lo: vdbeapi.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-vdbeapi.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-vdbeapi.Tpo" -c -o libsqlite_la-vdbeapi.lo `test -f 'vdbeapi.c' || echo '$(srcdir)/'`vdbeapi.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-vdbeapi.Tpo" "$(DEPDIR)/libsqlite_la-vdbeapi.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-vdbeapi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vdbeapi.c' object='libsqlite_la-vdbeapi.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-vdbeapi.lo `test -f 'vdbeapi.c' || echo '$(srcdir)/'`vdbeapi.c
+
+libsqlite_la-vdbeaux.lo: vdbeaux.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-vdbeaux.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-vdbeaux.Tpo" -c -o libsqlite_la-vdbeaux.lo `test -f 'vdbeaux.c' || echo '$(srcdir)/'`vdbeaux.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-vdbeaux.Tpo" "$(DEPDIR)/libsqlite_la-vdbeaux.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-vdbeaux.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vdbeaux.c' object='libsqlite_la-vdbeaux.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-vdbeaux.lo `test -f 'vdbeaux.c' || echo '$(srcdir)/'`vdbeaux.c
+
+libsqlite_la-vdbemem.lo: vdbemem.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-vdbemem.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-vdbemem.Tpo" -c -o libsqlite_la-vdbemem.lo `test -f 'vdbemem.c' || echo '$(srcdir)/'`vdbemem.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-vdbemem.Tpo" "$(DEPDIR)/libsqlite_la-vdbemem.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-vdbemem.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vdbemem.c' object='libsqlite_la-vdbemem.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-vdbemem.lo `test -f 'vdbemem.c' || echo '$(srcdir)/'`vdbemem.c
+
+libsqlite_la-where.lo: where.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -MT libsqlite_la-where.lo -MD -MP -MF "$(DEPDIR)/libsqlite_la-where.Tpo" -c -o libsqlite_la-where.lo `test -f 'where.c' || echo '$(srcdir)/'`where.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsqlite_la-where.Tpo" "$(DEPDIR)/libsqlite_la-where.Plo"; else rm -f "$(DEPDIR)/libsqlite_la-where.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='where.c' object='libsqlite_la-where.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsqlite_la_CFLAGS) $(CFLAGS) -c -o libsqlite_la-where.lo `test -f 'where.c' || echo '$(srcdir)/'`where.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+#>- mostlyclean-am
+#>+ 2
+clean-am: clean-bcheck clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+#>+ 2
+KDE_DIST=sqlite3.h vdbeInt.h btree.h parse.h os_win.h os.h os_unix.h sqliteInt.h vdbe.h opcodes.h pager.h keywordhash.h Makefile.in os_common.h hash.h Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sqlite/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/sqlite/Makefile
+ cd $(top_srcdir) && perl admin/am_edit src/sqlite/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) libsqlite_la_OBJECTS="$(libsqlite_la_final_OBJECTS)" all-am
+
+#>+ 3
+final-install:
+ $(MAKE) libsqlite_la_OBJECTS="$(libsqlite_la_final_OBJECTS)" install-am
+
+#>+ 3
+no-final:
+ $(MAKE) libsqlite_la_OBJECTS="$(libsqlite_la_nofinal_OBJECTS)" all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) libsqlite_la_OBJECTS="$(libsqlite_la_nofinal_OBJECTS)" install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/src/sqlite/alter.c b/src/sqlite/alter.c
new file mode 100644
index 0000000..8d852b8
--- /dev/null
+++ b/src/sqlite/alter.c
@@ -0,0 +1,553 @@
+/*
+** 2005 February 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that used to generate VDBE code
+** that implements the ALTER TABLE command.
+**
+** $Id: alter.c,v 1.1.1.1 2006/02/03 20:35:16 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include <ctype.h>
+
+/*
+** The code in this file only exists if we are not omitting the
+** ALTER TABLE logic from the build.
+*/
+#ifndef SQLITE_OMIT_ALTERTABLE
+
+
+/*
+** This function is used by SQL generated to implement the
+** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
+** CREATE INDEX command. The second is a table name. The table name in
+** the CREATE TABLE or CREATE INDEX statement is replaced with the second
+** argument and the result returned. Examples:
+**
+** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
+** -> 'CREATE TABLE def(a, b, c)'
+**
+** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
+** -> 'CREATE INDEX i ON def(a, b, c)'
+*/
+static void renameTableFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ unsigned char const *zSql = sqlite3_value_text(argv[0]);
+ unsigned char const *zTableName = sqlite3_value_text(argv[1]);
+
+ int token;
+ Token tname;
+ char const *zCsr = zSql;
+ int len = 0;
+ char *zRet;
+
+ /* The principle used to locate the table name in the CREATE TABLE
+ ** statement is that the table name is the first token that is immediatedly
+ ** followed by a left parenthesis - TK_LP.
+ */
+ if( zSql ){
+ do {
+ /* Store the token that zCsr points to in tname. */
+ tname.z = zCsr;
+ tname.n = len;
+
+ /* Advance zCsr to the next token. Store that token type in 'token',
+ ** and it's length in 'len' (to be used next iteration of this loop).
+ */
+ do {
+ zCsr += len;
+ len = sqlite3GetToken(zCsr, &token);
+ } while( token==TK_SPACE );
+ assert( len>0 );
+ } while( token!=TK_LP );
+
+ zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql,
+ zTableName, tname.z+tname.n);
+ sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
+ }
+}
+
+#ifndef SQLITE_OMIT_TRIGGER
+/* This function is used by SQL generated to implement the ALTER TABLE
+** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER
+** statement. The second is a table name. The table name in the CREATE
+** TRIGGER statement is replaced with the second argument and the result
+** returned. This is analagous to renameTableFunc() above, except for CREATE
+** TRIGGER, not CREATE INDEX and CREATE TABLE.
+*/
+static void renameTriggerFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ unsigned char const *zSql = sqlite3_value_text(argv[0]);
+ unsigned char const *zTableName = sqlite3_value_text(argv[1]);
+
+ int token;
+ Token tname;
+ int dist = 3;
+ char const *zCsr = zSql;
+ int len = 0;
+ char *zRet;
+
+ /* The principle used to locate the table name in the CREATE TRIGGER
+ ** statement is that the table name is the first token that is immediatedly
+ ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
+ ** of TK_WHEN, TK_BEGIN or TK_FOR.
+ */
+ if( zSql ){
+ do {
+ /* Store the token that zCsr points to in tname. */
+ tname.z = zCsr;
+ tname.n = len;
+
+ /* Advance zCsr to the next token. Store that token type in 'token',
+ ** and it's length in 'len' (to be used next iteration of this loop).
+ */
+ do {
+ zCsr += len;
+ len = sqlite3GetToken(zCsr, &token);
+ }while( token==TK_SPACE );
+ assert( len>0 );
+
+ /* Variable 'dist' stores the number of tokens read since the most
+ ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN
+ ** token is read and 'dist' equals 2, the condition stated above
+ ** to be met.
+ **
+ ** Note that ON cannot be a database, table or column name, so
+ ** there is no need to worry about syntax like
+ ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
+ */
+ dist++;
+ if( token==TK_DOT || token==TK_ON ){
+ dist = 0;
+ }
+ } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
+
+ /* Variable tname now contains the token that is the old table-name
+ ** in the CREATE TRIGGER statement.
+ */
+ zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql,
+ zTableName, tname.z+tname.n);
+ sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
+ }
+}
+#endif /* !SQLITE_OMIT_TRIGGER */
+
+/*
+** Register built-in functions used to help implement ALTER TABLE
+*/
+void sqlite3AlterFunctions(sqlite3 *db){
+ static const struct {
+ char *zName;
+ signed char nArg;
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
+ } aFuncs[] = {
+ { "sqlite_rename_table", 2, renameTableFunc},
+#ifndef SQLITE_OMIT_TRIGGER
+ { "sqlite_rename_trigger", 2, renameTriggerFunc},
+#endif
+ };
+ int i;
+
+ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
+ sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
+ SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
+ }
+}
+
+/*
+** Generate the text of a WHERE expression which can be used to select all
+** temporary triggers on table pTab from the sqlite_temp_master table. If
+** table pTab has no temporary triggers, or is itself stored in the
+** temporary database, NULL is returned.
+*/
+static char *whereTempTriggers(Parse *pParse, Table *pTab){
+ Trigger *pTrig;
+ char *zWhere = 0;
+ char *tmp = 0;
+ if( pTab->iDb!=1 ){
+ for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
+ if( pTrig->iDb==1 ){
+ if( !zWhere ){
+ zWhere = sqlite3MPrintf("name=%Q", pTrig->name);
+ }else{
+ tmp = zWhere;
+ zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name);
+ sqliteFree(tmp);
+ }
+ }
+ }
+ }
+ return zWhere;
+}
+
+/*
+** Generate code to drop and reload the internal representation of table
+** pTab from the database, including triggers and temporary triggers.
+** Argument zName is the name of the table in the database schema at
+** the time the generated code is executed. This can be different from
+** pTab->zName if this function is being called to code part of an
+** "ALTER TABLE RENAME TO" statement.
+*/
+static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
+ Vdbe *v;
+ char *zWhere;
+ int iDb;
+#ifndef SQLITE_OMIT_TRIGGER
+ Trigger *pTrig;
+#endif
+
+ v = sqlite3GetVdbe(pParse);
+ if( !v ) return;
+ iDb = pTab->iDb;
+
+#ifndef SQLITE_OMIT_TRIGGER
+ /* Drop any table triggers from the internal schema. */
+ for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
+ assert( pTrig->iDb==iDb || pTrig->iDb==1 );
+ sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0);
+ }
+#endif
+
+ /* Drop the table and index from the internal schema */
+ sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
+
+ /* Reload the table, index and permanent trigger schemas. */
+ zWhere = sqlite3MPrintf("tbl_name=%Q", zName);
+ if( !zWhere ) return;
+ sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
+
+#ifndef SQLITE_OMIT_TRIGGER
+ /* Now, if the table is not stored in the temp database, reload any temp
+ ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
+ */
+ if( (zWhere=whereTempTriggers(pParse, pTab)) ){
+ sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC);
+ }
+#endif
+}
+
+/*
+** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy"
+** command.
+*/
+void sqlite3AlterRenameTable(
+ Parse *pParse, /* Parser context. */
+ SrcList *pSrc, /* The table to rename. */
+ Token *pName /* The new table name. */
+){
+ int iDb; /* Database that contains the table */
+ char *zDb; /* Name of database iDb */
+ Table *pTab; /* Table being renamed */
+ char *zName = 0; /* NULL-terminated version of pName */
+ sqlite3 *db = pParse->db; /* Database connection */
+ Vdbe *v;
+#ifndef SQLITE_OMIT_TRIGGER
+ char *zWhere = 0; /* Where clause to locate temp triggers */
+#endif
+
+ assert( pSrc->nSrc==1 );
+
+ pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
+ if( !pTab ) goto exit_rename_table;
+ iDb = pTab->iDb;
+ zDb = db->aDb[iDb].zName;
+
+ /* Get a NULL terminated version of the new table name. */
+ zName = sqlite3NameFromToken(pName);
+ if( !zName ) goto exit_rename_table;
+
+ /* Check that a table or index named 'zName' does not already exist
+ ** in database iDb. If so, this is an error.
+ */
+ if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
+ sqlite3ErrorMsg(pParse,
+ "there is already another table or index with this name: %s", zName);
+ goto exit_rename_table;
+ }
+
+ /* Make sure it is not a system table being altered, or a reserved name
+ ** that the table is being renamed to.
+ */
+ if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){
+ sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
+ goto exit_rename_table;
+ }
+ if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ goto exit_rename_table;
+ }
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ /* Invoke the authorization callback. */
+ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
+ goto exit_rename_table;
+ }
+#endif
+
+ /* Begin a transaction and code the VerifyCookie for database iDb.
+ ** Then modify the schema cookie (since the ALTER TABLE modifies the
+ ** schema).
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ){
+ goto exit_rename_table;
+ }
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3ChangeCookie(db, v, iDb);
+
+ /* Modify the sqlite_master table to use the new table name. */
+ sqlite3NestedParse(pParse,
+ "UPDATE %Q.%s SET "
+#ifdef SQLITE_OMIT_TRIGGER
+ "sql = sqlite_rename_table(sql, %Q), "
+#else
+ "sql = CASE "
+ "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
+ "ELSE sqlite_rename_table(sql, %Q) END, "
+#endif
+ "tbl_name = %Q, "
+ "name = CASE "
+ "WHEN type='table' THEN %Q "
+ "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
+ "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) "
+ "ELSE name END "
+ "WHERE tbl_name=%Q AND "
+ "(type='table' OR type='index' OR type='trigger');",
+ zDb, SCHEMA_TABLE(iDb), zName, zName, zName,
+#ifndef SQLITE_OMIT_TRIGGER
+ zName,
+#endif
+ zName, strlen(pTab->zName), pTab->zName
+ );
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ /* If the sqlite_sequence table exists in this database, then update
+ ** it with the new table name.
+ */
+ if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
+ sqlite3NestedParse(pParse,
+ "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",
+ zDb, zName, pTab->zName);
+ }
+#endif
+
+#ifndef SQLITE_OMIT_TRIGGER
+ /* If there are TEMP triggers on this table, modify the sqlite_temp_master
+ ** table. Don't do this if the table being ALTERed is itself located in
+ ** the temp database.
+ */
+ if( (zWhere=whereTempTriggers(pParse, pTab)) ){
+ sqlite3NestedParse(pParse,
+ "UPDATE sqlite_temp_master SET "
+ "sql = sqlite_rename_trigger(sql, %Q), "
+ "tbl_name = %Q "
+ "WHERE %s;", zName, zName, zWhere);
+ sqliteFree(zWhere);
+ }
+#endif
+
+ /* Drop and reload the internal table schema. */
+ reloadTableSchema(pParse, pTab, zName);
+
+exit_rename_table:
+ sqlite3SrcListDelete(pSrc);
+ sqliteFree(zName);
+}
+
+
+/*
+** This function is called after an "ALTER TABLE ... ADD" statement
+** has been parsed. Argument pColDef contains the text of the new
+** column definition.
+**
+** The Table structure pParse->pNewTable was extended to include
+** the new column during parsing.
+*/
+void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
+ Table *pNew; /* Copy of pParse->pNewTable */
+ Table *pTab; /* Table being altered */
+ int iDb; /* Database number */
+ const char *zDb; /* Database name */
+ const char *zTab; /* Table name */
+ char *zCol; /* Null-terminated column definition */
+ Column *pCol; /* The new column */
+ Expr *pDflt; /* Default value for the new column */
+ Vdbe *v;
+
+ if( pParse->nErr ) return;
+ pNew = pParse->pNewTable;
+ assert( pNew );
+
+ iDb = pNew->iDb;
+ zDb = pParse->db->aDb[iDb].zName;
+ zTab = pNew->zName;
+ pCol = &pNew->aCol[pNew->nCol-1];
+ pDflt = pCol->pDflt;
+ pTab = sqlite3FindTable(pParse->db, zTab, zDb);
+ assert( pTab );
+
+ /* If the default value for the new column was specified with a
+ ** literal NULL, then set pDflt to 0. This simplifies checking
+ ** for an SQL NULL default below.
+ */
+ if( pDflt && pDflt->op==TK_NULL ){
+ pDflt = 0;
+ }
+
+ /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
+ ** If there is a NOT NULL constraint, then the default value for the
+ ** column must not be NULL.
+ */
+ if( pCol->isPrimKey ){
+ sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
+ return;
+ }
+ if( pNew->pIndex ){
+ sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
+ return;
+ }
+ if( pCol->notNull && !pDflt ){
+ sqlite3ErrorMsg(pParse,
+ "Cannot add a NOT NULL column with default value NULL");
+ return;
+ }
+
+ /* Ensure the default expression is something that sqlite3ValueFromExpr()
+ ** can handle (i.e. not CURRENT_TIME etc.)
+ */
+ if( pDflt ){
+ sqlite3_value *pVal;
+ if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
+ /* malloc() has failed */
+ return;
+ }
+ if( !pVal ){
+ sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
+ return;
+ }
+ sqlite3ValueFree(pVal);
+ }
+
+ /* Modify the CREATE TABLE statement. */
+ zCol = sqliteStrNDup(pColDef->z, pColDef->n);
+ if( zCol ){
+ char *zEnd = &zCol[pColDef->n-1];
+ while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
+ *zEnd-- = '\0';
+ }
+ sqlite3NestedParse(pParse,
+ "UPDATE %Q.%s SET "
+ "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) "
+ "WHERE type = 'table' AND name = %Q",
+ zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
+ zTab
+ );
+ sqliteFree(zCol);
+ }
+
+ /* If the default value of the new column is NULL, then set the file
+ ** format to 2. If the default value of the new column is not NULL,
+ ** the file format becomes 3.
+ */
+ if( (v=sqlite3GetVdbe(pParse)) ){
+ int f = (pDflt?3:2);
+
+ /* Only set the file format to $f if it is currently less than $f. */
+ sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
+ sqlite3VdbeAddOp(v, OP_Integer, f, 0);
+ sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeAddOp(v, OP_Integer, f, 0);
+ sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
+ }
+
+ /* Reload the schema of the modified table. */
+ reloadTableSchema(pParse, pTab, pTab->zName);
+}
+
+
+/*
+** This function is called by the parser after the table-name in
+** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument
+** pSrc is the full-name of the table being altered.
+**
+** This routine makes a (partial) copy of the Table structure
+** for the table being altered and sets Parse.pNewTable to point
+** to it. Routines called by the parser as the column definition
+** is parsed (i.e. sqlite3AddColumn()) add the new Column data to
+** the copy. The copy of the Table structure is deleted by tokenize.c
+** after parsing is finished.
+**
+** Routine sqlite3AlterFinishAddColumn() will be called to complete
+** coding the "ALTER TABLE ... ADD" statement.
+*/
+void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
+ Table *pNew;
+ Table *pTab;
+ Vdbe *v;
+ int iDb;
+ int i;
+ int nAlloc;
+
+ /* Look up the table being altered. */
+ assert( !pParse->pNewTable );
+ pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
+ if( !pTab ) goto exit_begin_add_column;
+
+ /* Make sure this is not an attempt to ALTER a view. */
+ if( pTab->pSelect ){
+ sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
+ goto exit_begin_add_column;
+ }
+
+ assert( pTab->addColOffset>0 );
+ iDb = pTab->iDb;
+
+ /* Put a copy of the Table struct in Parse.pNewTable for the
+ ** sqlite3AddColumn() function and friends to modify.
+ */
+ pNew = (Table *)sqliteMalloc(sizeof(Table));
+ if( !pNew ) goto exit_begin_add_column;
+ pParse->pNewTable = pNew;
+ pNew->nCol = pTab->nCol;
+ assert( pNew->nCol>0 );
+ nAlloc = (((pNew->nCol-1)/8)*8)+8;
+ assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
+ pNew->aCol = (Column *)sqliteMalloc(sizeof(Column)*nAlloc);
+ pNew->zName = sqliteStrDup(pTab->zName);
+ if( !pNew->aCol || !pNew->zName ){
+ goto exit_begin_add_column;
+ }
+ memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
+ for(i=0; i<pNew->nCol; i++){
+ Column *pCol = &pNew->aCol[i];
+ pCol->zName = sqliteStrDup(pCol->zName);
+ pCol->zType = 0;
+ pCol->pDflt = 0;
+ }
+ pNew->iDb = iDb;
+ pNew->addColOffset = pTab->addColOffset;
+ pNew->nRef = 1;
+
+ /* Begin a transaction and increment the schema cookie. */
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ v = sqlite3GetVdbe(pParse);
+ if( !v ) goto exit_begin_add_column;
+ sqlite3ChangeCookie(pParse->db, v, iDb);
+
+exit_begin_add_column:
+ sqlite3SrcListDelete(pSrc);
+ return;
+}
+#endif /* SQLITE_ALTER_TABLE */
diff --git a/src/sqlite/attach.c b/src/sqlite/attach.c
new file mode 100644
index 0000000..c8ce123
--- /dev/null
+++ b/src/sqlite/attach.c
@@ -0,0 +1,352 @@
+/*
+** 2003 April 6
+**
+** 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 used to implement the ATTACH and DETACH commands.
+**
+** $Id: attach.c,v 1.1.1.1 2006/02/03 20:35:10 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** This routine is called by the parser to process an ATTACH statement:
+**
+** ATTACH DATABASE filename AS dbname
+**
+** The pFilename and pDbname arguments are the tokens that define the
+** filename and dbname in the ATTACH statement.
+*/
+void sqlite3Attach(
+ Parse *pParse, /* The parser context */
+ Token *pFilename, /* Name of database file */
+ Token *pDbname, /* Name of the database to use internally */
+ int keyType, /* 0: no key. 1: TEXT, 2: BLOB */
+ Token *pKey /* Text of the key for keytype 1 and 2 */
+){
+ Db *aNew;
+ int rc, i;
+ char *zFile = 0;
+ char *zName = 0;
+ sqlite3 *db;
+ Vdbe *v;
+
+ v = sqlite3GetVdbe(pParse);
+ if( !v ) return;
+ sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
+ if( pParse->explain ) return;
+ db = pParse->db;
+ if( db->nDb>=MAX_ATTACHED+2 ){
+ sqlite3ErrorMsg(pParse, "too many attached databases - max %d",
+ MAX_ATTACHED);
+ pParse->rc = SQLITE_ERROR;
+ return;
+ }
+
+ if( !db->autoCommit ){
+ sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction");
+ pParse->rc = SQLITE_ERROR;
+ return;
+ }
+
+ zFile = sqlite3NameFromToken(pFilename);
+ if( zFile==0 ){
+ goto attach_end;
+ }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
+ goto attach_end;
+ }
+#endif /* SQLITE_OMIT_AUTHORIZATION */
+
+ zName = sqlite3NameFromToken(pDbname);
+ if( zName==0 ){
+ goto attach_end;
+ }
+ for(i=0; i<db->nDb; i++){
+ char *z = db->aDb[i].zName;
+ if( z && sqlite3StrICmp(z, zName)==0 ){
+ sqlite3ErrorMsg(pParse, "database %s is already in use", zName);
+ pParse->rc = SQLITE_ERROR;
+ goto attach_end;
+ }
+ }
+
+ if( db->aDb==db->aDbStatic ){
+ aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
+ if( aNew==0 ){
+ goto attach_end;
+ }
+ memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
+ }else{
+ aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
+ if( aNew==0 ){
+ goto attach_end;
+ }
+ }
+ db->aDb = aNew;
+ aNew = &db->aDb[db->nDb++];
+ memset(aNew, 0, sizeof(*aNew));
+ sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
+ sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
+ sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
+ sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
+ aNew->zName = zName;
+ zName = 0;
+ aNew->safety_level = 3;
+ rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
+ if( rc ){
+ sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
+ }
+#if SQLITE_HAS_CODEC
+ {
+ extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
+ char *zKey;
+ int nKey;
+ if( keyType==0 ){
+ /* No key specified. Use the key from the main database */
+ extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+ }else if( keyType==1 ){
+ /* Key specified as text */
+ zKey = sqlite3NameFromToken(pKey);
+ nKey = strlen(zKey);
+ }else{
+ /* Key specified as a BLOB */
+ char *zTemp;
+ assert( keyType==2 );
+ pKey->z++;
+ pKey->n--;
+ zTemp = sqlite3NameFromToken(pKey);
+ zKey = sqlite3HexToBlob(zTemp);
+ sqliteFree(zTemp);
+ }
+ sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+ if( keyType ){
+ sqliteFree(zKey);
+ }
+ }
+#endif
+ db->flags &= ~SQLITE_Initialized;
+ if( pParse->nErr==0 && rc==SQLITE_OK ){
+ rc = sqlite3ReadSchema(pParse);
+ }
+ if( rc ){
+ int i = db->nDb - 1;
+ assert( i>=2 );
+ if( db->aDb[i].pBt ){
+ sqlite3BtreeClose(db->aDb[i].pBt);
+ db->aDb[i].pBt = 0;
+ }
+ sqlite3ResetInternalSchema(db, 0);
+ if( 0==pParse->nErr ){
+ pParse->nErr++;
+ pParse->rc = SQLITE_ERROR;
+ }
+ }
+
+attach_end:
+ sqliteFree(zFile);
+ sqliteFree(zName);
+}
+
+/*
+** This routine is called by the parser to process a DETACH statement:
+**
+** DETACH DATABASE dbname
+**
+** The pDbname argument is the name of the database in the DETACH statement.
+*/
+void sqlite3Detach(Parse *pParse, Token *pDbname){
+ int i;
+ sqlite3 *db;
+ Vdbe *v;
+ Db *pDb = 0;
+ char *zName;
+
+ v = sqlite3GetVdbe(pParse);
+ if( !v ) return;
+ sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
+ if( pParse->explain ) return;
+ db = pParse->db;
+ zName = sqlite3NameFromToken(pDbname);
+ if( zName==0 ) return;
+ for(i=0; i<db->nDb; i++){
+ pDb = &db->aDb[i];
+ if( pDb->pBt==0 ) continue;
+ if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
+ }
+ if( i>=db->nDb ){
+ sqlite3ErrorMsg(pParse, "no such database: %z", zName);
+ return;
+ }
+ if( i<2 ){
+ sqlite3ErrorMsg(pParse, "cannot detach database %z", zName);
+ return;
+ }
+ sqliteFree(zName);
+ if( !db->autoCommit ){
+ sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction");
+ pParse->rc = SQLITE_ERROR;
+ return;
+ }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
+ return;
+ }
+#endif /* SQLITE_OMIT_AUTHORIZATION */
+ sqlite3BtreeClose(pDb->pBt);
+ pDb->pBt = 0;
+ sqlite3ResetInternalSchema(db, 0);
+}
+
+/*
+** Initialize a DbFixer structure. This routine must be called prior
+** to passing the structure to one of the sqliteFixAAAA() routines below.
+**
+** The return value indicates whether or not fixation is required. TRUE
+** means we do need to fix the database references, FALSE means we do not.
+*/
+int sqlite3FixInit(
+ DbFixer *pFix, /* The fixer to be initialized */
+ Parse *pParse, /* Error messages will be written here */
+ int iDb, /* This is the database that must be used */
+ const char *zType, /* "view", "trigger", or "index" */
+ const Token *pName /* Name of the view, trigger, or index */
+){
+ sqlite3 *db;
+
+ if( iDb<0 || iDb==1 ) return 0;
+ db = pParse->db;
+ assert( db->nDb>iDb );
+ pFix->pParse = pParse;
+ pFix->zDb = db->aDb[iDb].zName;
+ pFix->zType = zType;
+ pFix->pName = pName;
+ return 1;
+}
+
+/*
+** The following set of routines walk through the parse tree and assign
+** a specific database to all table references where the database name
+** was left unspecified in the original SQL statement. The pFix structure
+** must have been initialized by a prior call to sqlite3FixInit().
+**
+** These routines are used to make sure that an index, trigger, or
+** view in one database does not refer to objects in a different database.
+** (Exception: indices, triggers, and views in the TEMP database are
+** allowed to refer to anything.) If a reference is explicitly made
+** to an object in a different database, an error message is added to
+** pParse->zErrMsg and these routines return non-zero. If everything
+** checks out, these routines return 0.
+*/
+int sqlite3FixSrcList(
+ DbFixer *pFix, /* Context of the fixation */
+ SrcList *pList /* The Source list to check and modify */
+){
+ int i;
+ const char *zDb;
+ struct SrcList_item *pItem;
+
+ if( pList==0 ) return 0;
+ zDb = pFix->zDb;
+ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
+ if( pItem->zDatabase==0 ){
+ pItem->zDatabase = sqliteStrDup(zDb);
+ }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
+ sqlite3ErrorMsg(pFix->pParse,
+ "%s %T cannot reference objects in database %s",
+ pFix->zType, pFix->pName, pItem->zDatabase);
+ return 1;
+ }
+#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
+ if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
+ if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
+#endif
+ }
+ return 0;
+}
+#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
+int sqlite3FixSelect(
+ DbFixer *pFix, /* Context of the fixation */
+ Select *pSelect /* The SELECT statement to be fixed to one database */
+){
+ while( pSelect ){
+ if( sqlite3FixExprList(pFix, pSelect->pEList) ){
+ return 1;
+ }
+ if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
+ return 1;
+ }
+ pSelect = pSelect->pPrior;
+ }
+ return 0;
+}
+int sqlite3FixExpr(
+ DbFixer *pFix, /* Context of the fixation */
+ Expr *pExpr /* The expression to be fixed to one database */
+){
+ while( pExpr ){
+ if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
+ return 1;
+ }
+ if( sqlite3FixExprList(pFix, pExpr->pList) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pExpr->pRight) ){
+ return 1;
+ }
+ pExpr = pExpr->pLeft;
+ }
+ return 0;
+}
+int sqlite3FixExprList(
+ DbFixer *pFix, /* Context of the fixation */
+ ExprList *pList /* The expression to be fixed to one database */
+){
+ int i;
+ struct ExprList_item *pItem;
+ if( pList==0 ) return 0;
+ for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
+ if( sqlite3FixExpr(pFix, pItem->pExpr) ){
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif
+
+#ifndef SQLITE_OMIT_TRIGGER
+int sqlite3FixTriggerStep(
+ DbFixer *pFix, /* Context of the fixation */
+ TriggerStep *pStep /* The trigger step be fixed to one database */
+){
+ while( pStep ){
+ if( sqlite3FixSelect(pFix, pStep->pSelect) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pStep->pWhere) ){
+ return 1;
+ }
+ if( sqlite3FixExprList(pFix, pStep->pExprList) ){
+ return 1;
+ }
+ pStep = pStep->pNext;
+ }
+ return 0;
+}
+#endif
diff --git a/src/sqlite/auth.c b/src/sqlite/auth.c
new file mode 100644
index 0000000..0d7e612
--- /dev/null
+++ b/src/sqlite/auth.c
@@ -0,0 +1,224 @@
+/*
+** 2003 January 11
+**
+** 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 used to implement the sqlite3_set_authorizer()
+** API. This facility is an optional feature of the library. Embedded
+** systems that do not need this facility may omit it by recompiling
+** the library with -DSQLITE_OMIT_AUTHORIZATION=1
+**
+** $Id: auth.c,v 1.1.1.1 2006/02/03 20:35:11 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** All of the code in this file may be omitted by defining a single
+** macro.
+*/
+#ifndef SQLITE_OMIT_AUTHORIZATION
+
+/*
+** Set or clear the access authorization function.
+**
+** The access authorization function is be called during the compilation
+** phase to verify that the user has read and/or write access permission on
+** various fields of the database. The first argument to the auth function
+** is a copy of the 3rd argument to this routine. The second argument
+** to the auth function is one of these constants:
+**
+** SQLITE_CREATE_INDEX
+** SQLITE_CREATE_TABLE
+** SQLITE_CREATE_TEMP_INDEX
+** SQLITE_CREATE_TEMP_TABLE
+** SQLITE_CREATE_TEMP_TRIGGER
+** SQLITE_CREATE_TEMP_VIEW
+** SQLITE_CREATE_TRIGGER
+** SQLITE_CREATE_VIEW
+** SQLITE_DELETE
+** SQLITE_DROP_INDEX
+** SQLITE_DROP_TABLE
+** SQLITE_DROP_TEMP_INDEX
+** SQLITE_DROP_TEMP_TABLE
+** SQLITE_DROP_TEMP_TRIGGER
+** SQLITE_DROP_TEMP_VIEW
+** SQLITE_DROP_TRIGGER
+** SQLITE_DROP_VIEW
+** SQLITE_INSERT
+** SQLITE_PRAGMA
+** SQLITE_READ
+** SQLITE_SELECT
+** SQLITE_TRANSACTION
+** SQLITE_UPDATE
+**
+** The third and fourth arguments to the auth function are the name of
+** the table and the column that are being accessed. The auth function
+** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
+** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
+** means that the SQL statement will never-run - the sqlite3_exec() call
+** will return with an error. SQLITE_IGNORE means that the SQL statement
+** should run but attempts to read the specified column will return NULL
+** and attempts to write the column will be ignored.
+**
+** Setting the auth function to NULL disables this hook. The default
+** setting of the auth function is NULL.
+*/
+int sqlite3_set_authorizer(
+ sqlite3 *db,
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+ void *pArg
+){
+ db->xAuth = xAuth;
+ db->pAuthArg = pArg;
+ sqlite3ExpirePreparedStatements(db);
+ return SQLITE_OK;
+}
+
+/*
+** Write an error message into pParse->zErrMsg that explains that the
+** user-supplied authorization function returned an illegal value.
+*/
+static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
+ sqlite3ErrorMsg(pParse, "illegal return value (%d) from the "
+ "authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
+ "or SQLITE_DENY", rc);
+ pParse->rc = SQLITE_ERROR;
+}
+
+/*
+** The pExpr should be a TK_COLUMN expression. The table referred to
+** is in pTabList or else it is the NEW or OLD table of a trigger.
+** Check to see if it is OK to read this particular column.
+**
+** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
+** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
+** then generate an error.
+*/
+void sqlite3AuthRead(
+ Parse *pParse, /* The parser context */
+ Expr *pExpr, /* The expression to check authorization on */
+ SrcList *pTabList /* All table that pExpr might refer to */
+){
+ sqlite3 *db = pParse->db;
+ int rc;
+ Table *pTab; /* The table being read */
+ const char *zCol; /* Name of the column of the table */
+ int iSrc; /* Index in pTabList->a[] of table being read */
+ const char *zDBase; /* Name of database being accessed */
+ TriggerStack *pStack; /* The stack of current triggers */
+
+ if( db->xAuth==0 ) return;
+ assert( pExpr->op==TK_COLUMN );
+ for(iSrc=0; pTabList && iSrc<pTabList->nSrc; iSrc++){
+ if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
+ }
+ if( iSrc>=0 && pTabList && iSrc<pTabList->nSrc ){
+ pTab = pTabList->a[iSrc].pTab;
+ }else if( (pStack = pParse->trigStack)!=0 ){
+ /* This must be an attempt to read the NEW or OLD pseudo-tables
+ ** of a trigger.
+ */
+ assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
+ pTab = pStack->pTab;
+ }else{
+ return;
+ }
+ if( pTab==0 ) return;
+ if( pExpr->iColumn>=0 ){
+ assert( pExpr->iColumn<pTab->nCol );
+ zCol = pTab->aCol[pExpr->iColumn].zName;
+ }else if( pTab->iPKey>=0 ){
+ assert( pTab->iPKey<pTab->nCol );
+ zCol = pTab->aCol[pTab->iPKey].zName;
+ }else{
+ zCol = "ROWID";
+ }
+ assert( pExpr->iDb<db->nDb );
+ zDBase = db->aDb[pExpr->iDb].zName;
+ rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase,
+ pParse->zAuthContext);
+ if( rc==SQLITE_IGNORE ){
+ pExpr->op = TK_NULL;
+ }else if( rc==SQLITE_DENY ){
+ if( db->nDb>2 || pExpr->iDb!=0 ){
+ sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",
+ zDBase, pTab->zName, zCol);
+ }else{
+ sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol);
+ }
+ pParse->rc = SQLITE_AUTH;
+ }else if( rc!=SQLITE_OK ){
+ sqliteAuthBadReturnCode(pParse, rc);
+ }
+}
+
+/*
+** Do an authorization check using the code and arguments given. Return
+** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
+** is returned, then the error count and error message in pParse are
+** modified appropriately.
+*/
+int sqlite3AuthCheck(
+ Parse *pParse,
+ int code,
+ const char *zArg1,
+ const char *zArg2,
+ const char *zArg3
+){
+ sqlite3 *db = pParse->db;
+ int rc;
+
+ /* Don't do any authorization checks if the database is initialising. */
+ if( db->init.busy ){
+ return SQLITE_OK;
+ }
+
+ if( db->xAuth==0 ){
+ return SQLITE_OK;
+ }
+ rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
+ if( rc==SQLITE_DENY ){
+ sqlite3ErrorMsg(pParse, "not authorized");
+ pParse->rc = SQLITE_AUTH;
+ }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
+ rc = SQLITE_DENY;
+ sqliteAuthBadReturnCode(pParse, rc);
+ }
+ return rc;
+}
+
+/*
+** Push an authorization context. After this routine is called, the
+** zArg3 argument to authorization callbacks will be zContext until
+** popped. Or if pParse==0, this routine is a no-op.
+*/
+void sqlite3AuthContextPush(
+ Parse *pParse,
+ AuthContext *pContext,
+ const char *zContext
+){
+ pContext->pParse = pParse;
+ if( pParse ){
+ pContext->zAuthContext = pParse->zAuthContext;
+ pParse->zAuthContext = zContext;
+ }
+}
+
+/*
+** Pop an authorization context that was previously pushed
+** by sqlite3AuthContextPush
+*/
+void sqlite3AuthContextPop(AuthContext *pContext){
+ if( pContext->pParse ){
+ pContext->pParse->zAuthContext = pContext->zAuthContext;
+ pContext->pParse = 0;
+ }
+}
+
+#endif /* SQLITE_OMIT_AUTHORIZATION */
diff --git a/src/sqlite/btree.c b/src/sqlite/btree.c
new file mode 100644
index 0000000..e4157f5
--- /dev/null
+++ b/src/sqlite/btree.c
@@ -0,0 +1,5812 @@
+/*
+** 2004 April 6
+**
+** 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.
+**
+*************************************************************************
+** $Id: btree.c,v 1.1.1.1 2006/02/03 20:35:21 hoganrobert Exp $
+**
+** This file implements a external (disk-based) database using BTrees.
+** For a detailed discussion of BTrees, refer to
+**
+** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
+** "Sorting And Searching", pages 473-480. Addison-Wesley
+** Publishing Company, Reading, Massachusetts.
+**
+** The basic idea is that each page of the file contains N database
+** entries and N+1 pointers to subpages.
+**
+** ----------------------------------------------------------------
+** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N) | Ptr(N+1) |
+** ----------------------------------------------------------------
+**
+** All of the keys on the page that Ptr(0) points to have values less
+** than Key(0). All of the keys on page Ptr(1) and its subpages have
+** values greater than Key(0) and less than Key(1). All of the keys
+** on Ptr(N+1) and its subpages have values greater than Key(N). And
+** so forth.
+**
+** Finding a particular key requires reading O(log(M)) pages from the
+** disk where M is the number of entries in the tree.
+**
+** In this implementation, a single file can hold one or more separate
+** BTrees. Each BTree is identified by the index of its root page. The
+** key and data for any entry are combined to form the "payload". A
+** fixed amount of payload can be carried directly on the database
+** page. If the payload is larger than the preset amount then surplus
+** bytes are stored on overflow pages. The payload for an entry
+** and the preceding pointer are combined to form a "Cell". Each
+** page has a small header which contains the Ptr(N+1) pointer and other
+** information such as the size of key and data.
+**
+** FORMAT DETAILS
+**
+** The file is divided into pages. The first page is called page 1,
+** the second is page 2, and so forth. A page number of zero indicates
+** "no such page". The page size can be anything between 512 and 65536.
+** Each page can be either a btree page, a freelist page or an overflow
+** page.
+**
+** The first page is always a btree page. The first 100 bytes of the first
+** page contain a special header (the "file header") that describes the file.
+** The format of the file header is as follows:
+**
+** OFFSET SIZE DESCRIPTION
+** 0 16 Header string: "SQLite format 3\000"
+** 16 2 Page size in bytes.
+** 18 1 File format write version
+** 19 1 File format read version
+** 20 1 Bytes of unused space at the end of each page
+** 21 1 Max embedded payload fraction
+** 22 1 Min embedded payload fraction
+** 23 1 Min leaf payload fraction
+** 24 4 File change counter
+** 28 4 Reserved for future use
+** 32 4 First freelist page
+** 36 4 Number of freelist pages in the file
+** 40 60 15 4-byte meta values passed to higher layers
+**
+** All of the integer values are big-endian (most significant byte first).
+**
+** The file change counter is incremented when the database is changed more
+** than once within the same second. This counter, together with the
+** modification time of the file, allows other processes to know
+** when the file has changed and thus when they need to flush their
+** cache.
+**
+** The max embedded payload fraction is the amount of the total usable
+** space in a page that can be consumed by a single cell for standard
+** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default
+** is to limit the maximum cell size so that at least 4 cells will fit
+** on one page. Thus the default max embedded payload fraction is 64.
+**
+** If the payload for a cell is larger than the max payload, then extra
+** payload is spilled to overflow pages. Once an overflow page is allocated,
+** as many bytes as possible are moved into the overflow pages without letting
+** the cell size drop below the min embedded payload fraction.
+**
+** The min leaf payload fraction is like the min embedded payload fraction
+** except that it applies to leaf nodes in a LEAFDATA tree. The maximum
+** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
+** not specified in the header.
+**
+** Each btree pages is divided into three sections: The header, the
+** cell pointer array, and the cell area area. Page 1 also has a 100-byte
+** file header that occurs before the page header.
+**
+** |----------------|
+** | file header | 100 bytes. Page 1 only.
+** |----------------|
+** | page header | 8 bytes for leaves. 12 bytes for interior nodes
+** |----------------|
+** | cell pointer | | 2 bytes per cell. Sorted order.
+** | array | | Grows downward
+** | | v
+** |----------------|
+** | unallocated |
+** | space |
+** |----------------| ^ Grows upwards
+** | cell content | | Arbitrary order interspersed with freeblocks.
+** | area | | and free space fragments.
+** |----------------|
+**
+** The page headers looks like this:
+**
+** OFFSET SIZE DESCRIPTION
+** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
+** 1 2 byte offset to the first freeblock
+** 3 2 number of cells on this page
+** 5 2 first byte of the cell content area
+** 7 1 number of fragmented free bytes
+** 8 4 Right child (the Ptr(N+1) value). Omitted on leaves.
+**
+** The flags define the format of this btree page. The leaf flag means that
+** this page has no children. The zerodata flag means that this page carries
+** only keys and no data. The intkey flag means that the key is a integer
+** which is stored in the key size entry of the cell header rather than in
+** the payload area.
+**
+** The cell pointer array begins on the first byte after the page header.
+** The cell pointer array contains zero or more 2-byte numbers which are
+** offsets from the beginning of the page to the cell content in the cell
+** content area. The cell pointers occur in sorted order. The system strives
+** to keep free space after the last cell pointer so that new cells can
+** be easily added without having to defragment the page.
+**
+** Cell content is stored at the very end of the page and grows toward the
+** beginning of the page.
+**
+** Unused space within the cell content area is collected into a linked list of
+** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset
+** to the first freeblock is given in the header. Freeblocks occur in
+** increasing order. Because a freeblock must be at least 4 bytes in size,
+** any group of 3 or fewer unused bytes in the cell content area cannot
+** exist on the freeblock chain. A group of 3 or fewer free bytes is called
+** a fragment. The total number of bytes in all fragments is recorded.
+** in the page header at offset 7.
+**
+** SIZE DESCRIPTION
+** 2 Byte offset of the next freeblock
+** 2 Bytes in this freeblock
+**
+** Cells are of variable length. Cells are stored in the cell content area at
+** the end of the page. Pointers to the cells are in the cell pointer array
+** that immediately follows the page header. Cells is not necessarily
+** contiguous or in order, but cell pointers are contiguous and in order.
+**
+** Cell content makes use of variable length integers. A variable
+** length integer is 1 to 9 bytes where the lower 7 bits of each
+** byte are used. The integer consists of all bytes that have bit 8 set and
+** the first byte with bit 8 clear. The most significant byte of the integer
+** appears first. A variable-length integer may not be more than 9 bytes long.
+** As a special case, all 8 bytes of the 9th byte are used as data. This
+** allows a 64-bit integer to be encoded in 9 bytes.
+**
+** 0x00 becomes 0x00000000
+** 0x7f becomes 0x0000007f
+** 0x81 0x00 becomes 0x00000080
+** 0x82 0x00 becomes 0x00000100
+** 0x80 0x7f becomes 0x0000007f
+** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
+** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
+**
+** Variable length integers are used for rowids and to hold the number of
+** bytes of key and data in a btree cell.
+**
+** The content of a cell looks like this:
+**
+** SIZE DESCRIPTION
+** 4 Page number of the left child. Omitted if leaf flag is set.
+** var Number of bytes of data. Omitted if the zerodata flag is set.
+** var Number of bytes of key. Or the key itself if intkey flag is set.
+** * Payload
+** 4 First page of the overflow chain. Omitted if no overflow
+**
+** Overflow pages form a linked list. Each page except the last is completely
+** filled with data (pagesize - 4 bytes). The last page can have as little
+** as 1 byte of data.
+**
+** SIZE DESCRIPTION
+** 4 Page number of next overflow page
+** * Data
+**
+** Freelist pages come in two subtypes: trunk pages and leaf pages. The
+** file header points to first in a linked list of trunk page. Each trunk
+** page points to multiple leaf pages. The content of a leaf page is
+** unspecified. A trunk page looks like this:
+**
+** SIZE DESCRIPTION
+** 4 Page number of next trunk page
+** 4 Number of leaf pointers on this page
+** * zero or more pages numbers of leaves
+*/
+#include "sqliteInt.h"
+#include "pager.h"
+#include "btree.h"
+#include "os.h"
+#include <assert.h>
+
+/* Round up a number to the next larger multiple of 8. This is used
+** to force 8-byte alignment on 64-bit architectures.
+*/
+#define ROUND8(x) ((x+7)&~7)
+
+
+/* The following value is the maximum cell size assuming a maximum page
+** size give above.
+*/
+#define MX_CELL_SIZE(pBt) (pBt->pageSize-8)
+
+/* The maximum number of cells on a single page of the database. This
+** assumes a minimum cell size of 3 bytes. Such small cells will be
+** exceedingly rare, but they are possible.
+*/
+#define MX_CELL(pBt) ((pBt->pageSize-8)/3)
+
+/* Forward declarations */
+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";
+
+/*
+** Page type flags. An ORed combination of these flags appear as the
+** first byte of every BTree page.
+*/
+#define PTF_INTKEY 0x01
+#define PTF_ZERODATA 0x02
+#define PTF_LEAFDATA 0x04
+#define PTF_LEAF 0x08
+
+/*
+** As each page of the file is loaded into memory, an instance of the following
+** structure is appended and initialized to zero. This structure stores
+** information about the page that is decoded from the raw file page.
+**
+** The pParent field points back to the parent page. This allows us to
+** walk up the BTree from any leaf to the root. Care must be taken to
+** unref() the parent page pointer when this page is no longer referenced.
+** The pageDestructor() routine handles that chore.
+*/
+struct MemPage {
+ u8 isInit; /* True if previously initialized. MUST BE FIRST! */
+ u8 idxShift; /* True if Cell indices have changed */
+ u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
+ u8 intKey; /* True if intkey flag is set */
+ u8 leaf; /* True if leaf flag is set */
+ u8 zeroData; /* True if table stores keys only */
+ u8 leafData; /* True if tables stores data on leaves only */
+ u8 hasData; /* True if this page stores data */
+ u8 hdrOffset; /* 100 for page 1. 0 otherwise */
+ u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
+ u16 maxLocal; /* Copy of Btree.maxLocal or Btree.maxLeaf */
+ u16 minLocal; /* Copy of Btree.minLocal or Btree.minLeaf */
+ u16 cellOffset; /* Index in aData of first cell pointer */
+ u16 idxParent; /* Index in parent of this node */
+ u16 nFree; /* Number of free bytes on the page */
+ u16 nCell; /* Number of cells on this page, local and ovfl */
+ struct _OvflCell { /* Cells that will not fit on aData[] */
+ u8 *pCell; /* Pointers to the body of the overflow cell */
+ u16 idx; /* Insert this cell before idx-th non-overflow cell */
+ } aOvfl[5];
+ struct Btree *pBt; /* Pointer back to BTree structure */
+ u8 *aData; /* Pointer back to the start of the page */
+ Pgno pgno; /* Page number for this page */
+ MemPage *pParent; /* The parent of this page. NULL for root */
+};
+
+/*
+** The in-memory image of a disk page has the auxiliary information appended
+** to the end. EXTRA_SIZE is the number of bytes of space needed to hold
+** that extra information.
+*/
+#define EXTRA_SIZE sizeof(MemPage)
+
+/*
+** Everything we need to know about an open database
+*/
+struct Btree {
+ Pager *pPager; /* The page cache */
+ BtCursor *pCursor; /* A list of all open cursors */
+ MemPage *pPage1; /* First page of the database */
+ u8 inTrans; /* True if a transaction is in progress */
+ u8 inStmt; /* True if we are in a statement subtransaction */
+ u8 readOnly; /* True if the underlying file is readonly */
+ u8 maxEmbedFrac; /* Maximum payload as % of total page size */
+ u8 minEmbedFrac; /* Minimum payload as % of total page size */
+ u8 minLeafFrac; /* Minimum leaf payload as % of total page size */
+ u8 pageSizeFixed; /* True if the page size can no longer be changed */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ u8 autoVacuum; /* True if database supports auto-vacuum */
+#endif
+ u16 pageSize; /* Total number of bytes on a page */
+ u16 usableSize; /* Number of usable bytes on each page */
+ int maxLocal; /* Maximum local payload in non-LEAFDATA tables */
+ int minLocal; /* Minimum local payload in non-LEAFDATA tables */
+ int maxLeaf; /* Maximum local payload in a LEAFDATA table */
+ int minLeaf; /* Minimum local payload in a LEAFDATA table */
+ BusyHandler *pBusyHandler; /* Callback for when there is lock contention */
+};
+typedef Btree Bt;
+
+/*
+** Btree.inTrans may take one of the following values.
+*/
+#define TRANS_NONE 0
+#define TRANS_READ 1
+#define TRANS_WRITE 2
+
+/*
+** An instance of the following structure is used to hold information
+** about a cell. The parseCellPtr() function fills in this structure
+** based on information extract from the raw disk page.
+*/
+typedef struct CellInfo CellInfo;
+struct CellInfo {
+ u8 *pCell; /* Pointer to the start of cell content */
+ i64 nKey; /* The key for INTKEY tables, or number of bytes in key */
+ u32 nData; /* Number of bytes of data */
+ u16 nHeader; /* Size of the cell content header in bytes */
+ u16 nLocal; /* Amount of payload held locally */
+ u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
+ u16 nSize; /* Size of the cell content on the main b-tree page */
+};
+
+/*
+** A cursor is a pointer to a particular entry in the BTree.
+** The entry is identified by its MemPage and the index in
+** MemPage.aCell[] of the entry.
+*/
+struct BtCursor {
+ Btree *pBt; /* The Btree to which this cursor belongs */
+ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
+ int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */
+ void *pArg; /* First arg to xCompare() */
+ Pgno pgnoRoot; /* The root page of this tree */
+ MemPage *pPage; /* Page that contains the entry */
+ int idx; /* Index of the entry in pPage->aCell[] */
+ CellInfo info; /* A parse of the cell we are pointing at */
+ u8 wrFlag; /* True if writable */
+ u8 isValid; /* TRUE if points to a valid entry */
+};
+
+/*
+** The TRACE macro will print high-level status information about the
+** btree operation when the global variable sqlite3_btree_trace is
+** enabled.
+*/
+#if SQLITE_TEST
+# define TRACE(X) if( sqlite3_btree_trace )\
+ { sqlite3DebugPrintf X; fflush(stdout); }
+#else
+# define TRACE(X)
+#endif
+int sqlite3_btree_trace=0; /* True to enable tracing */
+
+/*
+** Forward declaration
+*/
+static int checkReadLocks(Btree*,Pgno,BtCursor*);
+
+/*
+** Read or write a two- and four-byte big-endian integer values.
+*/
+static u32 get2byte(unsigned char *p){
+ return (p[0]<<8) | p[1];
+}
+static u32 get4byte(unsigned char *p){
+ return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
+}
+static void put2byte(unsigned char *p, u32 v){
+ p[0] = v>>8;
+ p[1] = v;
+}
+static void put4byte(unsigned char *p, u32 v){
+ p[0] = v>>24;
+ p[1] = v>>16;
+ p[2] = v>>8;
+ p[3] = v;
+}
+
+/*
+** Routines to read and write variable-length integers. These used to
+** be defined locally, but now we use the varint routines in the util.c
+** file.
+*/
+#define getVarint sqlite3GetVarint
+#define getVarint32 sqlite3GetVarint32
+#define putVarint sqlite3PutVarint
+
+/* The database page the PENDING_BYTE occupies. This page is never used.
+** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
+** should possibly be consolidated (presumably in pager.h).
+*/
+#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+/*
+** These macros define the location of the pointer-map entry for a
+** database page. The first argument to each is the number of usable
+** bytes on each page of the database (often 1024). The second is the
+** page number to look up in the pointer map.
+**
+** PTRMAP_PAGENO returns the database page number of the pointer-map
+** page that stores the required pointer. PTRMAP_PTROFFSET returns
+** the offset of the requested map entry.
+**
+** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
+** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
+** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
+** this test.
+*/
+#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2)
+#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5)
+#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno)
+
+/*
+** The pointer map is a lookup table that identifies the parent page for
+** each child page in the database file. The parent page is the page that
+** contains a pointer to the child. Every page in the database contains
+** 0 or 1 parent pages. (In this context 'database page' refers
+** to any page that is not part of the pointer map itself.) Each pointer map
+** entry consists of a single byte 'type' and a 4 byte parent page number.
+** The PTRMAP_XXX identifiers below are the valid types.
+**
+** The purpose of the pointer map is to facility moving pages from one
+** position in the file to another as part of autovacuum. When a page
+** is moved, the pointer in its parent must be updated to point to the
+** new location. The pointer map is used to locate the parent page quickly.
+**
+** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
+** used in this case.
+**
+** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number
+** is not used in this case.
+**
+** PTRMAP_OVERFLOW1: The database page is the first page in a list of
+** overflow pages. The page number identifies the page that
+** contains the cell with a pointer to this overflow page.
+**
+** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
+** overflow pages. The page-number identifies the previous
+** page in the overflow page list.
+**
+** PTRMAP_BTREE: The database page is a non-root btree page. The page number
+** identifies the parent page in the btree.
+*/
+#define PTRMAP_ROOTPAGE 1
+#define PTRMAP_FREEPAGE 2
+#define PTRMAP_OVERFLOW1 3
+#define PTRMAP_OVERFLOW2 4
+#define PTRMAP_BTREE 5
+
+/*
+** Write an entry into the pointer map.
+**
+** This routine updates the pointer map entry for page number 'key'
+** so that it maps to type 'eType' and parent page number 'pgno'.
+** An error code is returned if something goes wrong, otherwise SQLITE_OK.
+*/
+static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){
+ u8 *pPtrmap; /* The pointer map page */
+ Pgno iPtrmap; /* The pointer map page number */
+ int offset; /* Offset in pointer map page */
+ int rc;
+
+ assert( pBt->autoVacuum );
+ if( key==0 ){
+ return SQLITE_CORRUPT;
+ }
+ iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+ rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
+
+ if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
+ TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
+ rc = sqlite3pager_write(pPtrmap);
+ if( rc==SQLITE_OK ){
+ pPtrmap[offset] = eType;
+ put4byte(&pPtrmap[offset+1], parent);
+ }
+ }
+
+ sqlite3pager_unref(pPtrmap);
+ return rc;
+}
+
+/*
+** Read an entry from the pointer map.
+**
+** This routine retrieves the pointer map entry for page 'key', writing
+** the type and parent page number to *pEType and *pPgno respectively.
+** An error code is returned if something goes wrong, otherwise SQLITE_OK.
+*/
+static int ptrmapGet(Btree *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
+ int iPtrmap; /* Pointer map page index */
+ u8 *pPtrmap; /* Pointer map page data */
+ int offset; /* Offset of entry in pointer map */
+ int rc;
+
+ iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+ rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
+ if( rc!=0 ){
+ return rc;
+ }
+
+ offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
+ if( pEType ) *pEType = pPtrmap[offset];
+ if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
+
+ sqlite3pager_unref(pPtrmap);
+ if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT;
+ return SQLITE_OK;
+}
+
+#endif /* SQLITE_OMIT_AUTOVACUUM */
+
+/*
+** Given a btree page and a cell index (0 means the first cell on
+** the page, 1 means the second cell, and so forth) return a pointer
+** to the cell content.
+**
+** This routine works only for pages that do not contain overflow cells.
+*/
+static u8 *findCell(MemPage *pPage, int iCell){
+ u8 *data = pPage->aData;
+ assert( iCell>=0 );
+ assert( iCell<get2byte(&data[pPage->hdrOffset+3]) );
+ return data + get2byte(&data[pPage->cellOffset+2*iCell]);
+}
+
+/*
+** This a more complex version of findCell() that works for
+** pages that do contain overflow cells. See insert
+*/
+static u8 *findOverflowCell(MemPage *pPage, int iCell){
+ int i;
+ for(i=pPage->nOverflow-1; i>=0; i--){
+ int k;
+ struct _OvflCell *pOvfl;
+ pOvfl = &pPage->aOvfl[i];
+ k = pOvfl->idx;
+ if( k<=iCell ){
+ if( k==iCell ){
+ return pOvfl->pCell;
+ }
+ iCell--;
+ }
+ }
+ return findCell(pPage, iCell);
+}
+
+/*
+** Parse a cell content block and fill in the CellInfo structure. There
+** are two versions of this function. parseCell() takes a cell index
+** as the second argument and parseCellPtr() takes a pointer to the
+** body of the cell as its second argument.
+*/
+static void parseCellPtr(
+ MemPage *pPage, /* Page containing the cell */
+ u8 *pCell, /* Pointer to the cell text. */
+ CellInfo *pInfo /* Fill in this structure */
+){
+ int n; /* Number bytes in cell content header */
+ u32 nPayload; /* Number of bytes of cell payload */
+
+ pInfo->pCell = pCell;
+ assert( pPage->leaf==0 || pPage->leaf==1 );
+ n = pPage->childPtrSize;
+ assert( n==4-4*pPage->leaf );
+ if( pPage->hasData ){
+ n += getVarint32(&pCell[n], &nPayload);
+ }else{
+ nPayload = 0;
+ }
+ n += getVarint(&pCell[n], (u64 *)&pInfo->nKey);
+ pInfo->nHeader = n;
+ pInfo->nData = nPayload;
+ if( !pPage->intKey ){
+ nPayload += pInfo->nKey;
+ }
+ if( nPayload<=pPage->maxLocal ){
+ /* This is the (easy) common case where the entire payload fits
+ ** on the local page. No overflow is required.
+ */
+ int nSize; /* Total size of cell content in bytes */
+ pInfo->nLocal = nPayload;
+ pInfo->iOverflow = 0;
+ nSize = nPayload + n;
+ if( nSize<4 ){
+ nSize = 4; /* Minimum cell size is 4 */
+ }
+ pInfo->nSize = nSize;
+ }else{
+ /* If the payload will not fit completely on the local page, we have
+ ** to decide how much to store locally and how much to spill onto
+ ** overflow pages. The strategy is to minimize the amount of unused
+ ** space on overflow pages while keeping the amount of local storage
+ ** in between minLocal and maxLocal.
+ **
+ ** Warning: changing the way overflow payload is distributed in any
+ ** way will result in an incompatible file format.
+ */
+ int minLocal; /* Minimum amount of payload held locally */
+ int maxLocal; /* Maximum amount of payload held locally */
+ int surplus; /* Overflow payload available for local storage */
+
+ minLocal = pPage->minLocal;
+ maxLocal = pPage->maxLocal;
+ surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
+ if( surplus <= maxLocal ){
+ pInfo->nLocal = surplus;
+ }else{
+ pInfo->nLocal = minLocal;
+ }
+ pInfo->iOverflow = pInfo->nLocal + n;
+ pInfo->nSize = pInfo->iOverflow + 4;
+ }
+}
+static void parseCell(
+ MemPage *pPage, /* Page containing the cell */
+ int iCell, /* The cell index. First cell is 0 */
+ CellInfo *pInfo /* Fill in this structure */
+){
+ parseCellPtr(pPage, findCell(pPage, iCell), pInfo);
+}
+
+/*
+** Compute the total number of bytes that a Cell needs in the cell
+** data area of the btree-page. The return number includes the cell
+** data header and the local payload, but not any overflow page or
+** the space used by the cell pointer.
+*/
+#ifndef NDEBUG
+static int cellSize(MemPage *pPage, int iCell){
+ CellInfo info;
+ parseCell(pPage, iCell, &info);
+ return info.nSize;
+}
+#endif
+static int cellSizePtr(MemPage *pPage, u8 *pCell){
+ CellInfo info;
+ parseCellPtr(pPage, pCell, &info);
+ return info.nSize;
+}
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+/*
+** If the cell pCell, part of page pPage contains a pointer
+** to an overflow page, insert an entry into the pointer-map
+** for the overflow page.
+*/
+static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
+ if( pCell ){
+ CellInfo info;
+ parseCellPtr(pPage, pCell, &info);
+ if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
+ Pgno ovfl = get4byte(&pCell[info.iOverflow]);
+ return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
+ }
+ }
+ return SQLITE_OK;
+}
+/*
+** If the cell with index iCell on page pPage contains a pointer
+** to an overflow page, insert an entry into the pointer-map
+** for the overflow page.
+*/
+static int ptrmapPutOvfl(MemPage *pPage, int iCell){
+ u8 *pCell;
+ pCell = findOverflowCell(pPage, iCell);
+ return ptrmapPutOvflPtr(pPage, pCell);
+}
+#endif
+
+
+/*
+** Do sanity checking on a page. Throw an exception if anything is
+** not right.
+**
+** This routine is used for internal error checking only. It is omitted
+** from most builds.
+*/
+#if defined(BTREE_DEBUG) && !defined(NDEBUG) && 0
+static void _pageIntegrity(MemPage *pPage){
+ int usableSize;
+ u8 *data;
+ int i, j, idx, c, pc, hdr, nFree;
+ int cellOffset;
+ int nCell, cellLimit;
+ u8 *used;
+
+ used = sqliteMallocRaw( pPage->pBt->pageSize );
+ if( used==0 ) return;
+ usableSize = pPage->pBt->usableSize;
+ assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] );
+ hdr = pPage->hdrOffset;
+ assert( hdr==(pPage->pgno==1 ? 100 : 0) );
+ assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
+ c = pPage->aData[hdr];
+ if( pPage->isInit ){
+ assert( pPage->leaf == ((c & PTF_LEAF)!=0) );
+ assert( pPage->zeroData == ((c & PTF_ZERODATA)!=0) );
+ assert( pPage->leafData == ((c & PTF_LEAFDATA)!=0) );
+ assert( pPage->intKey == ((c & (PTF_INTKEY|PTF_LEAFDATA))!=0) );
+ assert( pPage->hasData ==
+ !(pPage->zeroData || (!pPage->leaf && pPage->leafData)) );
+ assert( pPage->cellOffset==pPage->hdrOffset+12-4*pPage->leaf );
+ assert( pPage->nCell = get2byte(&pPage->aData[hdr+3]) );
+ }
+ data = pPage->aData;
+ memset(used, 0, usableSize);
+ for(i=0; i<hdr+10-pPage->leaf*4; i++) used[i] = 1;
+ nFree = 0;
+ pc = get2byte(&data[hdr+1]);
+ while( pc ){
+ int size;
+ assert( pc>0 && pc<usableSize-4 );
+ size = get2byte(&data[pc+2]);
+ assert( pc+size<=usableSize );
+ nFree += size;
+ for(i=pc; i<pc+size; i++){
+ assert( used[i]==0 );
+ used[i] = 1;
+ }
+ pc = get2byte(&data[pc]);
+ }
+ idx = 0;
+ nCell = get2byte(&data[hdr+3]);
+ cellLimit = get2byte(&data[hdr+5]);
+ assert( pPage->isInit==0
+ || pPage->nFree==nFree+data[hdr+7]+cellLimit-(cellOffset+2*nCell) );
+ cellOffset = pPage->cellOffset;
+ for(i=0; i<nCell; i++){
+ int size;
+ pc = get2byte(&data[cellOffset+2*i]);
+ assert( pc>0 && pc<usableSize-4 );
+ size = cellSize(pPage, &data[pc]);
+ assert( pc+size<=usableSize );
+ for(j=pc; j<pc+size; j++){
+ assert( used[j]==0 );
+ used[j] = 1;
+ }
+ }
+ for(i=cellOffset+2*nCell; i<cellimit; i++){
+ assert( used[i]==0 );
+ used[i] = 1;
+ }
+ nFree = 0;
+ for(i=0; i<usableSize; i++){
+ assert( used[i]<=1 );
+ if( used[i]==0 ) nFree++;
+ }
+ assert( nFree==data[hdr+7] );
+ sqliteFree(used);
+}
+#define pageIntegrity(X) _pageIntegrity(X)
+#else
+# define pageIntegrity(X)
+#endif
+
+/*
+** Defragment the page given. All Cells are moved to the
+** beginning of the page and all free space is collected
+** into one big FreeBlk at the end of the page.
+*/
+static int defragmentPage(MemPage *pPage){
+ int i; /* Loop counter */
+ int pc; /* Address of a i-th cell */
+ int addr; /* Offset of first byte after cell pointer array */
+ int hdr; /* Offset to the page header */
+ int size; /* Size of a cell */
+ int usableSize; /* Number of usable bytes on a page */
+ int cellOffset; /* Offset to the cell pointer array */
+ int brk; /* Offset to the cell content area */
+ int nCell; /* Number of cells on the page */
+ unsigned char *data; /* The page data */
+ unsigned char *temp; /* Temp area for cell content */
+
+ assert( sqlite3pager_iswriteable(pPage->aData) );
+ assert( pPage->pBt!=0 );
+ assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
+ assert( pPage->nOverflow==0 );
+ temp = sqliteMalloc( pPage->pBt->pageSize );
+ if( temp==0 ) return SQLITE_NOMEM;
+ data = pPage->aData;
+ hdr = pPage->hdrOffset;
+ cellOffset = pPage->cellOffset;
+ nCell = pPage->nCell;
+ assert( nCell==get2byte(&data[hdr+3]) );
+ usableSize = pPage->pBt->usableSize;
+ brk = get2byte(&data[hdr+5]);
+ memcpy(&temp[brk], &data[brk], usableSize - brk);
+ brk = usableSize;
+ for(i=0; i<nCell; i++){
+ u8 *pAddr; /* The i-th cell pointer */
+ pAddr = &data[cellOffset + i*2];
+ pc = get2byte(pAddr);
+ assert( pc<pPage->pBt->usableSize );
+ size = cellSizePtr(pPage, &temp[pc]);
+ brk -= size;
+ memcpy(&data[brk], &temp[pc], size);
+ put2byte(pAddr, brk);
+ }
+ assert( brk>=cellOffset+2*nCell );
+ put2byte(&data[hdr+5], brk);
+ data[hdr+1] = 0;
+ data[hdr+2] = 0;
+ data[hdr+7] = 0;
+ addr = cellOffset+2*nCell;
+ memset(&data[addr], 0, brk-addr);
+ sqliteFree(temp);
+ return SQLITE_OK;
+}
+
+/*
+** Allocate nByte bytes of space on a page.
+**
+** Return the index into pPage->aData[] of the first byte of
+** the new allocation. Or return 0 if there is not enough free
+** space on the page to satisfy the allocation request.
+**
+** If the page contains nBytes of free space but does not contain
+** nBytes of contiguous free space, then this routine automatically
+** calls defragementPage() to consolidate all free space before
+** allocating the new chunk.
+*/
+static int allocateSpace(MemPage *pPage, int nByte){
+ int addr, pc, hdr;
+ int size;
+ int nFrag;
+ int top;
+ int nCell;
+ int cellOffset;
+ unsigned char *data;
+
+ data = pPage->aData;
+ assert( sqlite3pager_iswriteable(data) );
+ assert( pPage->pBt );
+ if( nByte<4 ) nByte = 4;
+ if( pPage->nFree<nByte || pPage->nOverflow>0 ) return 0;
+ pPage->nFree -= nByte;
+ hdr = pPage->hdrOffset;
+
+ nFrag = data[hdr+7];
+ if( nFrag<60 ){
+ /* Search the freelist looking for a slot big enough to satisfy the
+ ** space request. */
+ addr = hdr+1;
+ while( (pc = get2byte(&data[addr]))>0 ){
+ size = get2byte(&data[pc+2]);
+ if( size>=nByte ){
+ if( size<nByte+4 ){
+ memcpy(&data[addr], &data[pc], 2);
+ data[hdr+7] = nFrag + size - nByte;
+ return pc;
+ }else{
+ put2byte(&data[pc+2], size-nByte);
+ return pc + size - nByte;
+ }
+ }
+ addr = pc;
+ }
+ }
+
+ /* Allocate memory from the gap in between the cell pointer array
+ ** and the cell content area.
+ */
+ top = get2byte(&data[hdr+5]);
+ nCell = get2byte(&data[hdr+3]);
+ cellOffset = pPage->cellOffset;
+ if( nFrag>=60 || cellOffset + 2*nCell > top - nByte ){
+ if( defragmentPage(pPage) ) return 0;
+ top = get2byte(&data[hdr+5]);
+ }
+ top -= nByte;
+ assert( cellOffset + 2*nCell <= top );
+ put2byte(&data[hdr+5], top);
+ return top;
+}
+
+/*
+** Return a section of the pPage->aData to the freelist.
+** The first byte of the new free block is pPage->aDisk[start]
+** and the size of the block is "size" bytes.
+**
+** Most of the effort here is involved in coalesing adjacent
+** free blocks into a single big free block.
+*/
+static void freeSpace(MemPage *pPage, int start, int size){
+ int addr, pbegin, hdr;
+ unsigned char *data = pPage->aData;
+
+ assert( pPage->pBt!=0 );
+ assert( sqlite3pager_iswriteable(data) );
+ assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
+ assert( (start + size)<=pPage->pBt->usableSize );
+ if( size<4 ) size = 4;
+
+ /* Add the space back into the linked list of freeblocks */
+ hdr = pPage->hdrOffset;
+ addr = hdr + 1;
+ while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
+ assert( pbegin<=pPage->pBt->usableSize-4 );
+ assert( pbegin>addr );
+ addr = pbegin;
+ }
+ assert( pbegin<=pPage->pBt->usableSize-4 );
+ assert( pbegin>addr || pbegin==0 );
+ put2byte(&data[addr], start);
+ put2byte(&data[start], pbegin);
+ put2byte(&data[start+2], size);
+ pPage->nFree += size;
+
+ /* Coalesce adjacent free blocks */
+ addr = pPage->hdrOffset + 1;
+ while( (pbegin = get2byte(&data[addr]))>0 ){
+ int pnext, psize;
+ assert( pbegin>addr );
+ assert( pbegin<=pPage->pBt->usableSize-4 );
+ pnext = get2byte(&data[pbegin]);
+ psize = get2byte(&data[pbegin+2]);
+ if( pbegin + psize + 3 >= pnext && pnext>0 ){
+ int frag = pnext - (pbegin+psize);
+ assert( frag<=data[pPage->hdrOffset+7] );
+ data[pPage->hdrOffset+7] -= frag;
+ put2byte(&data[pbegin], get2byte(&data[pnext]));
+ put2byte(&data[pbegin+2], pnext+get2byte(&data[pnext+2])-pbegin);
+ }else{
+ addr = pbegin;
+ }
+ }
+
+ /* If the cell content area begins with a freeblock, remove it. */
+ if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
+ int top;
+ pbegin = get2byte(&data[hdr+1]);
+ memcpy(&data[hdr+1], &data[pbegin], 2);
+ top = get2byte(&data[hdr+5]);
+ put2byte(&data[hdr+5], top + get2byte(&data[pbegin+2]));
+ }
+}
+
+/*
+** Decode the flags byte (the first byte of the header) for a page
+** and initialize fields of the MemPage structure accordingly.
+*/
+static void decodeFlags(MemPage *pPage, int flagByte){
+ Btree *pBt; /* A copy of pPage->pBt */
+
+ assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
+ pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
+ pPage->zeroData = (flagByte & PTF_ZERODATA)!=0;
+ pPage->leaf = (flagByte & PTF_LEAF)!=0;
+ pPage->childPtrSize = 4*(pPage->leaf==0);
+ pBt = pPage->pBt;
+ if( flagByte & PTF_LEAFDATA ){
+ pPage->leafData = 1;
+ pPage->maxLocal = pBt->maxLeaf;
+ pPage->minLocal = pBt->minLeaf;
+ }else{
+ pPage->leafData = 0;
+ pPage->maxLocal = pBt->maxLocal;
+ pPage->minLocal = pBt->minLocal;
+ }
+ pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
+}
+
+/*
+** Initialize the auxiliary information for a disk block.
+**
+** The pParent parameter must be a pointer to the MemPage which
+** is the parent of the page being initialized. The root of a
+** BTree has no parent and so for that page, pParent==NULL.
+**
+** Return SQLITE_OK on success. If we see that the page does
+** not contain a well-formed database page, then return
+** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
+** guarantee that the page is well-formed. It only shows that
+** we failed to detect any corruption.
+*/
+static int initPage(
+ MemPage *pPage, /* The page to be initialized */
+ MemPage *pParent /* The parent. Might be NULL */
+){
+ int pc; /* Address of a freeblock within pPage->aData[] */
+ int hdr; /* Offset to beginning of page header */
+ u8 *data; /* Equal to pPage->aData */
+ Btree *pBt; /* The main btree structure */
+ int usableSize; /* Amount of usable space on each page */
+ int cellOffset; /* Offset from start of page to first cell pointer */
+ int nFree; /* Number of unused bytes on the page */
+ int top; /* First byte of the cell content area */
+
+ pBt = pPage->pBt;
+ assert( pBt!=0 );
+ assert( pParent==0 || pParent->pBt==pBt );
+ assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
+ assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] );
+ if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
+ /* The parent page should never change unless the file is corrupt */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ if( pPage->isInit ) return SQLITE_OK;
+ if( pPage->pParent==0 && pParent!=0 ){
+ pPage->pParent = pParent;
+ sqlite3pager_ref(pParent->aData);
+ }
+ hdr = pPage->hdrOffset;
+ data = pPage->aData;
+ decodeFlags(pPage, data[hdr]);
+ pPage->nOverflow = 0;
+ pPage->idxShift = 0;
+ usableSize = pBt->usableSize;
+ pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
+ top = get2byte(&data[hdr+5]);
+ pPage->nCell = get2byte(&data[hdr+3]);
+ if( pPage->nCell>MX_CELL(pBt) ){
+ /* To many cells for a single page. The page must be corrupt */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){
+ /* All pages must have at least one cell, except for root pages */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+
+ /* Compute the total free space on the page */
+ pc = get2byte(&data[hdr+1]);
+ nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
+ while( pc>0 ){
+ int next, size;
+ if( pc>usableSize-4 ){
+ /* Free block is off the page */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ next = get2byte(&data[pc]);
+ size = get2byte(&data[pc+2]);
+ if( next>0 && next<=pc+size+3 ){
+ /* Free blocks must be in accending order */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ nFree += size;
+ pc = next;
+ }
+ pPage->nFree = nFree;
+ if( nFree>=usableSize ){
+ /* Free space cannot exceed total page size */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+
+ pPage->isInit = 1;
+ pageIntegrity(pPage);
+ return SQLITE_OK;
+}
+
+/*
+** Set up a raw page so that it looks like a database page holding
+** no entries.
+*/
+static void zeroPage(MemPage *pPage, int flags){
+ unsigned char *data = pPage->aData;
+ Btree *pBt = pPage->pBt;
+ int hdr = pPage->hdrOffset;
+ int first;
+
+ assert( sqlite3pager_pagenumber(data)==pPage->pgno );
+ assert( &data[pBt->pageSize] == (unsigned char*)pPage );
+ assert( sqlite3pager_iswriteable(data) );
+ memset(&data[hdr], 0, pBt->usableSize - hdr);
+ data[hdr] = flags;
+ first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
+ memset(&data[hdr+1], 0, 4);
+ data[hdr+7] = 0;
+ put2byte(&data[hdr+5], pBt->usableSize);
+ pPage->nFree = pBt->usableSize - first;
+ decodeFlags(pPage, flags);
+ pPage->hdrOffset = hdr;
+ pPage->cellOffset = first;
+ pPage->nOverflow = 0;
+ pPage->idxShift = 0;
+ pPage->nCell = 0;
+ pPage->isInit = 1;
+ pageIntegrity(pPage);
+}
+
+/*
+** Get a page from the pager. Initialize the MemPage.pBt and
+** MemPage.aData elements if needed.
+*/
+static int getPage(Btree *pBt, Pgno pgno, MemPage **ppPage){
+ int rc;
+ unsigned char *aData;
+ MemPage *pPage;
+ rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData);
+ if( rc ) return rc;
+ pPage = (MemPage*)&aData[pBt->pageSize];
+ pPage->aData = aData;
+ pPage->pBt = pBt;
+ pPage->pgno = pgno;
+ pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
+ *ppPage = pPage;
+ return SQLITE_OK;
+}
+
+/*
+** Get a page from the pager and initialize it. This routine
+** is just a convenience wrapper around separate calls to
+** getPage() and initPage().
+*/
+static int getAndInitPage(
+ Btree *pBt, /* The database file */
+ Pgno pgno, /* Number of the page to get */
+ MemPage **ppPage, /* Write the page pointer here */
+ MemPage *pParent /* Parent of the page */
+){
+ int rc;
+ if( pgno==0 ){
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ rc = getPage(pBt, pgno, ppPage);
+ if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
+ rc = initPage(*ppPage, pParent);
+ }
+ return rc;
+}
+
+/*
+** Release a MemPage. This should be called once for each prior
+** call to getPage.
+*/
+static void releasePage(MemPage *pPage){
+ if( pPage ){
+ assert( pPage->aData );
+ assert( pPage->pBt );
+ assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage );
+ sqlite3pager_unref(pPage->aData);
+ }
+}
+
+/*
+** This routine is called when the reference count for a page
+** reaches zero. We need to unref the pParent pointer when that
+** happens.
+*/
+static void pageDestructor(void *pData, int pageSize){
+ MemPage *pPage;
+ assert( (pageSize & 7)==0 );
+ pPage = (MemPage*)&((char*)pData)[pageSize];
+ if( pPage->pParent ){
+ MemPage *pParent = pPage->pParent;
+ pPage->pParent = 0;
+ releasePage(pParent);
+ }
+ pPage->isInit = 0;
+}
+
+/*
+** During a rollback, when the pager reloads information into the cache
+** so that the cache is restored to its original state at the start of
+** the transaction, for each page restored this routine is called.
+**
+** This routine needs to reset the extra data section at the end of the
+** page to agree with the restored data.
+*/
+static void pageReinit(void *pData, int pageSize){
+ MemPage *pPage;
+ assert( (pageSize & 7)==0 );
+ pPage = (MemPage*)&((char*)pData)[pageSize];
+ if( pPage->isInit ){
+ pPage->isInit = 0;
+ initPage(pPage, pPage->pParent);
+ }
+}
+
+/*
+** Open a database file.
+**
+** zFilename is the name of the database file. If zFilename is NULL
+** a new database with a random name is created. This randomly named
+** database file will be deleted when sqlite3BtreeClose() is called.
+*/
+int sqlite3BtreeOpen(
+ const char *zFilename, /* Name of the file containing the BTree database */
+ Btree **ppBtree, /* Pointer to new Btree object written here */
+ int flags /* Options */
+){
+ Btree *pBt;
+ int rc;
+ int nReserve;
+ unsigned char zDbHeader[100];
+
+ /*
+ ** The following asserts make sure that structures used by the btree are
+ ** the right size. This is to guard against size changes that result
+ ** when compiling on a different architecture.
+ */
+ assert( sizeof(i64)==8 );
+ assert( sizeof(u64)==8 );
+ assert( sizeof(u32)==4 );
+ assert( sizeof(u16)==2 );
+ assert( sizeof(Pgno)==4 );
+
+ pBt = sqliteMalloc( sizeof(*pBt) );
+ if( pBt==0 ){
+ *ppBtree = 0;
+ return SQLITE_NOMEM;
+ }
+ rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
+ if( rc!=SQLITE_OK ){
+ if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
+ sqliteFree(pBt);
+ *ppBtree = 0;
+ return rc;
+ }
+ sqlite3pager_set_destructor(pBt->pPager, pageDestructor);
+ sqlite3pager_set_reiniter(pBt->pPager, pageReinit);
+ pBt->pCursor = 0;
+ pBt->pPage1 = 0;
+ pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
+ sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
+ pBt->pageSize = get2byte(&zDbHeader[16]);
+ if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
+ || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
+ pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
+ pBt->maxEmbedFrac = 64; /* 25% */
+ pBt->minEmbedFrac = 32; /* 12.5% */
+ pBt->minLeafFrac = 32; /* 12.5% */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* If the magic name ":memory:" will create an in-memory database, then
+ ** do not set the auto-vacuum flag, even if SQLITE_DEFAULT_AUTOVACUUM
+ ** is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined,
+ ** then ":memory:" is just a regular file-name. Respect the auto-vacuum
+ ** default in this case.
+ */
+#ifndef SQLITE_OMIT_MEMORYDB
+ if( zFilename && strcmp(zFilename,":memory:") ){
+#else
+ if( zFilename ){
+#endif
+ pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM;
+ }
+#endif
+ nReserve = 0;
+ }else{
+ nReserve = zDbHeader[20];
+ pBt->maxEmbedFrac = zDbHeader[21];
+ pBt->minEmbedFrac = zDbHeader[22];
+ pBt->minLeafFrac = zDbHeader[23];
+ pBt->pageSizeFixed = 1;
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
+#endif
+ }
+ pBt->usableSize = pBt->pageSize - nReserve;
+ assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */
+ sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
+ *ppBtree = pBt;
+ return SQLITE_OK;
+}
+
+/*
+** Close an open database and invalidate all cursors.
+*/
+int sqlite3BtreeClose(Btree *pBt){
+ while( pBt->pCursor ){
+ sqlite3BtreeCloseCursor(pBt->pCursor);
+ }
+ sqlite3pager_close(pBt->pPager);
+ sqliteFree(pBt);
+ return SQLITE_OK;
+}
+
+/*
+** Change the busy handler callback function.
+*/
+int sqlite3BtreeSetBusyHandler(Btree *pBt, BusyHandler *pHandler){
+ pBt->pBusyHandler = pHandler;
+ sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
+ return SQLITE_OK;
+}
+
+/*
+** Change the limit on the number of pages allowed in the cache.
+**
+** The maximum number of cache pages is set to the absolute
+** value of mxPage. If mxPage is negative, the pager will
+** operate asynchronously - it will not stop to do fsync()s
+** to insure data is written to the disk surface before
+** continuing. Transactions still work if synchronous is off,
+** and the database cannot be corrupted if this program
+** crashes. But if the operating system crashes or there is
+** an abrupt power failure when synchronous is off, the database
+** could be left in an inconsistent and unrecoverable state.
+** Synchronous is on by default so database corruption is not
+** normally a worry.
+*/
+int sqlite3BtreeSetCacheSize(Btree *pBt, int mxPage){
+ sqlite3pager_set_cachesize(pBt->pPager, mxPage);
+ return SQLITE_OK;
+}
+
+/*
+** Change the way data is synced to disk in order to increase or decrease
+** how well the database resists damage due to OS crashes and power
+** failures. Level 1 is the same as asynchronous (no syncs() occur and
+** there is a high probability of damage) Level 2 is the default. There
+** is a very low but non-zero probability of damage. Level 3 reduces the
+** probability of damage to near zero but with a write performance reduction.
+*/
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
+ sqlite3pager_set_safety_level(pBt->pPager, level);
+ return SQLITE_OK;
+}
+#endif
+
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
+/*
+** Change the default pages size and the number of reserved bytes per page.
+**
+** The page size must be a power of 2 between 512 and 65536. If the page
+** size supplied does not meet this constraint then the page size is not
+** changed.
+**
+** Page sizes are constrained to be a power of two so that the region
+** of the database file used for locking (beginning at PENDING_BYTE,
+** the first byte past the 1GB boundary, 0x40000000) needs to occur
+** at the beginning of a page.
+**
+** If parameter nReserve is less than zero, then the number of reserved
+** bytes per page is left unchanged.
+*/
+int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){
+ if( pBt->pageSizeFixed ){
+ return SQLITE_READONLY;
+ }
+ if( nReserve<0 ){
+ nReserve = pBt->pageSize - pBt->usableSize;
+ }
+ if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
+ ((pageSize-1)&pageSize)==0 ){
+ assert( (pageSize & 7)==0 );
+ pBt->pageSize = sqlite3pager_set_pagesize(pBt->pPager, pageSize);
+ }
+ pBt->usableSize = pBt->pageSize - nReserve;
+ return SQLITE_OK;
+}
+
+/*
+** Return the currently defined page size
+*/
+int sqlite3BtreeGetPageSize(Btree *pBt){
+ return pBt->pageSize;
+}
+int sqlite3BtreeGetReserve(Btree *pBt){
+ return pBt->pageSize - pBt->usableSize;
+}
+#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
+
+/*
+** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
+** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
+** is disabled. The default value for the auto-vacuum property is
+** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
+*/
+int sqlite3BtreeSetAutoVacuum(Btree *pBt, int autoVacuum){
+#ifdef SQLITE_OMIT_AUTOVACUUM
+ return SQLITE_READONLY;
+#else
+ if( pBt->pageSizeFixed ){
+ return SQLITE_READONLY;
+ }
+ pBt->autoVacuum = (autoVacuum?1:0);
+ return SQLITE_OK;
+#endif
+}
+
+/*
+** Return the value of the 'auto-vacuum' property. If auto-vacuum is
+** enabled 1 is returned. Otherwise 0.
+*/
+int sqlite3BtreeGetAutoVacuum(Btree *pBt){
+#ifdef SQLITE_OMIT_AUTOVACUUM
+ return 0;
+#else
+ return pBt->autoVacuum;
+#endif
+}
+
+
+/*
+** Get a reference to pPage1 of the database file. This will
+** also acquire a readlock on that file.
+**
+** SQLITE_OK is returned on success. If the file is not a
+** well-formed database file, then SQLITE_CORRUPT is returned.
+** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM
+** is returned if we run out of memory. SQLITE_PROTOCOL is returned
+** if there is a locking protocol violation.
+*/
+static int lockBtree(Btree *pBt){
+ int rc, pageSize;
+ MemPage *pPage1;
+ if( pBt->pPage1 ) return SQLITE_OK;
+ rc = getPage(pBt, 1, &pPage1);
+ if( rc!=SQLITE_OK ) return rc;
+
+
+ /* Do some checking to help insure the file we opened really is
+ ** a valid database file.
+ */
+ rc = SQLITE_NOTADB;
+ if( sqlite3pager_pagecount(pBt->pPager)>0 ){
+ u8 *page1 = pPage1->aData;
+ if( memcmp(page1, zMagicHeader, 16)!=0 ){
+ goto page1_init_failed;
+ }
+ if( page1[18]>1 || page1[19]>1 ){
+ goto page1_init_failed;
+ }
+ pageSize = get2byte(&page1[16]);
+ if( ((pageSize-1)&pageSize)!=0 ){
+ goto page1_init_failed;
+ }
+ assert( (pageSize & 7)==0 );
+ pBt->pageSize = pageSize;
+ pBt->usableSize = pageSize - page1[20];
+ if( pBt->usableSize<500 ){
+ goto page1_init_failed;
+ }
+ pBt->maxEmbedFrac = page1[21];
+ pBt->minEmbedFrac = page1[22];
+ pBt->minLeafFrac = page1[23];
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
+#endif
+ }
+
+ /* maxLocal is the maximum amount of payload to store locally for
+ ** a cell. Make sure it is small enough so that at least minFanout
+ ** cells can will fit on one page. We assume a 10-byte page header.
+ ** Besides the payload, the cell must store:
+ ** 2-byte pointer to the cell
+ ** 4-byte child pointer
+ ** 9-byte nKey value
+ ** 4-byte nData value
+ ** 4-byte overflow page pointer
+ ** So a cell consists of a 2-byte poiner, a header which is as much as
+ ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
+ ** page pointer.
+ */
+ pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23;
+ pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23;
+ pBt->maxLeaf = pBt->usableSize - 35;
+ pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23;
+ if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){
+ goto page1_init_failed;
+ }
+ assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
+ pBt->pPage1 = pPage1;
+ return SQLITE_OK;
+
+page1_init_failed:
+ releasePage(pPage1);
+ pBt->pPage1 = 0;
+ return rc;
+}
+
+/*
+** This routine works like lockBtree() except that it also invokes the
+** busy callback if there is lock contention.
+*/
+static int lockBtreeWithRetry(Btree *pBt){
+ int rc = SQLITE_OK;
+ if( pBt->inTrans==TRANS_NONE ){
+ rc = sqlite3BtreeBeginTrans(pBt, 0);
+ pBt->inTrans = TRANS_NONE;
+ }
+ return rc;
+}
+
+
+/*
+** If there are no outstanding cursors and we are not in the middle
+** of a transaction but there is a read lock on the database, then
+** this routine unrefs the first page of the database file which
+** has the effect of releasing the read lock.
+**
+** If there are any outstanding cursors, this routine is a no-op.
+**
+** If there is a transaction in progress, this routine is a no-op.
+*/
+static void unlockBtreeIfUnused(Btree *pBt){
+ if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
+ if( pBt->pPage1->aData==0 ){
+ MemPage *pPage = pBt->pPage1;
+ pPage->aData = &((char*)pPage)[-pBt->pageSize];
+ pPage->pBt = pBt;
+ pPage->pgno = 1;
+ }
+ releasePage(pBt->pPage1);
+ pBt->pPage1 = 0;
+ pBt->inStmt = 0;
+ }
+}
+
+/*
+** Create a new database by initializing the first page of the
+** file.
+*/
+static int newDatabase(Btree *pBt){
+ MemPage *pP1;
+ unsigned char *data;
+ int rc;
+ if( sqlite3pager_pagecount(pBt->pPager)>0 ) return SQLITE_OK;
+ pP1 = pBt->pPage1;
+ assert( pP1!=0 );
+ data = pP1->aData;
+ rc = sqlite3pager_write(data);
+ if( rc ) return rc;
+ memcpy(data, zMagicHeader, sizeof(zMagicHeader));
+ assert( sizeof(zMagicHeader)==16 );
+ put2byte(&data[16], pBt->pageSize);
+ data[18] = 1;
+ data[19] = 1;
+ data[20] = pBt->pageSize - pBt->usableSize;
+ data[21] = pBt->maxEmbedFrac;
+ data[22] = pBt->minEmbedFrac;
+ data[23] = pBt->minLeafFrac;
+ memset(&data[24], 0, 100-24);
+ zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
+ pBt->pageSizeFixed = 1;
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ put4byte(&data[36 + 4*4], 1);
+ }
+#endif
+ return SQLITE_OK;
+}
+
+/*
+** Attempt to start a new transaction. A write-transaction
+** is started if the second argument is nonzero, otherwise a read-
+** transaction. If the second argument is 2 or more and exclusive
+** transaction is started, meaning that no other process is allowed
+** to access the database. A preexisting transaction may not be
+** upgraded to exclusive by calling this routine a second time - the
+** exclusivity flag only works for a new transaction.
+**
+** A write-transaction must be started before attempting any
+** changes to the database. None of the following routines
+** will work unless a transaction is started first:
+**
+** sqlite3BtreeCreateTable()
+** sqlite3BtreeCreateIndex()
+** sqlite3BtreeClearTable()
+** sqlite3BtreeDropTable()
+** sqlite3BtreeInsert()
+** sqlite3BtreeDelete()
+** sqlite3BtreeUpdateMeta()
+**
+** If an initial attempt to acquire the lock fails because of lock contention
+** and the database was previously unlocked, then invoke the busy handler
+** if there is one. But if there was previously a read-lock, do not
+** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is
+** returned when there is already a read-lock in order to avoid a deadlock.
+**
+** Suppose there are two processes A and B. A has a read lock and B has
+** a reserved lock. B tries to promote to exclusive but is blocked because
+** of A's read lock. A tries to promote to reserved but is blocked by B.
+** One or the other of the two processes must give way or there can be
+** no progress. By returning SQLITE_BUSY and not invoking the busy callback
+** when A already has a read lock, we encourage A to give up and let B
+** proceed.
+*/
+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
+ ** is requested, this is a no-op.
+ */
+ if( pBt->inTrans==TRANS_WRITE || (pBt->inTrans==TRANS_READ && !wrflag) ){
+ return SQLITE_OK;
+ }
+
+ /* Write transactions are not possible on a read-only database */
+ if( pBt->readOnly && wrflag ){
+ return SQLITE_READONLY;
+ }
+
+ do {
+ if( pBt->pPage1==0 ){
+ rc = lockBtree(pBt);
+ }
+
+ if( rc==SQLITE_OK && wrflag ){
+ rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1);
+ if( rc==SQLITE_OK ){
+ rc = newDatabase(pBt);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
+ if( wrflag ) pBt->inStmt = 0;
+ }else{
+ unlockBtreeIfUnused(pBt);
+ }
+ }while( rc==SQLITE_BUSY && pBt->inTrans==TRANS_NONE &&
+ (pH = pBt->pBusyHandler)!=0 &&
+ pH->xFunc && pH->xFunc(pH->pArg, busy++)
+ );
+ return rc;
+}
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+
+/*
+** Set the pointer-map entries for all children of page pPage. Also, if
+** pPage contains cells that point to overflow pages, set the pointer
+** map entries for the overflow pages as well.
+*/
+static int setChildPtrmaps(MemPage *pPage){
+ int i; /* Counter variable */
+ int nCell; /* Number of cells in page pPage */
+ int rc = SQLITE_OK; /* Return code */
+ Btree *pBt = pPage->pBt;
+ int isInitOrig = pPage->isInit;
+ Pgno pgno = pPage->pgno;
+
+ initPage(pPage, 0);
+ nCell = pPage->nCell;
+
+ for(i=0; i<nCell; i++){
+ u8 *pCell = findCell(pPage, i);
+
+ rc = ptrmapPutOvflPtr(pPage, pCell);
+ if( rc!=SQLITE_OK ){
+ goto set_child_ptrmaps_out;
+ }
+
+ if( !pPage->leaf ){
+ Pgno childPgno = get4byte(pCell);
+ rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
+ if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
+ }
+ }
+
+ if( !pPage->leaf ){
+ Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
+ }
+
+set_child_ptrmaps_out:
+ pPage->isInit = isInitOrig;
+ return rc;
+}
+
+/*
+** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow
+** page, is a pointer to page iFrom. Modify this pointer so that it points to
+** iTo. Parameter eType describes the type of pointer to be modified, as
+** follows:
+**
+** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child
+** page of pPage.
+**
+** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
+** page pointed to by one of the cells on pPage.
+**
+** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
+** overflow page in the list.
+*/
+static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
+ if( eType==PTRMAP_OVERFLOW2 ){
+ /* The pointer is always the first 4 bytes of the page in this case. */
+ if( get4byte(pPage->aData)!=iFrom ){
+ return SQLITE_CORRUPT;
+ }
+ put4byte(pPage->aData, iTo);
+ }else{
+ int isInitOrig = pPage->isInit;
+ int i;
+ int nCell;
+
+ initPage(pPage, 0);
+ nCell = pPage->nCell;
+
+ for(i=0; i<nCell; i++){
+ u8 *pCell = findCell(pPage, i);
+ if( eType==PTRMAP_OVERFLOW1 ){
+ CellInfo info;
+ parseCellPtr(pPage, pCell, &info);
+ if( info.iOverflow ){
+ if( iFrom==get4byte(&pCell[info.iOverflow]) ){
+ put4byte(&pCell[info.iOverflow], iTo);
+ break;
+ }
+ }
+ }else{
+ if( get4byte(pCell)==iFrom ){
+ put4byte(pCell, iTo);
+ break;
+ }
+ }
+ }
+
+ if( i==nCell ){
+ if( eType!=PTRMAP_BTREE ||
+ get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
+ return SQLITE_CORRUPT;
+ }
+ put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
+ }
+
+ pPage->isInit = isInitOrig;
+ }
+ return SQLITE_OK;
+}
+
+
+/*
+** Move the open database page pDbPage to location iFreePage in the
+** database. The pDbPage reference remains valid.
+*/
+static int relocatePage(
+ Btree *pBt, /* Btree */
+ MemPage *pDbPage, /* Open page to move */
+ u8 eType, /* Pointer map 'type' entry for pDbPage */
+ Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */
+ Pgno iFreePage /* The location to move pDbPage to */
+){
+ MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */
+ Pgno iDbPage = pDbPage->pgno;
+ Pager *pPager = pBt->pPager;
+ int rc;
+
+ assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
+ eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
+
+ /* Move page iDbPage from it's current location to page number iFreePage */
+ TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
+ iDbPage, iFreePage, iPtrPage, eType));
+ rc = sqlite3pager_movepage(pPager, pDbPage->aData, iFreePage);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ pDbPage->pgno = iFreePage;
+
+ /* If pDbPage was a btree-page, then it may have child pages and/or cells
+ ** that point to overflow pages. The pointer map entries for all these
+ ** pages need to be changed.
+ **
+ ** If pDbPage is an overflow page, then the first 4 bytes may store a
+ ** pointer to a subsequent overflow page. If this is the case, then
+ ** the pointer map needs to be updated for the subsequent overflow page.
+ */
+ if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){
+ rc = setChildPtrmaps(pDbPage);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }else{
+ Pgno nextOvfl = get4byte(pDbPage->aData);
+ if( nextOvfl!=0 ){
+ rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
+ }
+
+ /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
+ ** that it points at iFreePage. Also fix the pointer map entry for
+ ** iPtrPage.
+ */
+ if( eType!=PTRMAP_ROOTPAGE ){
+ rc = getPage(pBt, iPtrPage, &pPtrPage);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = sqlite3pager_write(pPtrPage->aData);
+ if( rc!=SQLITE_OK ){
+ releasePage(pPtrPage);
+ return rc;
+ }
+ rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
+ releasePage(pPtrPage);
+ if( rc==SQLITE_OK ){
+ rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
+ }
+ }
+ return rc;
+}
+
+/* Forward declaration required by autoVacuumCommit(). */
+static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8);
+
+/*
+** This routine is called prior to sqlite3pager_commit when a transaction
+** is commited for an auto-vacuum database.
+*/
+static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){
+ Pager *pPager = pBt->pPager;
+ Pgno nFreeList; /* Number of pages remaining on the free-list. */
+ int nPtrMap; /* Number of pointer-map pages deallocated */
+ Pgno origSize; /* Pages in the database file */
+ Pgno finSize; /* Pages in the database file after truncation */
+ int rc; /* Return code */
+ u8 eType;
+ int pgsz = pBt->pageSize; /* Page size for this database */
+ Pgno iDbPage; /* The database page to move */
+ MemPage *pDbMemPage = 0; /* "" */
+ Pgno iPtrPage; /* The page that contains a pointer to iDbPage */
+ Pgno iFreePage; /* The free-list page to move iDbPage to */
+ MemPage *pFreeMemPage = 0; /* "" */
+
+#ifndef NDEBUG
+ int nRef = *sqlite3pager_stats(pPager);
+#endif
+
+ assert( pBt->autoVacuum );
+ if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){
+ return SQLITE_CORRUPT;
+ }
+
+ /* Figure out how many free-pages are in the database. If there are no
+ ** free pages, then auto-vacuum is a no-op.
+ */
+ nFreeList = get4byte(&pBt->pPage1->aData[36]);
+ if( nFreeList==0 ){
+ *nTrunc = 0;
+ return SQLITE_OK;
+ }
+
+ origSize = sqlite3pager_pagecount(pPager);
+ nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
+ finSize = origSize - nFreeList - nPtrMap;
+ if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
+ finSize--;
+ if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){
+ finSize--;
+ }
+ }
+ TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));
+
+ /* Variable 'finSize' will be the size of the file in pages after
+ ** the auto-vacuum has completed (the current file size minus the number
+ ** of pages on the free list). Loop through the pages that lie beyond
+ ** this mark, and if they are not already on the free list, move them
+ ** to a free page earlier in the file (somewhere before finSize).
+ */
+ for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){
+ /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
+ if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
+ continue;
+ }
+
+ rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage);
+ if( rc!=SQLITE_OK ) goto autovacuum_out;
+ if( eType==PTRMAP_ROOTPAGE ){
+ rc = SQLITE_CORRUPT;
+ goto autovacuum_out;
+ }
+
+ /* If iDbPage is free, do not swap it. */
+ if( eType==PTRMAP_FREEPAGE ){
+ continue;
+ }
+ rc = getPage(pBt, iDbPage, &pDbMemPage);
+ if( rc!=SQLITE_OK ) goto autovacuum_out;
+
+ /* Find the next page in the free-list that is not already at the end
+ ** of the file. A page can be pulled off the free list using the
+ ** allocatePage() routine.
+ */
+ do{
+ if( pFreeMemPage ){
+ releasePage(pFreeMemPage);
+ pFreeMemPage = 0;
+ }
+ rc = allocatePage(pBt, &pFreeMemPage, &iFreePage, 0, 0);
+ if( rc!=SQLITE_OK ){
+ releasePage(pDbMemPage);
+ goto autovacuum_out;
+ }
+ assert( iFreePage<=origSize );
+ }while( iFreePage>finSize );
+ releasePage(pFreeMemPage);
+ pFreeMemPage = 0;
+
+ rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage);
+ releasePage(pDbMemPage);
+ if( rc!=SQLITE_OK ) goto autovacuum_out;
+ }
+
+ /* The entire free-list has been swapped to the end of the file. So
+ ** truncate the database file to finSize pages and consider the
+ ** free-list empty.
+ */
+ rc = sqlite3pager_write(pBt->pPage1->aData);
+ if( rc!=SQLITE_OK ) goto autovacuum_out;
+ put4byte(&pBt->pPage1->aData[32], 0);
+ put4byte(&pBt->pPage1->aData[36], 0);
+ if( rc!=SQLITE_OK ) goto autovacuum_out;
+ *nTrunc = finSize;
+
+autovacuum_out:
+ assert( nRef==*sqlite3pager_stats(pPager) );
+ if( rc!=SQLITE_OK ){
+ sqlite3pager_rollback(pPager);
+ }
+ return rc;
+}
+#endif
+
+/*
+** Commit the transaction currently in progress.
+**
+** This will release the write lock on the database file. If there
+** are no active cursors, it also releases the read lock.
+*/
+int sqlite3BtreeCommit(Btree *pBt){
+ int rc = SQLITE_OK;
+ if( pBt->inTrans==TRANS_WRITE ){
+ rc = sqlite3pager_commit(pBt->pPager);
+ }
+ pBt->inTrans = TRANS_NONE;
+ pBt->inStmt = 0;
+ unlockBtreeIfUnused(pBt);
+ return rc;
+}
+
+#ifndef NDEBUG
+/*
+** Return the number of write-cursors open on this handle. This is for use
+** in assert() expressions, so it is only compiled if NDEBUG is not
+** defined.
+*/
+static int countWriteCursors(Btree *pBt){
+ BtCursor *pCur;
+ int r = 0;
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ if( pCur->wrFlag ) r++;
+ }
+ return r;
+}
+#endif
+
+#ifdef SQLITE_TEST
+/*
+** Print debugging information about all cursors to standard output.
+*/
+void sqlite3BtreeCursorList(Btree *pBt){
+ BtCursor *pCur;
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ MemPage *pPage = pCur->pPage;
+ char *zMode = pCur->wrFlag ? "rw" : "ro";
+ sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
+ pCur, pCur->pgnoRoot, zMode,
+ pPage ? pPage->pgno : 0, pCur->idx,
+ pCur->isValid ? "" : " eof"
+ );
+ }
+}
+#endif
+
+/*
+** Rollback the transaction in progress. All cursors will be
+** invalided by this operation. Any attempt to use a cursor
+** that was open at the beginning of this operation will result
+** in an error.
+**
+** This will release the write lock on the database file. If there
+** are no active cursors, it also releases the read lock.
+*/
+int sqlite3BtreeRollback(Btree *pBt){
+ int rc = SQLITE_OK;
+ MemPage *pPage1;
+ if( pBt->inTrans==TRANS_WRITE ){
+ rc = sqlite3pager_rollback(pBt->pPager);
+ /* The rollback may have destroyed the pPage1->aData value. So
+ ** call getPage() on page 1 again to make sure pPage1->aData is
+ ** set correctly. */
+ if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
+ releasePage(pPage1);
+ }
+ assert( countWriteCursors(pBt)==0 );
+ }
+ pBt->inTrans = TRANS_NONE;
+ pBt->inStmt = 0;
+ unlockBtreeIfUnused(pBt);
+ return rc;
+}
+
+/*
+** Start a statement subtransaction. The subtransaction can
+** can be rolled back independently of the main transaction.
+** You must start a transaction before starting a subtransaction.
+** The subtransaction is ended automatically if the main transaction
+** commits or rolls back.
+**
+** Only one subtransaction may be active at a time. It is an error to try
+** to start a new subtransaction if another subtransaction is already active.
+**
+** Statement subtransactions are used around individual SQL statements
+** that are contained within a BEGIN...COMMIT block. If a constraint
+** error occurs within the statement, the effect of that one statement
+** can be rolled back without having to rollback the entire transaction.
+*/
+int sqlite3BtreeBeginStmt(Btree *pBt){
+ int rc;
+ if( (pBt->inTrans!=TRANS_WRITE) || pBt->inStmt ){
+ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
+ }
+ rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_stmt_begin(pBt->pPager);
+ pBt->inStmt = 1;
+ return rc;
+}
+
+
+/*
+** Commit the statment subtransaction currently in progress. If no
+** subtransaction is active, this is a no-op.
+*/
+int sqlite3BtreeCommitStmt(Btree *pBt){
+ int rc;
+ if( pBt->inStmt && !pBt->readOnly ){
+ rc = sqlite3pager_stmt_commit(pBt->pPager);
+ }else{
+ rc = SQLITE_OK;
+ }
+ pBt->inStmt = 0;
+ return rc;
+}
+
+/*
+** Rollback the active statement subtransaction. If no subtransaction
+** is active this routine is a no-op.
+**
+** All cursors will be invalidated by this operation. Any attempt
+** to use a cursor that was open at the beginning of this operation
+** will result in an error.
+*/
+int sqlite3BtreeRollbackStmt(Btree *pBt){
+ int rc;
+ if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
+ rc = sqlite3pager_stmt_rollback(pBt->pPager);
+ assert( countWriteCursors(pBt)==0 );
+ pBt->inStmt = 0;
+ return rc;
+}
+
+/*
+** Default key comparison function to be used if no comparison function
+** is specified on the sqlite3BtreeCursor() call.
+*/
+static int dfltCompare(
+ void *NotUsed, /* User data is not used */
+ int n1, const void *p1, /* First key to compare */
+ int n2, const void *p2 /* Second key to compare */
+){
+ int c;
+ c = memcmp(p1, p2, n1<n2 ? n1 : n2);
+ if( c==0 ){
+ c = n1 - n2;
+ }
+ return c;
+}
+
+/*
+** Create a new cursor for the BTree whose root is on the page
+** iTable. The act of acquiring a cursor gets a read lock on
+** the database file.
+**
+** If wrFlag==0, then the cursor can only be used for reading.
+** If wrFlag==1, then the cursor can be used for reading or for
+** writing if other conditions for writing are also met. These
+** are the conditions that must be met in order for writing to
+** be allowed:
+**
+** 1: The cursor must have been opened with wrFlag==1
+**
+** 2: No other cursors may be open with wrFlag==0 on the same table
+**
+** 3: The database must be writable (not on read-only media)
+**
+** 4: There must be an active transaction.
+**
+** Condition 2 warrants further discussion. If any cursor is opened
+** on a table with wrFlag==0, that prevents all other cursors from
+** writing to that table. This is a kind of "read-lock". When a cursor
+** is opened with wrFlag==0 it is guaranteed that the table will not
+** change as long as the cursor is open. This allows the cursor to
+** do a sequential scan of the table without having to worry about
+** entries being inserted or deleted during the scan. Cursors should
+** be opened with wrFlag==0 only if this read-lock property is needed.
+** That is to say, cursors should be opened with wrFlag==0 only if they
+** intend to use the sqlite3BtreeNext() system call. All other cursors
+** should be opened with wrFlag==1 even if they never really intend
+** to write.
+**
+** No checking is done to make sure that page iTable really is the
+** root page of a b-tree. If it is not, then the cursor acquired
+** will not work correctly.
+**
+** The comparison function must be logically the same for every cursor
+** on a particular table. Changing the comparison function will result
+** in incorrect operations. If the comparison function is NULL, a
+** default comparison function is used. The comparison function is
+** always ignored for INTKEY tables.
+*/
+int sqlite3BtreeCursor(
+ Btree *pBt, /* The btree */
+ int iTable, /* Root page of table to open */
+ int wrFlag, /* 1 to write. 0 read-only */
+ int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
+ void *pArg, /* First arg to xCompare() */
+ BtCursor **ppCur /* Write new cursor here */
+){
+ int rc;
+ BtCursor *pCur;
+
+ *ppCur = 0;
+ if( wrFlag ){
+ if( pBt->readOnly ){
+ return SQLITE_READONLY;
+ }
+ if( checkReadLocks(pBt, iTable, 0) ){
+ return SQLITE_LOCKED;
+ }
+ }
+ if( pBt->pPage1==0 ){
+ rc = lockBtreeWithRetry(pBt);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
+ pCur = sqliteMallocRaw( sizeof(*pCur) );
+ if( pCur==0 ){
+ rc = SQLITE_NOMEM;
+ goto create_cursor_exception;
+ }
+ pCur->pgnoRoot = (Pgno)iTable;
+ pCur->pPage = 0; /* For exit-handler, in case getAndInitPage() fails. */
+ if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){
+ rc = SQLITE_EMPTY;
+ goto create_cursor_exception;
+ }
+ rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0);
+ if( rc!=SQLITE_OK ){
+ goto create_cursor_exception;
+ }
+ pCur->xCompare = xCmp ? xCmp : dfltCompare;
+ pCur->pArg = pArg;
+ pCur->pBt = pBt;
+ pCur->wrFlag = wrFlag;
+ pCur->idx = 0;
+ memset(&pCur->info, 0, sizeof(pCur->info));
+ pCur->pNext = pBt->pCursor;
+ if( pCur->pNext ){
+ pCur->pNext->pPrev = pCur;
+ }
+ pCur->pPrev = 0;
+ pBt->pCursor = pCur;
+ pCur->isValid = 0;
+ *ppCur = pCur;
+ return SQLITE_OK;
+
+create_cursor_exception:
+ if( pCur ){
+ releasePage(pCur->pPage);
+ sqliteFree(pCur);
+ }
+ unlockBtreeIfUnused(pBt);
+ return rc;
+}
+
+#if 0 /* Not Used */
+/*
+** Change the value of the comparison function used by a cursor.
+*/
+void sqlite3BtreeSetCompare(
+ BtCursor *pCur, /* The cursor to whose comparison function is changed */
+ int(*xCmp)(void*,int,const void*,int,const void*), /* New comparison func */
+ void *pArg /* First argument to xCmp() */
+){
+ pCur->xCompare = xCmp ? xCmp : dfltCompare;
+ pCur->pArg = pArg;
+}
+#endif
+
+/*
+** Close a cursor. The read lock on the database file is released
+** when the last cursor is closed.
+*/
+int sqlite3BtreeCloseCursor(BtCursor *pCur){
+ Btree *pBt = pCur->pBt;
+ if( pCur->pPrev ){
+ pCur->pPrev->pNext = pCur->pNext;
+ }else{
+ pBt->pCursor = pCur->pNext;
+ }
+ if( pCur->pNext ){
+ pCur->pNext->pPrev = pCur->pPrev;
+ }
+ releasePage(pCur->pPage);
+ unlockBtreeIfUnused(pBt);
+ sqliteFree(pCur);
+ return SQLITE_OK;
+}
+
+/*
+** Make a temporary cursor by filling in the fields of pTempCur.
+** The temporary cursor is not on the cursor list for the Btree.
+*/
+static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
+ memcpy(pTempCur, pCur, sizeof(*pCur));
+ pTempCur->pNext = 0;
+ pTempCur->pPrev = 0;
+ if( pTempCur->pPage ){
+ sqlite3pager_ref(pTempCur->pPage->aData);
+ }
+}
+
+/*
+** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
+** function above.
+*/
+static void releaseTempCursor(BtCursor *pCur){
+ if( pCur->pPage ){
+ sqlite3pager_unref(pCur->pPage->aData);
+ }
+}
+
+/*
+** Make sure the BtCursor.info field of the given cursor is valid.
+** If it is not already valid, call parseCell() to fill it in.
+**
+** BtCursor.info is a cache of the information in the current cell.
+** Using this cache reduces the number of calls to parseCell().
+*/
+static void getCellInfo(BtCursor *pCur){
+ if( pCur->info.nSize==0 ){
+ parseCell(pCur->pPage, pCur->idx, &pCur->info);
+ }else{
+#ifndef NDEBUG
+ CellInfo info;
+ memset(&info, 0, sizeof(info));
+ parseCell(pCur->pPage, pCur->idx, &info);
+ assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
+#endif
+ }
+}
+
+/*
+** Set *pSize to the size of the buffer needed to hold the value of
+** the key for the current entry. If the cursor is not pointing
+** to a valid entry, *pSize is set to 0.
+**
+** For a table with the INTKEY flag set, this routine returns the key
+** itself, not the number of bytes in the key.
+*/
+int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
+ if( !pCur->isValid ){
+ *pSize = 0;
+ }else{
+ getCellInfo(pCur);
+ *pSize = pCur->info.nKey;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Set *pSize to the number of bytes of data in the entry the
+** cursor currently points to. Always return SQLITE_OK.
+** Failure is not possible. If the cursor is not currently
+** pointing to an entry (which can happen, for example, if
+** the database is empty) then *pSize is set to 0.
+*/
+int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
+ if( !pCur->isValid ){
+ /* Not pointing at a valid entry - set *pSize to 0. */
+ *pSize = 0;
+ }else{
+ getCellInfo(pCur);
+ *pSize = pCur->info.nData;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Read payload information from the entry that the pCur cursor is
+** pointing to. Begin reading the payload at "offset" and read
+** a total of "amt" bytes. Put the result in zBuf.
+**
+** This routine does not make a distinction between key and data.
+** It just reads bytes from the payload area. Data might appear
+** on the main page or be scattered out on multiple overflow pages.
+*/
+static int getPayload(
+ BtCursor *pCur, /* Cursor pointing to entry to read from */
+ int offset, /* Begin reading this far into payload */
+ int amt, /* Read this many bytes */
+ unsigned char *pBuf, /* Write the bytes into this buffer */
+ int skipKey /* offset begins at data if this is true */
+){
+ unsigned char *aPayload;
+ Pgno nextPage;
+ int rc;
+ MemPage *pPage;
+ Btree *pBt;
+ int ovflSize;
+ u32 nKey;
+
+ assert( pCur!=0 && pCur->pPage!=0 );
+ assert( pCur->isValid );
+ pBt = pCur->pBt;
+ pPage = pCur->pPage;
+ pageIntegrity(pPage);
+ assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
+ getCellInfo(pCur);
+ aPayload = pCur->info.pCell;
+ aPayload += pCur->info.nHeader;
+ if( pPage->intKey ){
+ nKey = 0;
+ }else{
+ nKey = pCur->info.nKey;
+ }
+ assert( offset>=0 );
+ if( skipKey ){
+ offset += nKey;
+ }
+ if( offset+amt > nKey+pCur->info.nData ){
+ return SQLITE_ERROR;
+ }
+ if( offset<pCur->info.nLocal ){
+ int a = amt;
+ if( a+offset>pCur->info.nLocal ){
+ a = pCur->info.nLocal - offset;
+ }
+ memcpy(pBuf, &aPayload[offset], a);
+ if( a==amt ){
+ return SQLITE_OK;
+ }
+ offset = 0;
+ pBuf += a;
+ amt -= a;
+ }else{
+ offset -= pCur->info.nLocal;
+ }
+ ovflSize = pBt->usableSize - 4;
+ if( amt>0 ){
+ nextPage = get4byte(&aPayload[pCur->info.nLocal]);
+ while( amt>0 && nextPage ){
+ rc = sqlite3pager_get(pBt->pPager, nextPage, (void**)&aPayload);
+ if( rc!=0 ){
+ return rc;
+ }
+ nextPage = get4byte(aPayload);
+ if( offset<ovflSize ){
+ int a = amt;
+ if( a + offset > ovflSize ){
+ a = ovflSize - offset;
+ }
+ memcpy(pBuf, &aPayload[offset+4], a);
+ offset = 0;
+ amt -= a;
+ pBuf += a;
+ }else{
+ offset -= ovflSize;
+ }
+ sqlite3pager_unref(aPayload);
+ }
+ }
+
+ if( amt>0 ){
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Read part of the key associated with cursor pCur. Exactly
+** "amt" bytes will be transfered into pBuf[]. The transfer
+** begins at "offset".
+**
+** Return SQLITE_OK on success or an error code if anything goes
+** wrong. An error is returned if "offset+amt" is larger than
+** the available payload.
+*/
+int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+ assert( pCur->isValid );
+ assert( pCur->pPage!=0 );
+ if( pCur->pPage->intKey ){
+ return SQLITE_CORRUPT;
+ }
+ assert( pCur->pPage->intKey==0 );
+ assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+ return getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
+}
+
+/*
+** Read part of the data associated with cursor pCur. Exactly
+** "amt" bytes will be transfered into pBuf[]. The transfer
+** begins at "offset".
+**
+** Return SQLITE_OK on success or an error code if anything goes
+** wrong. An error is returned if "offset+amt" is larger than
+** the available payload.
+*/
+int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+ assert( pCur->isValid );
+ assert( pCur->pPage!=0 );
+ assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+ return getPayload(pCur, offset, amt, pBuf, 1);
+}
+
+/*
+** Return a pointer to payload information from the entry that the
+** pCur cursor is pointing to. The pointer is to the beginning of
+** the key if skipKey==0 and it points to the beginning of data if
+** skipKey==1. The number of bytes of available key/data is written
+** into *pAmt. If *pAmt==0, then the value returned will not be
+** a valid pointer.
+**
+** This routine is an optimization. It is common for the entire key
+** and data to fit on the local page and for there to be no overflow
+** pages. When that is so, this routine can be used to access the
+** key and data without making a copy. If the key and/or data spills
+** onto overflow pages, then getPayload() must be used to reassembly
+** the key/data and copy it into a preallocated buffer.
+**
+** The pointer returned by this routine looks directly into the cached
+** page of the database. The data might change or move the next time
+** any btree routine is called.
+*/
+static const unsigned char *fetchPayload(
+ BtCursor *pCur, /* Cursor pointing to entry to read from */
+ int *pAmt, /* Write the number of available bytes here */
+ int skipKey /* read beginning at data if this is true */
+){
+ unsigned char *aPayload;
+ MemPage *pPage;
+ Btree *pBt;
+ u32 nKey;
+ int nLocal;
+
+ assert( pCur!=0 && pCur->pPage!=0 );
+ assert( pCur->isValid );
+ pBt = pCur->pBt;
+ pPage = pCur->pPage;
+ pageIntegrity(pPage);
+ assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
+ getCellInfo(pCur);
+ aPayload = pCur->info.pCell;
+ aPayload += pCur->info.nHeader;
+ if( pPage->intKey ){
+ nKey = 0;
+ }else{
+ nKey = pCur->info.nKey;
+ }
+ if( skipKey ){
+ aPayload += nKey;
+ nLocal = pCur->info.nLocal - nKey;
+ }else{
+ nLocal = pCur->info.nLocal;
+ if( nLocal>nKey ){
+ nLocal = nKey;
+ }
+ }
+ *pAmt = nLocal;
+ return aPayload;
+}
+
+
+/*
+** For the entry that cursor pCur is point to, return as
+** many bytes of the key or data as are available on the local
+** b-tree page. Write the number of available bytes into *pAmt.
+**
+** The pointer returned is ephemeral. The key/data may move
+** or be destroyed on the next call to any Btree routine.
+**
+** These routines is used to get quick access to key and data
+** in the common case where no overflow pages are used.
+*/
+const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
+ return (const void*)fetchPayload(pCur, pAmt, 0);
+}
+const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
+ return (const void*)fetchPayload(pCur, pAmt, 1);
+}
+
+
+/*
+** Move the cursor down to a new child page. The newPgno argument is the
+** page number of the child page to move to.
+*/
+static int moveToChild(BtCursor *pCur, u32 newPgno){
+ int rc;
+ MemPage *pNewPage;
+ MemPage *pOldPage;
+ Btree *pBt = pCur->pBt;
+
+ assert( pCur->isValid );
+ rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
+ if( rc ) return rc;
+ pageIntegrity(pNewPage);
+ pNewPage->idxParent = pCur->idx;
+ pOldPage = pCur->pPage;
+ pOldPage->idxShift = 0;
+ releasePage(pOldPage);
+ pCur->pPage = pNewPage;
+ pCur->idx = 0;
+ pCur->info.nSize = 0;
+ if( pNewPage->nCell<1 ){
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Return true if the page is the virtual root of its table.
+**
+** The virtual root page is the root page for most tables. But
+** for the table rooted on page 1, sometime the real root page
+** is empty except for the right-pointer. In such cases the
+** virtual root page is the page that the right-pointer of page
+** 1 is pointing to.
+*/
+static int isRootPage(MemPage *pPage){
+ MemPage *pParent = pPage->pParent;
+ if( pParent==0 ) return 1;
+ if( pParent->pgno>1 ) return 0;
+ if( get2byte(&pParent->aData[pParent->hdrOffset+3])==0 ) return 1;
+ return 0;
+}
+
+/*
+** Move the cursor up to the parent page.
+**
+** pCur->idx is set to the cell index that contains the pointer
+** to the page we are coming from. If we are coming from the
+** right-most child page then pCur->idx is set to one more than
+** the largest cell index.
+*/
+static void moveToParent(BtCursor *pCur){
+ Pgno oldPgno;
+ MemPage *pParent;
+ MemPage *pPage;
+ int idxParent;
+
+ assert( pCur->isValid );
+ pPage = pCur->pPage;
+ assert( pPage!=0 );
+ assert( !isRootPage(pPage) );
+ pageIntegrity(pPage);
+ pParent = pPage->pParent;
+ assert( pParent!=0 );
+ pageIntegrity(pParent);
+ idxParent = pPage->idxParent;
+ sqlite3pager_ref(pParent->aData);
+ oldPgno = pPage->pgno;
+ releasePage(pPage);
+ pCur->pPage = pParent;
+ pCur->info.nSize = 0;
+ assert( pParent->idxShift==0 );
+ pCur->idx = idxParent;
+}
+
+/*
+** Move the cursor to the root page
+*/
+static int moveToRoot(BtCursor *pCur){
+ MemPage *pRoot;
+ int rc;
+ Btree *pBt = pCur->pBt;
+
+ rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0);
+ if( rc ){
+ pCur->isValid = 0;
+ return rc;
+ }
+ releasePage(pCur->pPage);
+ pageIntegrity(pRoot);
+ pCur->pPage = pRoot;
+ pCur->idx = 0;
+ pCur->info.nSize = 0;
+ if( pRoot->nCell==0 && !pRoot->leaf ){
+ Pgno subpage;
+ assert( pRoot->pgno==1 );
+ subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
+ assert( subpage>0 );
+ pCur->isValid = 1;
+ rc = moveToChild(pCur, subpage);
+ }
+ pCur->isValid = pCur->pPage->nCell>0;
+ return rc;
+}
+
+/*
+** Move the cursor down to the left-most leaf entry beneath the
+** entry to which it is currently pointing.
+*/
+static int moveToLeftmost(BtCursor *pCur){
+ Pgno pgno;
+ int rc;
+ MemPage *pPage;
+
+ assert( pCur->isValid );
+ while( !(pPage = pCur->pPage)->leaf ){
+ assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
+ pgno = get4byte(findCell(pPage, pCur->idx));
+ rc = moveToChild(pCur, pgno);
+ if( rc ) return rc;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Move the cursor down to the right-most leaf entry beneath the
+** page to which it is currently pointing. Notice the difference
+** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
+** finds the left-most entry beneath the *entry* whereas moveToRightmost()
+** finds the right-most entry beneath the *page*.
+*/
+static int moveToRightmost(BtCursor *pCur){
+ Pgno pgno;
+ int rc;
+ MemPage *pPage;
+
+ assert( pCur->isValid );
+ while( !(pPage = pCur->pPage)->leaf ){
+ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ pCur->idx = pPage->nCell;
+ rc = moveToChild(pCur, pgno);
+ if( rc ) return rc;
+ }
+ pCur->idx = pPage->nCell - 1;
+ pCur->info.nSize = 0;
+ return SQLITE_OK;
+}
+
+/* Move the cursor to the first entry in the table. Return SQLITE_OK
+** on success. Set *pRes to 0 if the cursor actually points to something
+** or set *pRes to 1 if the table is empty.
+*/
+int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
+ int rc;
+ rc = moveToRoot(pCur);
+ if( rc ) return rc;
+ if( pCur->isValid==0 ){
+ assert( pCur->pPage->nCell==0 );
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ assert( pCur->pPage->nCell>0 );
+ *pRes = 0;
+ rc = moveToLeftmost(pCur);
+ return rc;
+}
+
+/* Move the cursor to the last entry in the table. Return SQLITE_OK
+** on success. Set *pRes to 0 if the cursor actually points to something
+** or set *pRes to 1 if the table is empty.
+*/
+int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
+ int rc;
+ rc = moveToRoot(pCur);
+ if( rc ) return rc;
+ if( pCur->isValid==0 ){
+ assert( pCur->pPage->nCell==0 );
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ assert( pCur->isValid );
+ *pRes = 0;
+ rc = moveToRightmost(pCur);
+ return rc;
+}
+
+/* Move the cursor so that it points to an entry near pKey/nKey.
+** Return a success code.
+**
+** For INTKEY tables, only the nKey parameter is used. pKey is
+** ignored. For other tables, nKey is the number of bytes of data
+** in nKey. The comparison function specified when the cursor was
+** created is used to compare keys.
+**
+** If an exact match is not found, then the cursor is always
+** left pointing at a leaf page which would hold the entry if it
+** were present. The cursor might point to an entry that comes
+** before or after the key.
+**
+** The result of comparing the key with the entry to which the
+** cursor is written to *pRes if pRes!=NULL. The meaning of
+** this value is as follows:
+**
+** *pRes<0 The cursor is left pointing at an entry that
+** is smaller than pKey or if the table is empty
+** and the cursor is therefore left point to nothing.
+**
+** *pRes==0 The cursor is left pointing at an entry that
+** exactly matches pKey.
+**
+** *pRes>0 The cursor is left pointing at an entry that
+** is larger than pKey.
+*/
+int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
+ int rc;
+ rc = moveToRoot(pCur);
+ if( rc ) return rc;
+ assert( pCur->pPage );
+ assert( pCur->pPage->isInit );
+ if( pCur->isValid==0 ){
+ *pRes = -1;
+ assert( pCur->pPage->nCell==0 );
+ return SQLITE_OK;
+ }
+ for(;;){
+ int lwr, upr;
+ Pgno chldPg;
+ MemPage *pPage = pCur->pPage;
+ int c = -1; /* pRes return if table is empty must be -1 */
+ lwr = 0;
+ upr = pPage->nCell-1;
+ if( !pPage->intKey && pKey==0 ){
+ return SQLITE_CORRUPT;
+ }
+ pageIntegrity(pPage);
+ while( lwr<=upr ){
+ void *pCellKey;
+ i64 nCellKey;
+ pCur->idx = (lwr+upr)/2;
+ pCur->info.nSize = 0;
+ sqlite3BtreeKeySize(pCur, &nCellKey);
+ if( pPage->intKey ){
+ if( nCellKey<nKey ){
+ c = -1;
+ }else if( nCellKey>nKey ){
+ c = +1;
+ }else{
+ c = 0;
+ }
+ }else{
+ int available;
+ pCellKey = (void *)fetchPayload(pCur, &available, 0);
+ if( available>=nCellKey ){
+ c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
+ }else{
+ pCellKey = sqliteMallocRaw( nCellKey );
+ if( pCellKey==0 ) return SQLITE_NOMEM;
+ rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
+ c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
+ sqliteFree(pCellKey);
+ if( rc ) return rc;
+ }
+ }
+ if( c==0 ){
+ if( pPage->leafData && !pPage->leaf ){
+ lwr = pCur->idx;
+ upr = lwr - 1;
+ break;
+ }else{
+ if( pRes ) *pRes = 0;
+ return SQLITE_OK;
+ }
+ }
+ if( c<0 ){
+ lwr = pCur->idx+1;
+ }else{
+ upr = pCur->idx-1;
+ }
+ }
+ assert( lwr==upr+1 );
+ assert( pPage->isInit );
+ if( pPage->leaf ){
+ chldPg = 0;
+ }else if( lwr>=pPage->nCell ){
+ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ }else{
+ chldPg = get4byte(findCell(pPage, lwr));
+ }
+ if( chldPg==0 ){
+ assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+ if( pRes ) *pRes = c;
+ return SQLITE_OK;
+ }
+ pCur->idx = lwr;
+ pCur->info.nSize = 0;
+ rc = moveToChild(pCur, chldPg);
+ if( rc ){
+ return rc;
+ }
+ }
+ /* NOT REACHED */
+}
+
+/*
+** Return TRUE if the cursor is not pointing at an entry of the table.
+**
+** TRUE will be returned after a call to sqlite3BtreeNext() moves
+** past the last entry in the table or sqlite3BtreePrev() moves past
+** the first entry. TRUE is also returned if the table is empty.
+*/
+int sqlite3BtreeEof(BtCursor *pCur){
+ return pCur->isValid==0;
+}
+
+/*
+** Advance the cursor to the next entry in the database. If
+** successful then set *pRes=0. If the cursor
+** was already pointing to the last entry in the database before
+** this routine was called, then set *pRes=1.
+*/
+int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
+ int rc;
+ MemPage *pPage = pCur->pPage;
+
+ assert( pRes!=0 );
+ if( pCur->isValid==0 ){
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ assert( pPage->isInit );
+ assert( pCur->idx<pPage->nCell );
+
+ pCur->idx++;
+ pCur->info.nSize = 0;
+ if( pCur->idx>=pPage->nCell ){
+ if( !pPage->leaf ){
+ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
+ if( rc ) return rc;
+ rc = moveToLeftmost(pCur);
+ *pRes = 0;
+ return rc;
+ }
+ do{
+ if( isRootPage(pPage) ){
+ *pRes = 1;
+ pCur->isValid = 0;
+ return SQLITE_OK;
+ }
+ moveToParent(pCur);
+ pPage = pCur->pPage;
+ }while( pCur->idx>=pPage->nCell );
+ *pRes = 0;
+ if( pPage->leafData ){
+ rc = sqlite3BtreeNext(pCur, pRes);
+ }else{
+ rc = SQLITE_OK;
+ }
+ return rc;
+ }
+ *pRes = 0;
+ if( pPage->leaf ){
+ return SQLITE_OK;
+ }
+ rc = moveToLeftmost(pCur);
+ return rc;
+}
+
+/*
+** Step the cursor to the back to the previous entry in the database. If
+** successful then set *pRes=0. If the cursor
+** was already pointing to the first entry in the database before
+** this routine was called, then set *pRes=1.
+*/
+int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
+ int rc;
+ Pgno pgno;
+ MemPage *pPage;
+ if( pCur->isValid==0 ){
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+
+ pPage = pCur->pPage;
+ assert( pPage->isInit );
+ assert( pCur->idx>=0 );
+ if( !pPage->leaf ){
+ pgno = get4byte( findCell(pPage, pCur->idx) );
+ rc = moveToChild(pCur, pgno);
+ if( rc ) return rc;
+ rc = moveToRightmost(pCur);
+ }else{
+ while( pCur->idx==0 ){
+ if( isRootPage(pPage) ){
+ pCur->isValid = 0;
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ moveToParent(pCur);
+ pPage = pCur->pPage;
+ }
+ pCur->idx--;
+ pCur->info.nSize = 0;
+ if( pPage->leafData && !pPage->leaf ){
+ rc = sqlite3BtreePrevious(pCur, pRes);
+ }else{
+ rc = SQLITE_OK;
+ }
+ }
+ *pRes = 0;
+ return rc;
+}
+
+/*
+** Allocate a new page from the database file.
+**
+** The new page is marked as dirty. (In other words, sqlite3pager_write()
+** has already been called on the new page.) The new page has also
+** been referenced and the calling routine is responsible for calling
+** sqlite3pager_unref() on the new page when it is done.
+**
+** SQLITE_OK is returned on success. Any other return value indicates
+** an error. *ppPage and *pPgno are undefined in the event of an error.
+** Do not invoke sqlite3pager_unref() on *ppPage if an error is returned.
+**
+** If the "nearby" parameter is not 0, then a (feeble) effort is made to
+** locate a page close to the page number "nearby". This can be used in an
+** attempt to keep related pages close to each other in the database file,
+** which in turn can make database access faster.
+**
+** If the "exact" parameter is not 0, and the page-number nearby exists
+** anywhere on the free-list, then it is guarenteed to be returned. This
+** is only used by auto-vacuum databases when allocating a new table.
+*/
+static int allocatePage(
+ Btree *pBt,
+ MemPage **ppPage,
+ Pgno *pPgno,
+ Pgno nearby,
+ u8 exact
+){
+ MemPage *pPage1;
+ int rc;
+ int n; /* Number of pages on the freelist */
+ int k; /* Number of leaves on the trunk of the freelist */
+
+ pPage1 = pBt->pPage1;
+ n = get4byte(&pPage1->aData[36]);
+ if( n>0 ){
+ /* There are pages on the freelist. Reuse one of those pages. */
+ MemPage *pTrunk = 0;
+ Pgno iTrunk;
+ MemPage *pPrevTrunk = 0;
+ u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
+
+ /* If the 'exact' parameter was true and a query of the pointer-map
+ ** shows that the page 'nearby' is somewhere on the free-list, then
+ ** the entire-list will be searched for that page.
+ */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( exact ){
+ u8 eType;
+ assert( nearby>0 );
+ assert( pBt->autoVacuum );
+ rc = ptrmapGet(pBt, nearby, &eType, 0);
+ if( rc ) return rc;
+ if( eType==PTRMAP_FREEPAGE ){
+ searchList = 1;
+ }
+ *pPgno = nearby;
+ }
+#endif
+
+ /* Decrement the free-list count by 1. Set iTrunk to the index of the
+ ** first free-list trunk page. iPrevTrunk is initially 1.
+ */
+ rc = sqlite3pager_write(pPage1->aData);
+ if( rc ) return rc;
+ put4byte(&pPage1->aData[36], n-1);
+
+ /* The code within this loop is run only once if the 'searchList' variable
+ ** is not true. Otherwise, it runs once for each trunk-page on the
+ ** free-list until the page 'nearby' is located.
+ */
+ do {
+ pPrevTrunk = pTrunk;
+ if( pPrevTrunk ){
+ iTrunk = get4byte(&pPrevTrunk->aData[0]);
+ }else{
+ iTrunk = get4byte(&pPage1->aData[32]);
+ }
+ rc = getPage(pBt, iTrunk, &pTrunk);
+ if( rc ){
+ releasePage(pPrevTrunk);
+ return rc;
+ }
+
+ /* TODO: This should move to after the loop? */
+ rc = sqlite3pager_write(pTrunk->aData);
+ if( rc ){
+ releasePage(pTrunk);
+ releasePage(pPrevTrunk);
+ return rc;
+ }
+
+ k = get4byte(&pTrunk->aData[4]);
+ if( k==0 && !searchList ){
+ /* The trunk has no leaves and the list is not being searched.
+ ** So extract the trunk page itself and use it as the newly
+ ** allocated page */
+ assert( pPrevTrunk==0 );
+ *pPgno = iTrunk;
+ memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
+ *ppPage = pTrunk;
+ pTrunk = 0;
+ TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
+ }else if( k>pBt->usableSize/4 - 8 ){
+ /* Value of k is out of range. Database corruption */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ }else if( searchList && nearby==iTrunk ){
+ /* The list is being searched and this trunk page is the page
+ ** to allocate, regardless of whether it has leaves.
+ */
+ assert( *pPgno==iTrunk );
+ *ppPage = pTrunk;
+ searchList = 0;
+ if( k==0 ){
+ if( !pPrevTrunk ){
+ memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
+ }else{
+ memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
+ }
+ }else{
+ /* The trunk page is required by the caller but it contains
+ ** pointers to free-list leaves. The first leaf becomes a trunk
+ ** page in this case.
+ */
+ MemPage *pNewTrunk;
+ Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
+ rc = getPage(pBt, iNewTrunk, &pNewTrunk);
+ if( rc!=SQLITE_OK ){
+ releasePage(pTrunk);
+ releasePage(pPrevTrunk);
+ return rc;
+ }
+ rc = sqlite3pager_write(pNewTrunk->aData);
+ if( rc!=SQLITE_OK ){
+ releasePage(pNewTrunk);
+ releasePage(pTrunk);
+ releasePage(pPrevTrunk);
+ return rc;
+ }
+ memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
+ put4byte(&pNewTrunk->aData[4], k-1);
+ memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
+ if( !pPrevTrunk ){
+ put4byte(&pPage1->aData[32], iNewTrunk);
+ }else{
+ put4byte(&pPrevTrunk->aData[0], iNewTrunk);
+ }
+ releasePage(pNewTrunk);
+ }
+ pTrunk = 0;
+ TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
+#endif
+ }else{
+ /* Extract a leaf from the trunk */
+ int closest;
+ Pgno iPage;
+ unsigned char *aData = pTrunk->aData;
+ if( nearby>0 ){
+ int i, dist;
+ closest = 0;
+ dist = get4byte(&aData[8]) - nearby;
+ if( dist<0 ) dist = -dist;
+ for(i=1; i<k; i++){
+ int d2 = get4byte(&aData[8+i*4]) - nearby;
+ if( d2<0 ) d2 = -d2;
+ if( d2<dist ){
+ closest = i;
+ dist = d2;
+ }
+ }
+ }else{
+ closest = 0;
+ }
+
+ iPage = get4byte(&aData[8+closest*4]);
+ if( !searchList || iPage==nearby ){
+ *pPgno = iPage;
+ if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){
+ /* Free page off the end of the file */
+ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
+ ": %d more free pages\n",
+ *pPgno, closest+1, k, pTrunk->pgno, n-1));
+ if( closest<k-1 ){
+ memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
+ }
+ put4byte(&aData[4], k-1);
+ rc = getPage(pBt, *pPgno, ppPage);
+ if( rc==SQLITE_OK ){
+ sqlite3pager_dont_rollback((*ppPage)->aData);
+ rc = sqlite3pager_write((*ppPage)->aData);
+ if( rc!=SQLITE_OK ){
+ releasePage(*ppPage);
+ }
+ }
+ searchList = 0;
+ }
+ }
+ releasePage(pPrevTrunk);
+ }while( searchList );
+ releasePage(pTrunk);
+ }else{
+ /* There are no pages on the freelist, so create a new page at the
+ ** end of the file */
+ *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1;
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){
+ /* If *pPgno refers to a pointer-map page, allocate two new pages
+ ** at the end of the file instead of one. The first allocated page
+ ** becomes a new pointer-map page, the second is used by the caller.
+ */
+ TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
+ assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+ (*pPgno)++;
+ }
+#endif
+
+ assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+ rc = getPage(pBt, *pPgno, ppPage);
+ if( rc ) return rc;
+ rc = sqlite3pager_write((*ppPage)->aData);
+ if( rc!=SQLITE_OK ){
+ releasePage(*ppPage);
+ }
+ TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
+ }
+
+ assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+ return rc;
+}
+
+/*
+** Add a page of the database file to the freelist.
+**
+** sqlite3pager_unref() is NOT called for pPage.
+*/
+static int freePage(MemPage *pPage){
+ Btree *pBt = pPage->pBt;
+ MemPage *pPage1 = pBt->pPage1;
+ int rc, n, k;
+
+ /* Prepare the page for freeing */
+ assert( pPage->pgno>1 );
+ pPage->isInit = 0;
+ releasePage(pPage->pParent);
+ pPage->pParent = 0;
+
+ /* Increment the free page count on pPage1 */
+ rc = sqlite3pager_write(pPage1->aData);
+ if( rc ) return rc;
+ n = get4byte(&pPage1->aData[36]);
+ put4byte(&pPage1->aData[36], n+1);
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* If the database supports auto-vacuum, write an entry in the pointer-map
+ ** to indicate that the page is free.
+ */
+ if( pBt->autoVacuum ){
+ rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0);
+ if( rc ) return rc;
+ }
+#endif
+
+ if( n==0 ){
+ /* This is the first free page */
+ rc = sqlite3pager_write(pPage->aData);
+ if( rc ) return rc;
+ memset(pPage->aData, 0, 8);
+ put4byte(&pPage1->aData[32], pPage->pgno);
+ TRACE(("FREE-PAGE: %d first\n", pPage->pgno));
+ }else{
+ /* Other free pages already exist. Retrive the first trunk page
+ ** of the freelist and find out how many leaves it has. */
+ MemPage *pTrunk;
+ rc = getPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk);
+ if( rc ) return rc;
+ k = get4byte(&pTrunk->aData[4]);
+ if( k>=pBt->usableSize/4 - 8 ){
+ /* The trunk is full. Turn the page being freed into a new
+ ** trunk page with no leaves. */
+ rc = sqlite3pager_write(pPage->aData);
+ if( rc ) return rc;
+ put4byte(pPage->aData, pTrunk->pgno);
+ put4byte(&pPage->aData[4], 0);
+ put4byte(&pPage1->aData[32], pPage->pgno);
+ TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
+ pPage->pgno, pTrunk->pgno));
+ }else{
+ /* Add the newly freed page as a leaf on the current trunk */
+ rc = sqlite3pager_write(pTrunk->aData);
+ if( rc ) return rc;
+ put4byte(&pTrunk->aData[4], k+1);
+ put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
+ sqlite3pager_dont_write(pBt->pPager, pPage->pgno);
+ TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
+ }
+ releasePage(pTrunk);
+ }
+ return rc;
+}
+
+/*
+** Free any overflow pages associated with the given Cell.
+*/
+static int clearCell(MemPage *pPage, unsigned char *pCell){
+ Btree *pBt = pPage->pBt;
+ CellInfo info;
+ Pgno ovflPgno;
+ int rc;
+
+ parseCellPtr(pPage, pCell, &info);
+ if( info.iOverflow==0 ){
+ return SQLITE_OK; /* No overflow pages. Return without doing anything */
+ }
+ ovflPgno = get4byte(&pCell[info.iOverflow]);
+ while( ovflPgno!=0 ){
+ MemPage *pOvfl;
+ if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){
+ return SQLITE_CORRUPT;
+ }
+ rc = getPage(pBt, ovflPgno, &pOvfl);
+ if( rc ) return rc;
+ ovflPgno = get4byte(pOvfl->aData);
+ rc = freePage(pOvfl);
+ sqlite3pager_unref(pOvfl->aData);
+ if( rc ) return rc;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Create the byte sequence used to represent a cell on page pPage
+** and write that byte sequence into pCell[]. Overflow pages are
+** allocated and filled in as necessary. The calling procedure
+** is responsible for making sure sufficient space has been allocated
+** for pCell[].
+**
+** Note that pCell does not necessary need to point to the pPage->aData
+** area. pCell might point to some temporary storage. The cell will
+** be constructed in this temporary area then copied into pPage->aData
+** later.
+*/
+static int fillInCell(
+ MemPage *pPage, /* The page that contains the cell */
+ unsigned char *pCell, /* Complete text of the cell */
+ const void *pKey, i64 nKey, /* The key */
+ const void *pData,int nData, /* The data */
+ int *pnSize /* Write cell size here */
+){
+ int nPayload;
+ const u8 *pSrc;
+ int nSrc, n, rc;
+ int spaceLeft;
+ MemPage *pOvfl = 0;
+ MemPage *pToRelease = 0;
+ unsigned char *pPrior;
+ unsigned char *pPayload;
+ Btree *pBt = pPage->pBt;
+ Pgno pgnoOvfl = 0;
+ int nHeader;
+ CellInfo info;
+
+ /* Fill in the header. */
+ nHeader = 0;
+ if( !pPage->leaf ){
+ nHeader += 4;
+ }
+ if( pPage->hasData ){
+ nHeader += putVarint(&pCell[nHeader], nData);
+ }else{
+ nData = 0;
+ }
+ nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
+ parseCellPtr(pPage, pCell, &info);
+ assert( info.nHeader==nHeader );
+ assert( info.nKey==nKey );
+ assert( info.nData==nData );
+
+ /* Fill in the payload */
+ nPayload = nData;
+ if( pPage->intKey ){
+ pSrc = pData;
+ nSrc = nData;
+ nData = 0;
+ }else{
+ nPayload += nKey;
+ pSrc = pKey;
+ nSrc = nKey;
+ }
+ *pnSize = info.nSize;
+ spaceLeft = info.nLocal;
+ pPayload = &pCell[nHeader];
+ pPrior = &pCell[info.iOverflow];
+
+ while( nPayload>0 ){
+ if( spaceLeft==0 ){
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
+#endif
+ rc = allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* If the database supports auto-vacuum, and the second or subsequent
+ ** overflow page is being allocated, add an entry to the pointer-map
+ ** for that page now. The entry for the first overflow page will be
+ ** added later, by the insertCell() routine.
+ */
+ if( pBt->autoVacuum && pgnoPtrmap!=0 && rc==SQLITE_OK ){
+ rc = ptrmapPut(pBt, pgnoOvfl, PTRMAP_OVERFLOW2, pgnoPtrmap);
+ }
+#endif
+ if( rc ){
+ releasePage(pToRelease);
+ /* clearCell(pPage, pCell); */
+ return rc;
+ }
+ put4byte(pPrior, pgnoOvfl);
+ releasePage(pToRelease);
+ pToRelease = pOvfl;
+ pPrior = pOvfl->aData;
+ put4byte(pPrior, 0);
+ pPayload = &pOvfl->aData[4];
+ spaceLeft = pBt->usableSize - 4;
+ }
+ n = nPayload;
+ if( n>spaceLeft ) n = spaceLeft;
+ if( n>nSrc ) n = nSrc;
+ memcpy(pPayload, pSrc, n);
+ nPayload -= n;
+ pPayload += n;
+ pSrc += n;
+ nSrc -= n;
+ spaceLeft -= n;
+ if( nSrc==0 ){
+ nSrc = nData;
+ pSrc = pData;
+ }
+ }
+ releasePage(pToRelease);
+ return SQLITE_OK;
+}
+
+/*
+** Change the MemPage.pParent pointer on the page whose number is
+** given in the second argument so that MemPage.pParent holds the
+** pointer in the third argument.
+*/
+static int reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){
+ MemPage *pThis;
+ unsigned char *aData;
+
+ if( pgno==0 ) return SQLITE_OK;
+ assert( pBt->pPager!=0 );
+ aData = sqlite3pager_lookup(pBt->pPager, pgno);
+ if( aData ){
+ pThis = (MemPage*)&aData[pBt->pageSize];
+ assert( pThis->aData==aData );
+ if( pThis->isInit ){
+ if( pThis->pParent!=pNewParent ){
+ if( pThis->pParent ) sqlite3pager_unref(pThis->pParent->aData);
+ pThis->pParent = pNewParent;
+ if( pNewParent ) sqlite3pager_ref(pNewParent->aData);
+ }
+ pThis->idxParent = idx;
+ }
+ sqlite3pager_unref(aData);
+ }
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno);
+ }
+#endif
+ return SQLITE_OK;
+}
+
+
+
+/*
+** Change the pParent pointer of all children of pPage to point back
+** to pPage.
+**
+** In other words, for every child of pPage, invoke reparentPage()
+** to make sure that each child knows that pPage is its parent.
+**
+** This routine gets called after you memcpy() one page into
+** another.
+*/
+static int reparentChildPages(MemPage *pPage){
+ int i;
+ Btree *pBt = pPage->pBt;
+ int rc = SQLITE_OK;
+
+ if( pPage->leaf ) return SQLITE_OK;
+
+ for(i=0; i<pPage->nCell; i++){
+ u8 *pCell = findCell(pPage, i);
+ if( !pPage->leaf ){
+ rc = reparentPage(pBt, get4byte(pCell), pPage, i);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ }
+ if( !pPage->leaf ){
+ rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]),
+ pPage, i);
+ pPage->idxShift = 0;
+ }
+ return rc;
+}
+
+/*
+** Remove the i-th cell from pPage. This routine effects pPage only.
+** The cell content is not freed or deallocated. It is assumed that
+** the cell content has been copied someplace else. This routine just
+** removes the reference to the cell from pPage.
+**
+** "sz" must be the number of bytes in the cell.
+*/
+static void dropCell(MemPage *pPage, int idx, int sz){
+ int i; /* Loop counter */
+ int pc; /* Offset to cell content of cell being deleted */
+ u8 *data; /* pPage->aData */
+ u8 *ptr; /* Used to move bytes around within data[] */
+
+ assert( idx>=0 && idx<pPage->nCell );
+ assert( sz==cellSize(pPage, idx) );
+ assert( sqlite3pager_iswriteable(pPage->aData) );
+ data = pPage->aData;
+ ptr = &data[pPage->cellOffset + 2*idx];
+ pc = get2byte(ptr);
+ assert( pc>10 && pc+sz<=pPage->pBt->usableSize );
+ freeSpace(pPage, pc, sz);
+ for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
+ ptr[0] = ptr[2];
+ ptr[1] = ptr[3];
+ }
+ pPage->nCell--;
+ put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
+ pPage->nFree += 2;
+ pPage->idxShift = 1;
+}
+
+/*
+** Insert a new cell on pPage at cell index "i". pCell points to the
+** content of the cell.
+**
+** If the cell content will fit on the page, then put it there. If it
+** will not fit, then make a copy of the cell content into pTemp if
+** pTemp is not null. Regardless of pTemp, allocate a new entry
+** in pPage->aOvfl[] and make it point to the cell content (either
+** in pTemp or the original pCell) and also record its index.
+** Allocating a new entry in pPage->aCell[] implies that
+** pPage->nOverflow is incremented.
+**
+** If nSkip is non-zero, then do not copy the first nSkip bytes of the
+** cell. The caller will overwrite them after this function returns. If
+** nSkip is non-zero, then pCell may not point to an invalid memory location
+** (but pCell+nSkip is always valid).
+*/
+static int insertCell(
+ MemPage *pPage, /* Page into which we are copying */
+ int i, /* New cell becomes the i-th cell of the page */
+ u8 *pCell, /* Content of the new cell */
+ int sz, /* Bytes of content in pCell */
+ u8 *pTemp, /* Temp storage space for pCell, if needed */
+ u8 nSkip /* Do not write the first nSkip bytes of the cell */
+){
+ int idx; /* Where to write new cell content in data[] */
+ int j; /* Loop counter */
+ int top; /* First byte of content for any cell in data[] */
+ int end; /* First byte past the last cell pointer in data[] */
+ int ins; /* Index in data[] where new cell pointer is inserted */
+ int hdr; /* Offset into data[] of the page header */
+ int cellOffset; /* Address of first cell pointer in data[] */
+ u8 *data; /* The content of the whole page */
+ u8 *ptr; /* Used for moving information around in data[] */
+
+ assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
+ assert( sz==cellSizePtr(pPage, pCell) );
+ assert( sqlite3pager_iswriteable(pPage->aData) );
+ if( pPage->nOverflow || sz+2>pPage->nFree ){
+ if( pTemp ){
+ memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
+ pCell = pTemp;
+ }
+ j = pPage->nOverflow++;
+ assert( j<sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0]) );
+ pPage->aOvfl[j].pCell = pCell;
+ pPage->aOvfl[j].idx = i;
+ pPage->nFree = 0;
+ }else{
+ data = pPage->aData;
+ hdr = pPage->hdrOffset;
+ top = get2byte(&data[hdr+5]);
+ cellOffset = pPage->cellOffset;
+ end = cellOffset + 2*pPage->nCell + 2;
+ ins = cellOffset + 2*i;
+ if( end > top - sz ){
+ int rc = defragmentPage(pPage);
+ if( rc!=SQLITE_OK ) return rc;
+ top = get2byte(&data[hdr+5]);
+ assert( end + sz <= top );
+ }
+ idx = allocateSpace(pPage, sz);
+ assert( idx>0 );
+ assert( end <= get2byte(&data[hdr+5]) );
+ pPage->nCell++;
+ pPage->nFree -= 2;
+ memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
+ for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){
+ ptr[0] = ptr[-2];
+ ptr[1] = ptr[-1];
+ }
+ put2byte(&data[ins], idx);
+ put2byte(&data[hdr+3], pPage->nCell);
+ pPage->idxShift = 1;
+ pageIntegrity(pPage);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pPage->pBt->autoVacuum ){
+ /* The cell may contain a pointer to an overflow page. If so, write
+ ** the entry for the overflow page into the pointer map.
+ */
+ CellInfo info;
+ parseCellPtr(pPage, pCell, &info);
+ if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
+ Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
+ int rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ }
+#endif
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Add a list of cells to a page. The page should be initially empty.
+** The cells are guaranteed to fit on the page.
+*/
+static void assemblePage(
+ MemPage *pPage, /* The page to be assemblied */
+ int nCell, /* The number of cells to add to this page */
+ u8 **apCell, /* Pointers to cell bodies */
+ int *aSize /* Sizes of the cells */
+){
+ int i; /* Loop counter */
+ int totalSize; /* Total size of all cells */
+ int hdr; /* Index of page header */
+ int cellptr; /* Address of next cell pointer */
+ int cellbody; /* Address of next cell body */
+ u8 *data; /* Data for the page */
+
+ assert( pPage->nOverflow==0 );
+ totalSize = 0;
+ for(i=0; i<nCell; i++){
+ totalSize += aSize[i];
+ }
+ assert( totalSize+2*nCell<=pPage->nFree );
+ assert( pPage->nCell==0 );
+ cellptr = pPage->cellOffset;
+ 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; i<nCell; i++){
+ put2byte(&data[cellptr], cellbody);
+ memcpy(&data[cellbody], apCell[i], aSize[i]);
+ cellptr += 2;
+ cellbody += aSize[i];
+ }
+ assert( cellbody==pPage->pBt->usableSize );
+ pPage->nCell = nCell;
+}
+
+/*
+** The following parameters determine how many adjacent pages get involved
+** in a balancing operation. NN is the number of neighbors on either side
+** of the page that participate in the balancing operation. NB is the
+** total number of pages that participate, including the target page and
+** NN neighbors on either side.
+**
+** The minimum value of NN is 1 (of course). Increasing NN above 1
+** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
+** in exchange for a larger degradation in INSERT and UPDATE performance.
+** The value of NN appears to give the best results overall.
+*/
+#define NN 1 /* Number of neighbors on either side of pPage */
+#define NB (NN*2+1) /* Total pages involved in the balance */
+
+/* Forward reference */
+static int balance(MemPage*, int);
+
+#ifndef SQLITE_OMIT_QUICKBALANCE
+/*
+** This version of balance() handles the common special case where
+** a new entry is being inserted on the extreme right-end of the
+** tree, in other words, when the new entry will become the largest
+** entry in the tree.
+**
+** Instead of trying balance the 3 right-most leaf pages, just add
+** a new page to the right-hand side and put the one new entry in
+** that page. This leaves the right side of the tree somewhat
+** unbalanced. But odds are that we will be inserting new entries
+** at the end soon afterwards so the nearly empty page will quickly
+** fill up. On average.
+**
+** pPage is the leaf page which is the right-most page in the tree.
+** pParent is its parent. pPage must have a single overflow entry
+** which is also the right-most entry on the page.
+*/
+static int balance_quick(MemPage *pPage, MemPage *pParent){
+ int rc;
+ MemPage *pNew;
+ Pgno pgnoNew;
+ u8 *pCell;
+ int szCell;
+ CellInfo info;
+ Btree *pBt = pPage->pBt;
+ int parentIdx = pParent->nCell; /* pParent new divider cell index */
+ int parentSize; /* Size of new divider cell */
+ u8 parentCell[64]; /* Space for the new divider cell */
+
+ /* Allocate a new page. Insert the overflow cell from pPage
+ ** into it. Then remove the overflow cell from pPage.
+ */
+ rc = allocatePage(pBt, &pNew, &pgnoNew, 0, 0);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ pCell = pPage->aOvfl[0].pCell;
+ szCell = cellSizePtr(pPage, pCell);
+ zeroPage(pNew, pPage->aData[0]);
+ assemblePage(pNew, 1, &pCell, &szCell);
+ pPage->nOverflow = 0;
+
+ /* Set the parent of the newly allocated page to pParent. */
+ pNew->pParent = pParent;
+ sqlite3pager_ref(pParent->aData);
+
+ /* pPage is currently the right-child of pParent. Change this
+ ** so that the right-child is the new page allocated above and
+ ** pPage is the next-to-right child.
+ */
+ assert( pPage->nCell>0 );
+ parseCellPtr(pPage, findCell(pPage, pPage->nCell-1), &info);
+ rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, &parentSize);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ assert( parentSize<64 );
+ rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
+ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* If this is an auto-vacuum database, update the pointer map
+ ** with entries for the new page, and any pointer from the
+ ** cell on the page to an overflow page.
+ */
+ if( pBt->autoVacuum ){
+ rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = ptrmapPutOvfl(pNew, 0);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
+#endif
+
+ /* Release the reference to the new page and balance the parent page,
+ ** in case the divider cell inserted caused it to become overfull.
+ */
+ releasePage(pNew);
+ return balance(pParent, 0);
+}
+#endif /* SQLITE_OMIT_QUICKBALANCE */
+
+/*
+** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
+** if the database supports auto-vacuum or not. Because it is used
+** within an expression that is an argument to another macro
+** (sqliteMallocRaw), it is not possible to use conditional compilation.
+** So, this macro is defined instead.
+*/
+#ifndef SQLITE_OMIT_AUTOVACUUM
+#define ISAUTOVACUUM (pBt->autoVacuum)
+#else
+#define ISAUTOVACUUM 0
+#endif
+
+/*
+** This routine redistributes Cells on pPage and up to NN*2 siblings
+** of pPage so that all pages have about the same amount of free space.
+** Usually NN siblings on either side of pPage is used in the balancing,
+** though more siblings might come from one side if pPage is the first
+** or last child of its parent. If pPage has fewer than 2*NN siblings
+** (something which can only happen if pPage is the root page or a
+** child of root) then all available siblings participate in the balancing.
+**
+** The number of siblings of pPage might be increased or decreased by one or
+** two in an effort to keep pages nearly full but not over full. The root page
+** is special and is allowed to be nearly empty. If pPage is
+** the root page, then the depth of the tree might be increased
+** or decreased by one, as necessary, to keep the root page from being
+** overfull or completely empty.
+**
+** Note that when this routine is called, some of the Cells on pPage
+** might not actually be stored in pPage->aData[]. This can happen
+** if the page is overfull. Part of the job of this routine is to
+** make sure all Cells for pPage once again fit in pPage->aData[].
+**
+** In the course of balancing the siblings of pPage, the parent of pPage
+** might become overfull or underfull. If that happens, then this routine
+** is called recursively on the parent.
+**
+** If this routine fails for any reason, it might leave the database
+** in a corrupted state. So if this routine fails, the database should
+** be rolled back.
+*/
+static int balance_nonroot(MemPage *pPage){
+ MemPage *pParent; /* The parent of pPage */
+ Btree *pBt; /* The whole database */
+ int nCell = 0; /* Number of cells in apCell[] */
+ int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
+ int nOld; /* Number of pages in apOld[] */
+ int nNew; /* Number of pages in apNew[] */
+ int nDiv; /* Number of cells in apDiv[] */
+ int i, j, k; /* Loop counters */
+ int idx; /* Index of pPage in pParent->aCell[] */
+ int nxDiv; /* Next divider slot in pParent->aCell[] */
+ int rc; /* The return code */
+ int leafCorrection; /* 4 if pPage is a leaf. 0 if not */
+ int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
+ int usableSpace; /* Bytes in pPage beyond the header */
+ int pageFlags; /* Value of pPage->aData[0] */
+ int subtotal; /* Subtotal of bytes in cells on one page */
+ int iSpace = 0; /* First unused byte of aSpace[] */
+ MemPage *apOld[NB]; /* pPage and up to two siblings */
+ Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */
+ MemPage *apCopy[NB]; /* Private copies of apOld[] pages */
+ MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */
+ Pgno pgnoNew[NB+2]; /* Page numbers for each page in apNew[] */
+ int idxDiv[NB]; /* Indices of divider cells in pParent */
+ u8 *apDiv[NB]; /* Divider cells in pParent */
+ int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */
+ int szNew[NB+2]; /* Combined size of cells place on i-th page */
+ u8 **apCell = 0; /* All cells begin balanced */
+ int *szCell; /* Local size of all cells in apCell[] */
+ u8 *aCopy[NB]; /* Space for holding data of apCopy[] */
+ u8 *aSpace; /* Space to hold copies of dividers cells */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ u8 *aFrom = 0;
+#endif
+
+ /*
+ ** Find the parent page.
+ */
+ assert( pPage->isInit );
+ assert( sqlite3pager_iswriteable(pPage->aData) );
+ pBt = pPage->pBt;
+ pParent = pPage->pParent;
+ sqlite3pager_write(pParent->aData);
+ assert( pParent );
+ TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
+
+#ifndef SQLITE_OMIT_QUICKBALANCE
+ /*
+ ** A special case: If a new entry has just been inserted into a
+ ** table (that is, a btree with integer keys and all data at the leaves)
+ ** an the new entry is the right-most entry in the tree (it has the
+ ** largest key) then use the special balance_quick() routine for
+ ** balancing. balance_quick() is much faster and results in a tighter
+ ** packing of data in the common case.
+ */
+ if( pPage->leaf &&
+ pPage->intKey &&
+ pPage->leafData &&
+ pPage->nOverflow==1 &&
+ pPage->aOvfl[0].idx==pPage->nCell &&
+ pPage->pParent->pgno!=1 &&
+ get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
+ ){
+ /*
+ ** TODO: Check the siblings to the left of pPage. It may be that
+ ** they are not full and no new page is required.
+ */
+ return balance_quick(pPage, pParent);
+ }
+#endif
+
+ /*
+ ** Find the cell in the parent page whose left child points back
+ ** to pPage. The "idx" variable is the index of that cell. If pPage
+ ** is the rightmost child of pParent then set idx to pParent->nCell
+ */
+ if( pParent->idxShift ){
+ Pgno pgno;
+ pgno = pPage->pgno;
+ assert( pgno==sqlite3pager_pagenumber(pPage->aData) );
+ for(idx=0; idx<pParent->nCell; idx++){
+ if( get4byte(findCell(pParent, idx))==pgno ){
+ break;
+ }
+ }
+ assert( idx<pParent->nCell
+ || get4byte(&pParent->aData[pParent->hdrOffset+8])==pgno );
+ }else{
+ idx = pPage->idxParent;
+ }
+
+ /*
+ ** Initialize variables so that it will be safe to jump
+ ** directly to balance_cleanup at any moment.
+ */
+ nOld = nNew = 0;
+ sqlite3pager_ref(pParent->aData);
+
+ /*
+ ** Find sibling pages to pPage and the cells in pParent that divide
+ ** the siblings. An attempt is made to find NN siblings on either
+ ** side of pPage. More siblings are taken from one side, however, if
+ ** pPage there are fewer than NN siblings on the other side. If pParent
+ ** has NB or fewer children then all children of pParent are taken.
+ */
+ nxDiv = idx - NN;
+ if( nxDiv + NB > pParent->nCell ){
+ nxDiv = pParent->nCell - NB + 1;
+ }
+ if( nxDiv<0 ){
+ nxDiv = 0;
+ }
+ nDiv = 0;
+ for(i=0, k=nxDiv; i<NB; i++, k++){
+ if( k<pParent->nCell ){
+ idxDiv[i] = k;
+ apDiv[i] = findCell(pParent, k);
+ nDiv++;
+ assert( !pParent->leaf );
+ pgnoOld[i] = get4byte(apDiv[i]);
+ }else if( k==pParent->nCell ){
+ pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]);
+ }else{
+ break;
+ }
+ rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent);
+ if( rc ) goto balance_cleanup;
+ apOld[i]->idxParent = k;
+ apCopy[i] = 0;
+ assert( i==nOld );
+ nOld++;
+ nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
+ }
+
+ /* Make nMaxCells a multiple of 2 in order to preserve 8-byte
+ ** alignment */
+ nMaxCells = (nMaxCells + 1)&~1;
+
+ /*
+ ** Allocate space for memory structures
+ */
+ apCell = sqliteMallocRaw(
+ nMaxCells*sizeof(u8*) /* apCell */
+ + nMaxCells*sizeof(int) /* szCell */
+ + ROUND8(sizeof(MemPage))*NB /* aCopy */
+ + pBt->pageSize*(5+NB) /* aSpace */
+ + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */
+ );
+ if( apCell==0 ){
+ rc = SQLITE_NOMEM;
+ goto balance_cleanup;
+ }
+ szCell = (int*)&apCell[nMaxCells];
+ aCopy[0] = (u8*)&szCell[nMaxCells];
+ assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
+ for(i=1; i<NB; i++){
+ aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
+ assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
+ }
+ aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
+ assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ aFrom = &aSpace[5*pBt->pageSize];
+ }
+#endif
+
+ /*
+ ** Make copies of the content of pPage and its siblings into aOld[].
+ ** The rest of this function will use data from the copies rather
+ ** that the original pages since the original pages will be in the
+ ** process of being overwritten.
+ */
+ for(i=0; i<nOld; i++){
+ MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->pageSize];
+ p->aData = &((u8*)p)[-pBt->pageSize];
+ memcpy(p->aData, apOld[i]->aData, pBt->pageSize + sizeof(MemPage));
+ /* The memcpy() above changes the value of p->aData so we have to
+ ** set it again. */
+ p->aData = &((u8*)p)[-pBt->pageSize];
+ }
+
+ /*
+ ** Load pointers to all cells on sibling pages and the divider cells
+ ** into the local apCell[] array. Make copies of the divider cells
+ ** into space obtained form aSpace[] and remove the the divider Cells
+ ** from pParent.
+ **
+ ** If the siblings are on leaf pages, then the child pointers of the
+ ** divider cells are stripped from the cells before they are copied
+ ** into aSpace[]. In this way, all cells in apCell[] are without
+ ** child pointers. If siblings are not leaves, then all cell in
+ ** apCell[] include child pointers. Either way, all cells in apCell[]
+ ** are alike.
+ **
+ ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
+ ** leafData: 1 if pPage holds key+data and pParent holds only keys.
+ */
+ nCell = 0;
+ leafCorrection = pPage->leaf*4;
+ leafData = pPage->leafData && pPage->leaf;
+ for(i=0; i<nOld; i++){
+ MemPage *pOld = apCopy[i];
+ int limit = pOld->nCell+pOld->nOverflow;
+ for(j=0; j<limit; j++){
+ assert( nCell<nMaxCells );
+ apCell[nCell] = findOverflowCell(pOld, j);
+ szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ int a;
+ aFrom[nCell] = i;
+ for(a=0; a<pOld->nOverflow; a++){
+ if( pOld->aOvfl[a].pCell==apCell[nCell] ){
+ aFrom[nCell] = 0xFF;
+ break;
+ }
+ }
+ }
+#endif
+ nCell++;
+ }
+ if( i<nOld-1 ){
+ int sz = cellSizePtr(pParent, apDiv[i]);
+ if( leafData ){
+ /* With the LEAFDATA flag, pParent cells hold only INTKEYs that
+ ** are duplicates of keys on the child pages. We need to remove
+ ** the divider cells from pParent, but the dividers cells are not
+ ** added to apCell[] because they are duplicates of child cells.
+ */
+ dropCell(pParent, nxDiv, sz);
+ }else{
+ u8 *pTemp;
+ assert( nCell<nMaxCells );
+ szCell[nCell] = sz;
+ pTemp = &aSpace[iSpace];
+ iSpace += sz;
+ assert( iSpace<=pBt->pageSize*5 );
+ memcpy(pTemp, apDiv[i], sz);
+ apCell[nCell] = pTemp+leafCorrection;
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ aFrom[nCell] = 0xFF;
+ }
+#endif
+ dropCell(pParent, nxDiv, sz);
+ szCell[nCell] -= leafCorrection;
+ assert( get4byte(pTemp)==pgnoOld[i] );
+ if( !pOld->leaf ){
+ assert( leafCorrection==0 );
+ /* The right pointer of the child page pOld becomes the left
+ ** pointer of the divider cell */
+ memcpy(apCell[nCell], &pOld->aData[pOld->hdrOffset+8], 4);
+ }else{
+ assert( leafCorrection==4 );
+ }
+ nCell++;
+ }
+ }
+ }
+
+ /*
+ ** Figure out the number of pages needed to hold all nCell cells.
+ ** Store this number in "k". Also compute szNew[] which is the total
+ ** size of all cells on the i-th page and cntNew[] which is the index
+ ** in apCell[] of the cell that divides page i from page i+1.
+ ** cntNew[k] should equal nCell.
+ **
+ ** Values computed by this block:
+ **
+ ** k: The total number of sibling pages
+ ** szNew[i]: Spaced used on the i-th sibling page.
+ ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to
+ ** the right of the i-th sibling page.
+ ** usableSpace: Number of bytes of space available on each sibling.
+ **
+ */
+ usableSpace = pBt->usableSize - 12 + leafCorrection;
+ for(subtotal=k=i=0; i<nCell; i++){
+ assert( i<nMaxCells );
+ subtotal += szCell[i] + 2;
+ if( subtotal > usableSpace ){
+ szNew[k] = subtotal - szCell[i];
+ cntNew[k] = i;
+ if( leafData ){ i--; }
+ subtotal = 0;
+ k++;
+ }
+ }
+ szNew[k] = subtotal;
+ cntNew[k] = nCell;
+ k++;
+
+ /*
+ ** The packing computed by the previous block is biased toward the siblings
+ ** on the left side. The left siblings are always nearly full, while the
+ ** right-most sibling might be nearly empty. This block of code attempts
+ ** to adjust the packing of siblings to get a better balance.
+ **
+ ** This adjustment is more than an optimization. The packing above might
+ ** be so out of balance as to be illegal. For example, the right-most
+ ** sibling might be completely empty. This adjustment is not optional.
+ */
+ for(i=k-1; i>0; i--){
+ int szRight = szNew[i]; /* Size of sibling on the right */
+ int szLeft = szNew[i-1]; /* Size of sibling on the left */
+ int r; /* Index of right-most cell in left sibling */
+ int d; /* Index of first cell to the left of right sibling */
+
+ r = cntNew[i-1] - 1;
+ d = r + 1 - leafData;
+ assert( d<nMaxCells );
+ assert( r<nMaxCells );
+ while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
+ szRight += szCell[d] + 2;
+ szLeft -= szCell[r] + 2;
+ cntNew[i-1]--;
+ r = cntNew[i-1] - 1;
+ d = r + 1 - leafData;
+ }
+ szNew[i] = szRight;
+ szNew[i-1] = szLeft;
+ }
+ assert( cntNew[0]>0 );
+
+ /*
+ ** Allocate k new pages. Reuse old pages where possible.
+ */
+ assert( pPage->pgno>1 );
+ pageFlags = pPage->aData[0];
+ for(i=0; i<k; i++){
+ MemPage *pNew;
+ if( i<nOld ){
+ pNew = apNew[i] = apOld[i];
+ pgnoNew[i] = pgnoOld[i];
+ apOld[i] = 0;
+ rc = sqlite3pager_write(pNew->aData);
+ if( rc ) goto balance_cleanup;
+ }else{
+ rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
+ if( rc ) goto balance_cleanup;
+ apNew[i] = pNew;
+ }
+ nNew++;
+ zeroPage(pNew, pageFlags);
+ }
+
+ /* Free any old pages that were not reused as new pages.
+ */
+ while( i<nOld ){
+ rc = freePage(apOld[i]);
+ if( rc ) goto balance_cleanup;
+ releasePage(apOld[i]);
+ apOld[i] = 0;
+ i++;
+ }
+
+ /*
+ ** Put the new pages in accending order. This helps to
+ ** keep entries in the disk file in order so that a scan
+ ** of the table is a linear scan through the file. That
+ ** in turn helps the operating system to deliver pages
+ ** from the disk more rapidly.
+ **
+ ** An O(n^2) insertion sort algorithm is used, but since
+ ** n is never more than NB (a small constant), that should
+ ** not be a problem.
+ **
+ ** When NB==3, this one optimization makes the database
+ ** about 25% faster for large insertions and deletions.
+ */
+ for(i=0; i<k-1; i++){
+ int minV = pgnoNew[i];
+ int minI = i;
+ for(j=i+1; j<k; j++){
+ if( pgnoNew[j]<(unsigned)minV ){
+ minI = j;
+ minV = pgnoNew[j];
+ }
+ }
+ if( minI>i ){
+ int t;
+ MemPage *pT;
+ t = pgnoNew[i];
+ pT = apNew[i];
+ pgnoNew[i] = pgnoNew[minI];
+ apNew[i] = apNew[minI];
+ pgnoNew[minI] = t;
+ apNew[minI] = pT;
+ }
+ }
+ TRACE(("BALANCE: old: %d %d %d new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
+ pgnoOld[0],
+ nOld>=2 ? pgnoOld[1] : 0,
+ nOld>=3 ? pgnoOld[2] : 0,
+ pgnoNew[0], szNew[0],
+ nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0,
+ nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0,
+ nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0,
+ nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0));
+
+ /*
+ ** Evenly distribute the data in apCell[] across the new pages.
+ ** Insert divider cells into pParent as necessary.
+ */
+ j = 0;
+ for(i=0; i<nNew; i++){
+ /* Assemble the new sibling page. */
+ MemPage *pNew = apNew[i];
+ assert( j<nMaxCells );
+ assert( pNew->pgno==pgnoNew[i] );
+ assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
+ assert( pNew->nCell>0 );
+ assert( pNew->nOverflow==0 );
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* If this is an auto-vacuum database, update the pointer map entries
+ ** that point to the siblings that were rearranged. These can be: left
+ ** children of cells, the right-child of the page, or overflow pages
+ ** pointed to by cells.
+ */
+ if( pBt->autoVacuum ){
+ for(k=j; k<cntNew[i]; k++){
+ assert( k<nMaxCells );
+ if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
+ rc = ptrmapPutOvfl(pNew, k-j);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
+ }
+ }
+ }
+ }
+#endif
+
+ j = cntNew[i];
+
+ /* If the sibling page assembled above was not the right-most sibling,
+ ** insert a divider cell into the parent page.
+ */
+ if( i<nNew-1 && j<nCell ){
+ u8 *pCell;
+ u8 *pTemp;
+ int sz;
+
+ assert( j<nMaxCells );
+ pCell = apCell[j];
+ sz = szCell[j] + leafCorrection;
+ if( !pNew->leaf ){
+ memcpy(&pNew->aData[8], pCell, 4);
+ pTemp = 0;
+ }else if( leafData ){
+ /* If the tree is a leaf-data tree, and the siblings are leaves,
+ ** then there is no divider cell in apCell[]. Instead, the divider
+ ** cell consists of the integer key for the right-most cell of
+ ** the sibling-page assembled above only.
+ */
+ CellInfo info;
+ j--;
+ parseCellPtr(pNew, apCell[j], &info);
+ pCell = &aSpace[iSpace];
+ fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz);
+ iSpace += sz;
+ assert( iSpace<=pBt->pageSize*5 );
+ pTemp = 0;
+ }else{
+ pCell -= 4;
+ pTemp = &aSpace[iSpace];
+ iSpace += sz;
+ assert( iSpace<=pBt->pageSize*5 );
+ }
+ rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
+ if( rc!=SQLITE_OK ) goto balance_cleanup;
+ put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* If this is an auto-vacuum database, and not a leaf-data tree,
+ ** then update the pointer map with an entry for the overflow page
+ ** that the cell just inserted points to (if any).
+ */
+ if( pBt->autoVacuum && !leafData ){
+ rc = ptrmapPutOvfl(pParent, nxDiv);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
+ }
+ }
+#endif
+ j++;
+ nxDiv++;
+ }
+ }
+ assert( j==nCell );
+ if( (pageFlags & PTF_LEAF)==0 ){
+ memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4);
+ }
+ if( nxDiv==pParent->nCell+pParent->nOverflow ){
+ /* Right-most sibling is the right-most child of pParent */
+ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]);
+ }else{
+ /* Right-most sibling is the left child of the first entry in pParent
+ ** past the right-most divider entry */
+ put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]);
+ }
+
+ /*
+ ** Reparent children of all cells.
+ */
+ for(i=0; i<nNew; i++){
+ rc = reparentChildPages(apNew[i]);
+ if( rc!=SQLITE_OK ) goto balance_cleanup;
+ }
+ rc = reparentChildPages(pParent);
+ if( rc!=SQLITE_OK ) goto balance_cleanup;
+
+ /*
+ ** Balance the parent page. Note that the current page (pPage) might
+ ** have been added to the freelist so it might no longer be initialized.
+ ** But the parent page will always be initialized.
+ */
+ assert( pParent->isInit );
+ /* assert( pPage->isInit ); // No! pPage might have been added to freelist */
+ /* pageIntegrity(pPage); // No! pPage might have been added to freelist */
+ rc = balance(pParent, 0);
+
+ /*
+ ** Cleanup before returning.
+ */
+balance_cleanup:
+ sqliteFree(apCell);
+ for(i=0; i<nOld; i++){
+ releasePage(apOld[i]);
+ }
+ for(i=0; i<nNew; i++){
+ releasePage(apNew[i]);
+ }
+ releasePage(pParent);
+ TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
+ pPage->pgno, nOld, nNew, nCell));
+ return rc;
+}
+
+/*
+** This routine is called for the root page of a btree when the root
+** page contains no cells. This is an opportunity to make the tree
+** shallower by one level.
+*/
+static int balance_shallower(MemPage *pPage){
+ MemPage *pChild; /* The only child page of pPage */
+ Pgno pgnoChild; /* Page number for pChild */
+ int rc = SQLITE_OK; /* Return code from subprocedures */
+ Btree *pBt; /* The main BTree structure */
+ int mxCellPerPage; /* Maximum number of cells per page */
+ u8 **apCell; /* All cells from pages being balanced */
+ int *szCell; /* Local size of all cells */
+
+ assert( pPage->pParent==0 );
+ assert( pPage->nCell==0 );
+ pBt = pPage->pBt;
+ mxCellPerPage = MX_CELL(pBt);
+ apCell = sqliteMallocRaw( mxCellPerPage*(sizeof(u8*)+sizeof(int)) );
+ if( apCell==0 ) return SQLITE_NOMEM;
+ szCell = (int*)&apCell[mxCellPerPage];
+ if( pPage->leaf ){
+ /* The table is completely empty */
+ TRACE(("BALANCE: empty table %d\n", pPage->pgno));
+ }else{
+ /* The root page is empty but has one child. Transfer the
+ ** information from that one child into the root page if it
+ ** will fit. This reduces the depth of the tree by one.
+ **
+ ** If the root page is page 1, it has less space available than
+ ** its child (due to the 100 byte header that occurs at the beginning
+ ** of the database fle), so it might not be able to hold all of the
+ ** information currently contained in the child. If this is the
+ ** case, then do not do the transfer. Leave page 1 empty except
+ ** for the right-pointer to the child page. The child page becomes
+ ** the virtual root of the tree.
+ */
+ pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ assert( pgnoChild>0 );
+ assert( pgnoChild<=sqlite3pager_pagecount(pPage->pBt->pPager) );
+ rc = getPage(pPage->pBt, pgnoChild, &pChild);
+ if( rc ) goto end_shallow_balance;
+ if( pPage->pgno==1 ){
+ rc = initPage(pChild, pPage);
+ if( rc ) goto end_shallow_balance;
+ assert( pChild->nOverflow==0 );
+ if( pChild->nFree>=100 ){
+ /* The child information will fit on the root page, so do the
+ ** copy */
+ int i;
+ zeroPage(pPage, pChild->aData[0]);
+ for(i=0; i<pChild->nCell; i++){
+ apCell[i] = findCell(pChild,i);
+ szCell[i] = cellSizePtr(pChild, apCell[i]);
+ }
+ assemblePage(pPage, pChild->nCell, apCell, szCell);
+ /* Copy the right-pointer of the child to the parent. */
+ put4byte(&pPage->aData[pPage->hdrOffset+8],
+ get4byte(&pChild->aData[pChild->hdrOffset+8]));
+ freePage(pChild);
+ TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno));
+ }else{
+ /* The child has more information that will fit on the root.
+ ** The tree is already balanced. Do nothing. */
+ TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno));
+ }
+ }else{
+ memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize);
+ pPage->isInit = 0;
+ pPage->pParent = 0;
+ rc = initPage(pPage, 0);
+ assert( rc==SQLITE_OK );
+ freePage(pChild);
+ TRACE(("BALANCE: transfer child %d into root %d\n",
+ pChild->pgno, pPage->pgno));
+ }
+ rc = reparentChildPages(pPage);
+ assert( pPage->nOverflow==0 );
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ int i;
+ for(i=0; i<pPage->nCell; i++){
+ rc = ptrmapPutOvfl(pPage, i);
+ if( rc!=SQLITE_OK ){
+ goto end_shallow_balance;
+ }
+ }
+ }
+#endif
+ if( rc!=SQLITE_OK ) goto end_shallow_balance;
+ releasePage(pChild);
+ }
+end_shallow_balance:
+ sqliteFree(apCell);
+ return rc;
+}
+
+
+/*
+** The root page is overfull
+**
+** When this happens, Create a new child page and copy the
+** contents of the root into the child. Then make the root
+** page an empty page with rightChild pointing to the new
+** child. Finally, call balance_internal() on the new child
+** to cause it to split.
+*/
+static int balance_deeper(MemPage *pPage){
+ int rc; /* Return value from subprocedures */
+ MemPage *pChild; /* Pointer to a new child page */
+ Pgno pgnoChild; /* Page number of the new child page */
+ Btree *pBt; /* The BTree */
+ int usableSize; /* Total usable size of a page */
+ u8 *data; /* Content of the parent page */
+ u8 *cdata; /* Content of the child page */
+ int hdr; /* Offset to page header in parent */
+ int brk; /* Offset to content of first cell in parent */
+
+ assert( pPage->pParent==0 );
+ assert( pPage->nOverflow>0 );
+ pBt = pPage->pBt;
+ rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
+ if( rc ) return rc;
+ assert( sqlite3pager_iswriteable(pChild->aData) );
+ usableSize = pBt->usableSize;
+ data = pPage->aData;
+ hdr = pPage->hdrOffset;
+ brk = get2byte(&data[hdr+5]);
+ cdata = pChild->aData;
+ memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
+ memcpy(&cdata[brk], &data[brk], usableSize-brk);
+ assert( pChild->isInit==0 );
+ rc = initPage(pChild, pPage);
+ if( rc ) goto balancedeeper_out;
+ memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
+ pChild->nOverflow = pPage->nOverflow;
+ if( pChild->nOverflow ){
+ pChild->nFree = 0;
+ }
+ assert( pChild->nCell==pPage->nCell );
+ zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
+ put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
+ TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ int i;
+ rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
+ if( rc ) goto balancedeeper_out;
+ for(i=0; i<pChild->nCell; i++){
+ rc = ptrmapPutOvfl(pChild, i);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
+ }
+#endif
+ rc = balance_nonroot(pChild);
+
+balancedeeper_out:
+ releasePage(pChild);
+ return rc;
+}
+
+/*
+** Decide if the page pPage needs to be balanced. If balancing is
+** required, call the appropriate balancing routine.
+*/
+static int balance(MemPage *pPage, int insert){
+ int rc = SQLITE_OK;
+ if( pPage->pParent==0 ){
+ if( pPage->nOverflow>0 ){
+ rc = balance_deeper(pPage);
+ }
+ if( rc==SQLITE_OK && pPage->nCell==0 ){
+ rc = balance_shallower(pPage);
+ }
+ }else{
+ if( pPage->nOverflow>0 ||
+ (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
+ rc = balance_nonroot(pPage);
+ }
+ }
+ return rc;
+}
+
+/*
+** This routine checks all cursors that point to table pgnoRoot.
+** If any of those cursors other than pExclude were opened with
+** wrFlag==0 then this routine returns SQLITE_LOCKED. If all
+** cursors that point to pgnoRoot were opened with wrFlag==1
+** then this routine returns SQLITE_OK.
+**
+** In addition to checking for read-locks (where a read-lock
+** means a cursor opened with wrFlag==0) this routine also moves
+** all cursors other than pExclude so that they are pointing to the
+** first Cell on root page. This is necessary because an insert
+** or delete might change the number of cells on a page or delete
+** a page entirely and we do not want to leave any cursors
+** pointing to non-existant pages or cells.
+*/
+static int checkReadLocks(Btree *pBt, Pgno pgnoRoot, BtCursor *pExclude){
+ BtCursor *p;
+ for(p=pBt->pCursor; p; p=p->pNext){
+ if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue;
+ if( p->wrFlag==0 ) return SQLITE_LOCKED;
+ if( p->pPage->pgno!=p->pgnoRoot ){
+ moveToRoot(p);
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Insert a new record into the BTree. The key is given by (pKey,nKey)
+** and the data is given by (pData,nData). The cursor is used only to
+** define what table the record should be inserted into. The cursor
+** is left pointing at a random location.
+**
+** For an INTKEY table, only the nKey value of the key is used. pKey is
+** ignored. For a ZERODATA table, the pData and nData are both ignored.
+*/
+int sqlite3BtreeInsert(
+ BtCursor *pCur, /* Insert data into the table of this cursor */
+ const void *pKey, i64 nKey, /* The key of the new record */
+ const void *pData, int nData /* The data of the new record */
+){
+ int rc;
+ int loc;
+ int szNew;
+ MemPage *pPage;
+ Btree *pBt = pCur->pBt;
+ unsigned char *oldCell;
+ unsigned char *newCell = 0;
+
+ if( pBt->inTrans!=TRANS_WRITE ){
+ /* Must start a transaction before doing an insert */
+ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
+ }
+ assert( !pBt->readOnly );
+ if( !pCur->wrFlag ){
+ return SQLITE_PERM; /* Cursor not open for writing */
+ }
+ if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
+ return SQLITE_LOCKED; /* The table pCur points to has a read lock */
+ }
+ rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc);
+ if( rc ) return rc;
+ pPage = pCur->pPage;
+ assert( pPage->intKey || nKey>=0 );
+ assert( pPage->leaf || !pPage->leafData );
+ TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
+ pCur->pgnoRoot, nKey, nData, pPage->pgno,
+ loc==0 ? "overwrite" : "new entry"));
+ assert( pPage->isInit );
+ rc = sqlite3pager_write(pPage->aData);
+ if( rc ) return rc;
+ newCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
+ if( newCell==0 ) return SQLITE_NOMEM;
+ rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, &szNew);
+ if( rc ) goto end_insert;
+ assert( szNew==cellSizePtr(pPage, newCell) );
+ assert( szNew<=MX_CELL_SIZE(pBt) );
+ if( loc==0 && pCur->isValid ){
+ int szOld;
+ assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
+ oldCell = findCell(pPage, pCur->idx);
+ if( !pPage->leaf ){
+ memcpy(newCell, oldCell, 4);
+ }
+ szOld = cellSizePtr(pPage, oldCell);
+ rc = clearCell(pPage, oldCell);
+ if( rc ) goto end_insert;
+ dropCell(pPage, pCur->idx, szOld);
+ }else if( loc<0 && pPage->nCell>0 ){
+ assert( pPage->leaf );
+ pCur->idx++;
+ pCur->info.nSize = 0;
+ }else{
+ assert( pPage->leaf );
+ }
+ rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
+ if( rc!=SQLITE_OK ) goto end_insert;
+ rc = balance(pPage, 1);
+ /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
+ /* fflush(stdout); */
+ if( rc==SQLITE_OK ){
+ moveToRoot(pCur);
+ }
+end_insert:
+ sqliteFree(newCell);
+ return rc;
+}
+
+/*
+** Delete the entry that the cursor is pointing to. The cursor
+** is left pointing at a random location.
+*/
+int sqlite3BtreeDelete(BtCursor *pCur){
+ MemPage *pPage = pCur->pPage;
+ unsigned char *pCell;
+ int rc;
+ Pgno pgnoChild = 0;
+ Btree *pBt = pCur->pBt;
+
+ assert( pPage->isInit );
+ if( pBt->inTrans!=TRANS_WRITE ){
+ /* Must start a transaction before doing a delete */
+ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
+ }
+ assert( !pBt->readOnly );
+ if( pCur->idx >= pPage->nCell ){
+ return SQLITE_ERROR; /* The cursor is not pointing to anything */
+ }
+ if( !pCur->wrFlag ){
+ return SQLITE_PERM; /* Did not open this cursor for writing */
+ }
+ if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
+ return SQLITE_LOCKED; /* The table pCur points to has a read lock */
+ }
+ rc = sqlite3pager_write(pPage->aData);
+ if( rc ) return rc;
+
+ /* Locate the cell within it's page and leave pCell pointing to the
+ ** data. The clearCell() call frees any overflow pages associated with the
+ ** cell. The cell itself is still intact.
+ */
+ pCell = findCell(pPage, pCur->idx);
+ if( !pPage->leaf ){
+ pgnoChild = get4byte(pCell);
+ }
+ rc = clearCell(pPage, pCell);
+ if( rc ) return rc;
+
+ if( !pPage->leaf ){
+ /*
+ ** The entry we are about to delete is not a leaf so if we do not
+ ** do something we will leave a hole on an internal page.
+ ** We have to fill the hole by moving in a cell from a leaf. The
+ ** next Cell after the one to be deleted is guaranteed to exist and
+ ** to be a leaf so we can use it.
+ */
+ BtCursor leafCur;
+ unsigned char *pNext;
+ int szNext;
+ int notUsed;
+ unsigned char *tempCell = 0;
+ assert( !pPage->leafData );
+ getTempCursor(pCur, &leafCur);
+ rc = sqlite3BtreeNext(&leafCur, &notUsed);
+ if( rc!=SQLITE_OK ){
+ if( rc!=SQLITE_NOMEM ){
+ rc = SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3pager_write(leafCur.pPage->aData);
+ }
+ if( rc==SQLITE_OK ){
+ TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
+ pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
+ dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
+ pNext = findCell(leafCur.pPage, leafCur.idx);
+ szNext = cellSizePtr(leafCur.pPage, pNext);
+ assert( MX_CELL_SIZE(pBt)>=szNext+4 );
+ tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
+ if( tempCell==0 ){
+ rc = SQLITE_NOMEM;
+ }
+ }
+ if( rc==SQLITE_OK ){
+ rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0);
+ }
+ if( rc==SQLITE_OK ){
+ put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild);
+ rc = balance(pPage, 0);
+ }
+ if( rc==SQLITE_OK ){
+ dropCell(leafCur.pPage, leafCur.idx, szNext);
+ rc = balance(leafCur.pPage, 0);
+ }
+ sqliteFree(tempCell);
+ releaseTempCursor(&leafCur);
+ }else{
+ TRACE(("DELETE: table=%d delete from leaf %d\n",
+ pCur->pgnoRoot, pPage->pgno));
+ dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
+ rc = balance(pPage, 0);
+ }
+ if( rc==SQLITE_OK ){
+ moveToRoot(pCur);
+ }
+ return rc;
+}
+
+/*
+** Create a new BTree table. Write into *piTable the page
+** number for the root page of the new table.
+**
+** The type of type is determined by the flags parameter. Only the
+** following values of flags are currently in use. Other values for
+** flags might not work:
+**
+** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys
+** BTREE_ZERODATA Used for SQL indices
+*/
+int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
+ MemPage *pRoot;
+ Pgno pgnoRoot;
+ int rc;
+ if( pBt->inTrans!=TRANS_WRITE ){
+ /* Must start a transaction first */
+ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
+ }
+ assert( !pBt->readOnly );
+
+ /* It is illegal to create a table if any cursors are open on the
+ ** database. This is because in auto-vacuum mode the backend may
+ ** need to move a database page to make room for the new root-page.
+ ** If an open cursor was using the page a problem would occur.
+ */
+ if( pBt->pCursor ){
+ return SQLITE_LOCKED;
+ }
+
+#ifdef SQLITE_OMIT_AUTOVACUUM
+ rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
+ if( rc ) return rc;
+#else
+ if( pBt->autoVacuum ){
+ Pgno pgnoMove; /* Move a page here to make room for the root-page */
+ MemPage *pPageMove; /* The page to move to. */
+
+ /* Read the value of meta[3] from the database to determine where the
+ ** root page of the new table should go. meta[3] is the largest root-page
+ ** created so far, so the new root-page is (meta[3]+1).
+ */
+ rc = sqlite3BtreeGetMeta(pBt, 4, &pgnoRoot);
+ if( rc!=SQLITE_OK ) return rc;
+ pgnoRoot++;
+
+ /* The new root-page may not be allocated on a pointer-map page, or the
+ ** PENDING_BYTE page.
+ */
+ if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) ||
+ pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
+ pgnoRoot++;
+ }
+ assert( pgnoRoot>=3 );
+
+ /* Allocate a page. The page that currently resides at pgnoRoot will
+ ** be moved to the allocated page (unless the allocated page happens
+ ** to reside at pgnoRoot).
+ */
+ rc = allocatePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ if( pgnoMove!=pgnoRoot ){
+ u8 eType;
+ Pgno iPtrPage;
+
+ releasePage(pPageMove);
+ rc = getPage(pBt, pgnoRoot, &pRoot);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
+ if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
+ releasePage(pRoot);
+ return rc;
+ }
+ assert( eType!=PTRMAP_ROOTPAGE );
+ assert( eType!=PTRMAP_FREEPAGE );
+ rc = sqlite3pager_write(pRoot->aData);
+ if( rc!=SQLITE_OK ){
+ releasePage(pRoot);
+ return rc;
+ }
+ rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
+ releasePage(pRoot);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = getPage(pBt, pgnoRoot, &pRoot);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = sqlite3pager_write(pRoot->aData);
+ if( rc!=SQLITE_OK ){
+ releasePage(pRoot);
+ return rc;
+ }
+ }else{
+ pRoot = pPageMove;
+ }
+
+ /* Update the pointer-map and meta-data with the new root-page number. */
+ rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
+ if( rc ){
+ releasePage(pRoot);
+ return rc;
+ }
+ rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot);
+ if( rc ){
+ releasePage(pRoot);
+ return rc;
+ }
+
+ }else{
+ rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
+ if( rc ) return rc;
+ }
+#endif
+ assert( sqlite3pager_iswriteable(pRoot->aData) );
+ zeroPage(pRoot, flags | PTF_LEAF);
+ sqlite3pager_unref(pRoot->aData);
+ *piTable = (int)pgnoRoot;
+ return SQLITE_OK;
+}
+
+/*
+** Erase the given database page and all its children. Return
+** the page to the freelist.
+*/
+static int clearDatabasePage(
+ Btree *pBt, /* The BTree that contains the table */
+ Pgno pgno, /* Page number to clear */
+ MemPage *pParent, /* Parent page. NULL for the root */
+ int freePageFlag /* Deallocate page if true */
+){
+ MemPage *pPage = 0;
+ int rc;
+ unsigned char *pCell;
+ int i;
+
+ if( pgno>sqlite3pager_pagecount(pBt->pPager) ){
+ return SQLITE_CORRUPT;
+ }
+
+ rc = getAndInitPage(pBt, pgno, &pPage, pParent);
+ if( rc ) goto cleardatabasepage_out;
+ rc = sqlite3pager_write(pPage->aData);
+ if( rc ) goto cleardatabasepage_out;
+ for(i=0; i<pPage->nCell; i++){
+ pCell = findCell(pPage, i);
+ if( !pPage->leaf ){
+ rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
+ if( rc ) goto cleardatabasepage_out;
+ }
+ rc = clearCell(pPage, pCell);
+ if( rc ) goto cleardatabasepage_out;
+ }
+ if( !pPage->leaf ){
+ rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1);
+ if( rc ) goto cleardatabasepage_out;
+ }
+ if( freePageFlag ){
+ rc = freePage(pPage);
+ }else{
+ zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
+ }
+
+cleardatabasepage_out:
+ releasePage(pPage);
+ return rc;
+}
+
+/*
+** Delete all information from a single table in the database. iTable is
+** the page number of the root of the table. After this routine returns,
+** the root page is empty, but still exists.
+**
+** This routine will fail with SQLITE_LOCKED if there are any open
+** read cursors on the table. Open write cursors are moved to the
+** root of the table.
+*/
+int sqlite3BtreeClearTable(Btree *pBt, int iTable){
+ int rc;
+ BtCursor *pCur;
+ if( pBt->inTrans!=TRANS_WRITE ){
+ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
+ }
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ if( pCur->pgnoRoot==(Pgno)iTable ){
+ if( pCur->wrFlag==0 ) return SQLITE_LOCKED;
+ moveToRoot(pCur);
+ }
+ }
+ rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0);
+ if( rc ){
+ sqlite3BtreeRollback(pBt);
+ }
+ return rc;
+}
+
+/*
+** Erase all information in a table and add the root of the table to
+** the freelist. Except, the root of the principle table (the one on
+** page 1) is never added to the freelist.
+**
+** This routine will fail with SQLITE_LOCKED if there are any open
+** cursors on the table.
+**
+** If AUTOVACUUM is enabled and the page at iTable is not the last
+** root page in the database file, then the last root page
+** in the database file is moved into the slot formerly occupied by
+** iTable and that last slot formerly occupied by the last root page
+** is added to the freelist instead of iTable. In this say, all
+** root pages are kept at the beginning of the database file, which
+** is necessary for AUTOVACUUM to work right. *piMoved is set to the
+** page number that used to be the last root page in the file before
+** the move. If no page gets moved, *piMoved is set to 0.
+** The last root page is recorded in meta[3] and the value of
+** meta[3] is updated by this procedure.
+*/
+int sqlite3BtreeDropTable(Btree *pBt, int iTable, int *piMoved){
+ int rc;
+ MemPage *pPage = 0;
+
+ if( pBt->inTrans!=TRANS_WRITE ){
+ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
+ }
+
+ /* It is illegal to drop a table if any cursors are open on the
+ ** database. This is because in auto-vacuum mode the backend may
+ ** need to move another root-page to fill a gap left by the deleted
+ ** root page. If an open cursor was using this page a problem would
+ ** occur.
+ */
+ if( pBt->pCursor ){
+ return SQLITE_LOCKED;
+ }
+
+ rc = getPage(pBt, (Pgno)iTable, &pPage);
+ if( rc ) return rc;
+ rc = sqlite3BtreeClearTable(pBt, iTable);
+ if( rc ){
+ releasePage(pPage);
+ return rc;
+ }
+
+ *piMoved = 0;
+
+ if( iTable>1 ){
+#ifdef SQLITE_OMIT_AUTOVACUUM
+ rc = freePage(pPage);
+ releasePage(pPage);
+#else
+ if( pBt->autoVacuum ){
+ Pgno maxRootPgno;
+ rc = sqlite3BtreeGetMeta(pBt, 4, &maxRootPgno);
+ if( rc!=SQLITE_OK ){
+ releasePage(pPage);
+ return rc;
+ }
+
+ if( iTable==maxRootPgno ){
+ /* If the table being dropped is the table with the largest root-page
+ ** number in the database, put the root page on the free list.
+ */
+ rc = freePage(pPage);
+ releasePage(pPage);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }else{
+ /* The table being dropped does not have the largest root-page
+ ** number in the database. So move the page that does into the
+ ** gap left by the deleted root-page.
+ */
+ MemPage *pMove;
+ releasePage(pPage);
+ rc = getPage(pBt, maxRootPgno, &pMove);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable);
+ releasePage(pMove);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = getPage(pBt, maxRootPgno, &pMove);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = freePage(pMove);
+ releasePage(pMove);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ *piMoved = maxRootPgno;
+ }
+
+ /* Set the new 'max-root-page' value in the database header. This
+ ** is the old value less one, less one more if that happens to
+ ** be a root-page number, less one again if that is the
+ ** PENDING_BYTE_PAGE.
+ */
+ maxRootPgno--;
+ if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
+ maxRootPgno--;
+ }
+ if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){
+ maxRootPgno--;
+ }
+ assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
+
+ rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno);
+ }else{
+ rc = freePage(pPage);
+ releasePage(pPage);
+ }
+#endif
+ }else{
+ /* If sqlite3BtreeDropTable was called on page 1. */
+ zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
+ releasePage(pPage);
+ }
+ return rc;
+}
+
+
+/*
+** Read the meta-information out of a database file. Meta[0]
+** is the number of free pages currently in the database. Meta[1]
+** through meta[15] are available for use by higher layers. Meta[0]
+** is read-only, the others are read/write.
+**
+** The schema layer numbers meta values differently. At the schema
+** layer (and the SetCookie and ReadCookie opcodes) the number of
+** free pages is not visible. So Cookie[0] is the same as Meta[1].
+*/
+int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){
+ int rc;
+ unsigned char *pP1;
+
+ assert( idx>=0 && idx<=15 );
+ rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);
+ if( rc ) return rc;
+ *pMeta = get4byte(&pP1[36 + idx*4]);
+ sqlite3pager_unref(pP1);
+
+ /* If autovacuumed is disabled in this build but we are trying to
+ ** access an autovacuumed database, then make the database readonly.
+ */
+#ifdef SQLITE_OMIT_AUTOVACUUM
+ if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
+#endif
+
+ return SQLITE_OK;
+}
+
+/*
+** Write meta-information back into the database. Meta[0] is
+** read-only and may not be written.
+*/
+int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){
+ unsigned char *pP1;
+ int rc;
+ assert( idx>=1 && idx<=15 );
+ if( pBt->inTrans!=TRANS_WRITE ){
+ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
+ }
+ assert( pBt->pPage1!=0 );
+ pP1 = pBt->pPage1->aData;
+ rc = sqlite3pager_write(pP1);
+ if( rc ) return rc;
+ put4byte(&pP1[36 + idx*4], iMeta);
+ return SQLITE_OK;
+}
+
+/*
+** Return the flag byte at the beginning of the page that the cursor
+** is currently pointing to.
+*/
+int sqlite3BtreeFlags(BtCursor *pCur){
+ MemPage *pPage = pCur->pPage;
+ return pPage ? pPage->aData[pPage->hdrOffset] : 0;
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** Print a disassembly of the given page on standard output. This routine
+** is used for debugging and testing only.
+*/
+static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
+ int rc;
+ MemPage *pPage;
+ int i, j, c;
+ int nFree;
+ u16 idx;
+ int hdr;
+ int nCell;
+ int isInit;
+ unsigned char *data;
+ char range[20];
+ unsigned char payload[20];
+
+ rc = getPage(pBt, (Pgno)pgno, &pPage);
+ isInit = pPage->isInit;
+ if( pPage->isInit==0 ){
+ initPage(pPage, pParent);
+ }
+ if( rc ){
+ return rc;
+ }
+ hdr = pPage->hdrOffset;
+ data = pPage->aData;
+ c = data[hdr];
+ pPage->intKey = (c & (PTF_INTKEY|PTF_LEAFDATA))!=0;
+ pPage->zeroData = (c & PTF_ZERODATA)!=0;
+ pPage->leafData = (c & PTF_LEAFDATA)!=0;
+ pPage->leaf = (c & PTF_LEAF)!=0;
+ pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
+ nCell = get2byte(&data[hdr+3]);
+ sqlite3DebugPrintf("PAGE %d: flags=0x%02x frag=%d parent=%d\n", pgno,
+ data[hdr], data[hdr+7],
+ (pPage->isInit && pPage->pParent) ? pPage->pParent->pgno : 0);
+ assert( hdr == (pgno==1 ? 100 : 0) );
+ idx = hdr + 12 - pPage->leaf*4;
+ for(i=0; i<nCell; i++){
+ CellInfo info;
+ Pgno child;
+ unsigned char *pCell;
+ int sz;
+ int addr;
+
+ addr = get2byte(&data[idx + 2*i]);
+ pCell = &data[addr];
+ parseCellPtr(pPage, pCell, &info);
+ sz = info.nSize;
+ sprintf(range,"%d..%d", addr, addr+sz-1);
+ if( pPage->leaf ){
+ child = 0;
+ }else{
+ child = get4byte(pCell);
+ }
+ sz = info.nData;
+ if( !pPage->intKey ) sz += info.nKey;
+ if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
+ memcpy(payload, &pCell[info.nHeader], sz);
+ for(j=0; j<sz; j++){
+ if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
+ }
+ payload[sz] = 0;
+ sqlite3DebugPrintf(
+ "cell %2d: i=%-10s chld=%-4d nk=%-4lld nd=%-4d payload=%s\n",
+ i, range, child, info.nKey, info.nData, payload
+ );
+ }
+ if( !pPage->leaf ){
+ sqlite3DebugPrintf("right_child: %d\n", get4byte(&data[hdr+8]));
+ }
+ nFree = 0;
+ i = 0;
+ idx = get2byte(&data[hdr+1]);
+ while( idx>0 && idx<pPage->pBt->usableSize ){
+ int sz = get2byte(&data[idx+2]);
+ sprintf(range,"%d..%d", idx, idx+sz-1);
+ nFree += sz;
+ sqlite3DebugPrintf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
+ i, range, sz, nFree);
+ idx = get2byte(&data[idx]);
+ i++;
+ }
+ if( idx!=0 ){
+ sqlite3DebugPrintf("ERROR: next freeblock index out of range: %d\n", idx);
+ }
+ if( recursive && !pPage->leaf ){
+ for(i=0; i<nCell; i++){
+ unsigned char *pCell = findCell(pPage, i);
+ btreePageDump(pBt, get4byte(pCell), 1, pPage);
+ idx = get2byte(pCell);
+ }
+ btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
+ }
+ pPage->isInit = isInit;
+ sqlite3pager_unref(data);
+ fflush(stdout);
+ return SQLITE_OK;
+}
+int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
+ return btreePageDump(pBt, pgno, recursive, 0);
+}
+#endif
+
+#ifdef SQLITE_TEST
+/*
+** Fill aResult[] with information about the entry and page that the
+** cursor is pointing to.
+**
+** aResult[0] = The page number
+** aResult[1] = The entry number
+** aResult[2] = Total number of entries on this page
+** aResult[3] = Cell size (local payload + header)
+** aResult[4] = Number of free bytes on this page
+** aResult[5] = Number of free blocks on the page
+** aResult[6] = Total payload size (local + overflow)
+** aResult[7] = Header size in bytes
+** aResult[8] = Local payload size
+** aResult[9] = Parent page number
+**
+** This routine is used for testing and debugging only.
+*/
+int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
+ int cnt, idx;
+ MemPage *pPage = pCur->pPage;
+ BtCursor tmpCur;
+
+ pageIntegrity(pPage);
+ assert( pPage->isInit );
+ getTempCursor(pCur, &tmpCur);
+ while( upCnt-- ){
+ moveToParent(&tmpCur);
+ }
+ pPage = tmpCur.pPage;
+ pageIntegrity(pPage);
+ aResult[0] = sqlite3pager_pagenumber(pPage->aData);
+ assert( aResult[0]==pPage->pgno );
+ aResult[1] = tmpCur.idx;
+ aResult[2] = pPage->nCell;
+ if( tmpCur.idx>=0 && tmpCur.idx<pPage->nCell ){
+ getCellInfo(&tmpCur);
+ aResult[3] = tmpCur.info.nSize;
+ aResult[6] = tmpCur.info.nData;
+ aResult[7] = tmpCur.info.nHeader;
+ aResult[8] = tmpCur.info.nLocal;
+ }else{
+ aResult[3] = 0;
+ aResult[6] = 0;
+ aResult[7] = 0;
+ aResult[8] = 0;
+ }
+ aResult[4] = pPage->nFree;
+ cnt = 0;
+ idx = get2byte(&pPage->aData[pPage->hdrOffset+1]);
+ while( idx>0 && idx<pPage->pBt->usableSize ){
+ cnt++;
+ idx = get2byte(&pPage->aData[idx]);
+ }
+ aResult[5] = cnt;
+ if( pPage->pParent==0 || isRootPage(pPage) ){
+ aResult[9] = 0;
+ }else{
+ aResult[9] = pPage->pParent->pgno;
+ }
+ releaseTempCursor(&tmpCur);
+ return SQLITE_OK;
+}
+#endif
+
+/*
+** Return the pager associated with a BTree. This routine is used for
+** testing and debugging only.
+*/
+Pager *sqlite3BtreePager(Btree *pBt){
+ return pBt->pPager;
+}
+
+/*
+** This structure is passed around through all the sanity checking routines
+** in order to keep track of some global state information.
+*/
+typedef struct IntegrityCk IntegrityCk;
+struct IntegrityCk {
+ Btree *pBt; /* The tree being checked out */
+ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
+ int nPage; /* Number of pages in the database */
+ int *anRef; /* Number of times each page is referenced */
+ char *zErrMsg; /* An error message. NULL of no errors seen. */
+};
+
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
+/*
+** Append a message to the error message string.
+*/
+static void checkAppendMsg(
+ IntegrityCk *pCheck,
+ char *zMsg1,
+ const char *zFormat,
+ ...
+){
+ va_list ap;
+ char *zMsg2;
+ va_start(ap, zFormat);
+ zMsg2 = sqlite3VMPrintf(zFormat, ap);
+ va_end(ap);
+ if( zMsg1==0 ) zMsg1 = "";
+ if( pCheck->zErrMsg ){
+ char *zOld = pCheck->zErrMsg;
+ pCheck->zErrMsg = 0;
+ sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
+ sqliteFree(zOld);
+ }else{
+ sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
+ }
+ sqliteFree(zMsg2);
+}
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
+/*
+** Add 1 to the reference count for page iPage. If this is the second
+** reference to the page, add an error message to pCheck->zErrMsg.
+** Return 1 if there are 2 ore more references to the page and 0 if
+** if this is the first reference to the page.
+**
+** Also check that the page number is in bounds.
+*/
+static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){
+ if( iPage==0 ) return 1;
+ if( iPage>pCheck->nPage || iPage<0 ){
+ checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
+ return 1;
+ }
+ if( pCheck->anRef[iPage]==1 ){
+ checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
+ return 1;
+ }
+ return (pCheck->anRef[iPage]++)>1;
+}
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+/*
+** Check that the entry in the pointer-map for page iChild maps to
+** page iParent, pointer type ptrType. If not, append an error message
+** to pCheck.
+*/
+static void checkPtrmap(
+ IntegrityCk *pCheck, /* Integrity check context */
+ Pgno iChild, /* Child page number */
+ u8 eType, /* Expected pointer map type */
+ Pgno iParent, /* Expected pointer map parent page number */
+ char *zContext /* Context description (used for error msg) */
+){
+ int rc;
+ u8 ePtrmapType;
+ Pgno iPtrmapParent;
+
+ rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
+ if( rc!=SQLITE_OK ){
+ checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
+ return;
+ }
+
+ if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
+ checkAppendMsg(pCheck, zContext,
+ "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
+ iChild, eType, iParent, ePtrmapType, iPtrmapParent);
+ }
+}
+#endif
+
+/*
+** Check the integrity of the freelist or of an overflow page list.
+** Verify that the number of pages on the list is N.
+*/
+static void checkList(
+ IntegrityCk *pCheck, /* Integrity checking context */
+ int isFreeList, /* True for a freelist. False for overflow page list */
+ int iPage, /* Page number for first page in the list */
+ int N, /* Expected number of pages in the list */
+ char *zContext /* Context for error messages */
+){
+ int i;
+ int expected = N;
+ int iFirst = iPage;
+ while( N-- > 0 ){
+ unsigned char *pOvfl;
+ if( iPage<1 ){
+ checkAppendMsg(pCheck, zContext,
+ "%d of %d pages missing from overflow list starting at %d",
+ N+1, expected, iFirst);
+ break;
+ }
+ if( checkRef(pCheck, iPage, zContext) ) break;
+ if( sqlite3pager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
+ checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
+ break;
+ }
+ if( isFreeList ){
+ int n = get4byte(&pOvfl[4]);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pCheck->pBt->autoVacuum ){
+ checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
+ }
+#endif
+ if( n>pCheck->pBt->usableSize/4-8 ){
+ checkAppendMsg(pCheck, zContext,
+ "freelist leaf count too big on page %d", iPage);
+ N--;
+ }else{
+ for(i=0; i<n; i++){
+ Pgno iFreePage = get4byte(&pOvfl[8+i*4]);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pCheck->pBt->autoVacuum ){
+ checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
+ }
+#endif
+ checkRef(pCheck, iFreePage, zContext);
+ }
+ N -= n;
+ }
+ }
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ else{
+ /* If this database supports auto-vacuum and iPage is not the last
+ ** page in this overflow list, check that the pointer-map entry for
+ ** the following page matches iPage.
+ */
+ if( pCheck->pBt->autoVacuum && N>0 ){
+ i = get4byte(pOvfl);
+ checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
+ }
+ }
+#endif
+ iPage = get4byte(pOvfl);
+ sqlite3pager_unref(pOvfl);
+ }
+}
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
+/*
+** Do various sanity checks on a single page of a tree. Return
+** the tree depth. Root pages return 0. Parents of root pages
+** return 1, and so forth.
+**
+** These checks are done:
+**
+** 1. Make sure that cells and freeblocks do not overlap
+** but combine to completely cover the page.
+** NO 2. Make sure cell keys are in order.
+** NO 3. Make sure no key is less than or equal to zLowerBound.
+** NO 4. Make sure no key is greater than or equal to zUpperBound.
+** 5. Check the integrity of overflow pages.
+** 6. Recursively call checkTreePage on all children.
+** 7. Verify that the depth of all children is the same.
+** 8. Make sure this page is at least 33% full or else it is
+** the root of the tree.
+*/
+static int checkTreePage(
+ IntegrityCk *pCheck, /* Context for the sanity check */
+ int iPage, /* Page number of the page to check */
+ MemPage *pParent, /* Parent page */
+ char *zParentContext, /* Parent context */
+ char *zLowerBound, /* All keys should be greater than this, if not NULL */
+ int nLower, /* Number of characters in zLowerBound */
+ char *zUpperBound, /* All keys should be less than this, if not NULL */
+ int nUpper /* Number of characters in zUpperBound */
+){
+ MemPage *pPage;
+ int i, rc, depth, d2, pgno, cnt;
+ int hdr, cellStart;
+ int nCell;
+ u8 *data;
+ BtCursor cur;
+ Btree *pBt;
+ int maxLocal, usableSize;
+ char zContext[100];
+ char *hit;
+
+ sprintf(zContext, "Page %d: ", iPage);
+
+ /* Check that the page exists
+ */
+ cur.pBt = pBt = pCheck->pBt;
+ usableSize = pBt->usableSize;
+ if( iPage==0 ) return 0;
+ if( checkRef(pCheck, iPage, zParentContext) ) return 0;
+ if( (rc = getPage(pBt, (Pgno)iPage, &pPage))!=0 ){
+ checkAppendMsg(pCheck, zContext,
+ "unable to get the page. error code=%d", rc);
+ return 0;
+ }
+ maxLocal = pPage->leafData ? pBt->maxLeaf : pBt->maxLocal;
+ if( (rc = initPage(pPage, pParent))!=0 ){
+ checkAppendMsg(pCheck, zContext, "initPage() returns error code %d", rc);
+ releasePage(pPage);
+ return 0;
+ }
+
+ /* Check out all the cells.
+ */
+ depth = 0;
+ cur.pPage = pPage;
+ for(i=0; i<pPage->nCell; i++){
+ u8 *pCell;
+ int sz;
+ CellInfo info;
+
+ /* Check payload overflow pages
+ */
+ sprintf(zContext, "On tree page %d cell %d: ", iPage, i);
+ pCell = findCell(pPage,i);
+ parseCellPtr(pPage, pCell, &info);
+ sz = info.nData;
+ if( !pPage->intKey ) sz += info.nKey;
+ if( sz>info.nLocal ){
+ int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
+ Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
+ }
+#endif
+ checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
+ }
+
+ /* Check sanity of left child page.
+ */
+ if( !pPage->leaf ){
+ pgno = get4byte(pCell);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
+ }
+#endif
+ d2 = checkTreePage(pCheck,pgno,pPage,zContext,0,0,0,0);
+ if( i>0 && d2!=depth ){
+ checkAppendMsg(pCheck, zContext, "Child page depth differs");
+ }
+ depth = d2;
+ }
+ }
+ if( !pPage->leaf ){
+ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ sprintf(zContext, "On page %d at right child: ", iPage);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
+ }
+#endif
+ checkTreePage(pCheck, pgno, pPage, zContext,0,0,0,0);
+ }
+
+ /* Check for complete coverage of the page
+ */
+ data = pPage->aData;
+ hdr = pPage->hdrOffset;
+ hit = sqliteMalloc( usableSize );
+ if( hit ){
+ memset(hit, 1, get2byte(&data[hdr+5]));
+ nCell = get2byte(&data[hdr+3]);
+ cellStart = hdr + 12 - 4*pPage->leaf;
+ for(i=0; i<nCell; i++){
+ int pc = get2byte(&data[cellStart+i*2]);
+ int size = cellSizePtr(pPage, &data[pc]);
+ int j;
+ if( (pc+size-1)>=usableSize || pc<0 ){
+ checkAppendMsg(pCheck, 0,
+ "Corruption detected in cell %d on page %d",i,iPage,0);
+ }else{
+ for(j=pc+size-1; j>=pc; j--) hit[j]++;
+ }
+ }
+ for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i<usableSize && cnt<10000;
+ cnt++){
+ int size = get2byte(&data[i+2]);
+ int j;
+ if( (i+size-1)>=usableSize || i<0 ){
+ checkAppendMsg(pCheck, 0,
+ "Corruption detected in cell %d on page %d",i,iPage,0);
+ }else{
+ for(j=i+size-1; j>=i; j--) hit[j]++;
+ }
+ i = get2byte(&data[i]);
+ }
+ for(i=cnt=0; i<usableSize; i++){
+ if( hit[i]==0 ){
+ cnt++;
+ }else if( hit[i]>1 ){
+ checkAppendMsg(pCheck, 0,
+ "Multiple uses for byte %d of page %d", i, iPage);
+ break;
+ }
+ }
+ if( cnt!=data[hdr+7] ){
+ checkAppendMsg(pCheck, 0,
+ "Fragmented space is %d byte reported as %d on page %d",
+ cnt, data[hdr+7], iPage);
+ }
+ }
+ sqliteFree(hit);
+
+ releasePage(pPage);
+ return depth+1;
+}
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
+/*
+** This routine does a complete check of the given BTree file. aRoot[] is
+** an array of pages numbers were each page number is the root page of
+** a table. nRoot is the number of entries in aRoot.
+**
+** If everything checks out, this routine returns NULL. If something is
+** amiss, an error message is written into memory obtained from malloc()
+** and a pointer to that error message is returned. The calling function
+** is responsible for freeing the error message when it is done.
+*/
+char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){
+ int i;
+ int nRef;
+ IntegrityCk sCheck;
+
+ nRef = *sqlite3pager_stats(pBt->pPager);
+ if( lockBtreeWithRetry(pBt)!=SQLITE_OK ){
+ return sqliteStrDup("Unable to acquire a read lock on the database");
+ }
+ sCheck.pBt = pBt;
+ sCheck.pPager = pBt->pPager;
+ sCheck.nPage = sqlite3pager_pagecount(sCheck.pPager);
+ if( sCheck.nPage==0 ){
+ unlockBtreeIfUnused(pBt);
+ return 0;
+ }
+ sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
+ if( !sCheck.anRef ){
+ unlockBtreeIfUnused(pBt);
+ return sqlite3MPrintf("Unable to malloc %d bytes",
+ (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
+ }
+ for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
+ i = PENDING_BYTE_PAGE(pBt);
+ if( i<=sCheck.nPage ){
+ sCheck.anRef[i] = 1;
+ }
+ sCheck.zErrMsg = 0;
+
+ /* Check the integrity of the freelist
+ */
+ checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
+ get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
+
+ /* Check all the tables.
+ */
+ for(i=0; i<nRoot; i++){
+ if( aRoot[i]==0 ) continue;
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum && aRoot[i]>1 ){
+ checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
+ }
+#endif
+ checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0);
+ }
+
+ /* Make sure every page in the file is referenced
+ */
+ for(i=1; i<=sCheck.nPage; i++){
+#ifdef SQLITE_OMIT_AUTOVACUUM
+ if( sCheck.anRef[i]==0 ){
+ checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
+ }
+#else
+ /* If the database supports auto-vacuum, make sure no tables contain
+ ** references to pointer-map pages.
+ */
+ if( sCheck.anRef[i]==0 &&
+ (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){
+ checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
+ }
+ if( sCheck.anRef[i]!=0 &&
+ (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){
+ checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
+ }
+#endif
+ }
+
+ /* Make sure this analysis did not leave any unref() pages
+ */
+ unlockBtreeIfUnused(pBt);
+ if( nRef != *sqlite3pager_stats(pBt->pPager) ){
+ checkAppendMsg(&sCheck, 0,
+ "Outstanding page count goes from %d to %d during this analysis",
+ nRef, *sqlite3pager_stats(pBt->pPager)
+ );
+ }
+
+ /* Clean up and report errors.
+ */
+ sqliteFree(sCheck.anRef);
+ return sCheck.zErrMsg;
+}
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+
+/*
+** Return the full pathname of the underlying database file.
+*/
+const char *sqlite3BtreeGetFilename(Btree *pBt){
+ assert( pBt->pPager!=0 );
+ return sqlite3pager_filename(pBt->pPager);
+}
+
+/*
+** Return the pathname of the directory that contains the database file.
+*/
+const char *sqlite3BtreeGetDirname(Btree *pBt){
+ assert( pBt->pPager!=0 );
+ return sqlite3pager_dirname(pBt->pPager);
+}
+
+/*
+** Return the pathname of the journal file for this database. The return
+** value of this routine is the same regardless of whether the journal file
+** has been created or not.
+*/
+const char *sqlite3BtreeGetJournalname(Btree *pBt){
+ assert( pBt->pPager!=0 );
+ return sqlite3pager_journalname(pBt->pPager);
+}
+
+#ifndef SQLITE_OMIT_VACUUM
+/*
+** Copy the complete content of pBtFrom into pBtTo. A transaction
+** must be active for both files.
+**
+** The size of file pBtFrom may be reduced by this operation.
+** If anything goes wrong, the transaction on pBtFrom is rolled back.
+*/
+int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
+ int rc = SQLITE_OK;
+ Pgno i, nPage, nToPage;
+
+ if( pBtTo->inTrans!=TRANS_WRITE || pBtFrom->inTrans!=TRANS_WRITE ){
+ return SQLITE_ERROR;
+ }
+ if( pBtTo->pCursor ) return SQLITE_BUSY;
+ nToPage = sqlite3pager_pagecount(pBtTo->pPager);
+ nPage = sqlite3pager_pagecount(pBtFrom->pPager);
+ for(i=1; rc==SQLITE_OK && i<=nPage; i++){
+ void *pPage;
+ rc = sqlite3pager_get(pBtFrom->pPager, i, &pPage);
+ if( rc ) break;
+ rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage);
+ if( rc ) break;
+ sqlite3pager_unref(pPage);
+ }
+ for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
+ void *pPage;
+ rc = sqlite3pager_get(pBtTo->pPager, i, &pPage);
+ if( rc ) break;
+ rc = sqlite3pager_write(pPage);
+ sqlite3pager_unref(pPage);
+ sqlite3pager_dont_write(pBtTo->pPager, i);
+ }
+ if( !rc && nPage<nToPage ){
+ rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
+ }
+ if( rc ){
+ sqlite3BtreeRollback(pBtTo);
+ }
+ return rc;
+}
+#endif /* SQLITE_OMIT_VACUUM */
+
+/*
+** Return non-zero if a transaction is active.
+*/
+int sqlite3BtreeIsInTrans(Btree *pBt){
+ return (pBt && (pBt->inTrans==TRANS_WRITE));
+}
+
+/*
+** Return non-zero if a statement transaction is active.
+*/
+int sqlite3BtreeIsInStmt(Btree *pBt){
+ return (pBt && pBt->inStmt);
+}
+
+/*
+** This call is a no-op if no write-transaction is currently active on pBt.
+**
+** Otherwise, sync the database file for the btree pBt. zMaster points to
+** the name of a master journal file that should be written into the
+** individual journal file, or is NULL, indicating no master journal file
+** (single database transaction).
+**
+** When this is called, the master journal should already have been
+** created, populated with this journal pointer and synced to disk.
+**
+** Once this is routine has returned, the only thing required to commit
+** the write-transaction for this database file is to delete the journal.
+*/
+int sqlite3BtreeSync(Btree *pBt, const char *zMaster){
+ if( pBt->inTrans==TRANS_WRITE ){
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ Pgno nTrunc = 0;
+ if( pBt->autoVacuum ){
+ int rc = autoVacuumCommit(pBt, &nTrunc);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
+#endif
+ return sqlite3pager_sync(pBt->pPager, zMaster, 0);
+ }
+ return SQLITE_OK;
+}
+
+#ifndef SQLITE_OMIT_GLOBALRECOVER
+/*
+** Reset the btree and underlying pager after a malloc() failure. Any
+** transaction that was active when malloc() failed is rolled back.
+*/
+int sqlite3BtreeReset(Btree *pBt){
+ if( pBt->pCursor ) return SQLITE_BUSY;
+ pBt->inTrans = TRANS_NONE;
+ unlockBtreeIfUnused(pBt);
+ return sqlite3pager_reset(pBt->pPager);
+}
+#endif
diff --git a/src/sqlite/btree.h b/src/sqlite/btree.h
new file mode 100644
index 0000000..c6ae456
--- /dev/null
+++ b/src/sqlite/btree.h
@@ -0,0 +1,143 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the interface that the sqlite B-Tree file
+** subsystem. See comments in the source code for a detailed description
+** of what each interface routine does.
+**
+** @(#) $Id: btree.h,v 1.1.1.1 2006/02/03 20:35:21 hoganrobert Exp $
+*/
+#ifndef _BTREE_H_
+#define _BTREE_H_
+
+/* TODO: This definition is just included so other modules compile. It
+** needs to be revisited.
+*/
+#define SQLITE_N_BTREE_META 10
+
+/*
+** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
+** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
+*/
+#ifndef SQLITE_DEFAULT_AUTOVACUUM
+ #define SQLITE_DEFAULT_AUTOVACUUM 0
+#endif
+
+/*
+** Forward declarations of structure
+*/
+typedef struct Btree Btree;
+typedef struct BtCursor BtCursor;
+
+
+int sqlite3BtreeOpen(
+ const char *zFilename, /* Name of database file to open */
+ Btree **, /* Return open Btree* here */
+ int flags /* Flags */
+);
+
+/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
+** following values.
+**
+** NOTE: These values must match the corresponding PAGER_ values in
+** pager.h.
+*/
+#define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */
+#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */
+#define BTREE_MEMORY 4 /* In-memory DB. No argument */
+
+int sqlite3BtreeClose(Btree*);
+int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
+int sqlite3BtreeSetCacheSize(Btree*,int);
+int sqlite3BtreeSetSafetyLevel(Btree*,int);
+int sqlite3BtreeSetPageSize(Btree*,int,int);
+int sqlite3BtreeGetPageSize(Btree*);
+int sqlite3BtreeGetReserve(Btree*);
+int sqlite3BtreeSetAutoVacuum(Btree *, int);
+int sqlite3BtreeGetAutoVacuum(Btree *);
+int sqlite3BtreeBeginTrans(Btree*,int);
+int sqlite3BtreeCommit(Btree*);
+int sqlite3BtreeRollback(Btree*);
+int sqlite3BtreeBeginStmt(Btree*);
+int sqlite3BtreeCommitStmt(Btree*);
+int sqlite3BtreeRollbackStmt(Btree*);
+int sqlite3BtreeCreateTable(Btree*, int*, int flags);
+int sqlite3BtreeIsInTrans(Btree*);
+int sqlite3BtreeIsInStmt(Btree*);
+int sqlite3BtreeSync(Btree*, const char *zMaster);
+int sqlite3BtreeReset(Btree *);
+
+const char *sqlite3BtreeGetFilename(Btree *);
+const char *sqlite3BtreeGetDirname(Btree *);
+const char *sqlite3BtreeGetJournalname(Btree *);
+int sqlite3BtreeCopyFile(Btree *, Btree *);
+
+/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
+** of the following flags:
+*/
+#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
+#define BTREE_ZERODATA 2 /* Table has keys only - no data */
+#define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */
+
+int sqlite3BtreeDropTable(Btree*, int, int*);
+int sqlite3BtreeClearTable(Btree*, int);
+int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
+int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
+
+int sqlite3BtreeCursor(
+ Btree*, /* BTree containing table to open */
+ int iTable, /* Index of root page */
+ int wrFlag, /* 1 for writing. 0 for read-only */
+ int(*)(void*,int,const void*,int,const void*), /* Key comparison function */
+ void*, /* First argument to compare function */
+ BtCursor **ppCursor /* Returned cursor */
+);
+
+void sqlite3BtreeSetCompare(
+ BtCursor *,
+ int(*)(void*,int,const void*,int,const void*),
+ void*
+);
+
+int sqlite3BtreeCloseCursor(BtCursor*);
+int sqlite3BtreeMoveto(BtCursor*, const void *pKey, i64 nKey, int *pRes);
+int sqlite3BtreeDelete(BtCursor*);
+int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
+ const void *pData, int nData);
+int sqlite3BtreeFirst(BtCursor*, int *pRes);
+int sqlite3BtreeLast(BtCursor*, int *pRes);
+int sqlite3BtreeNext(BtCursor*, int *pRes);
+int sqlite3BtreeEof(BtCursor*);
+int sqlite3BtreeFlags(BtCursor*);
+int sqlite3BtreePrevious(BtCursor*, int *pRes);
+int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
+int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
+const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
+const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
+int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
+int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
+
+char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
+struct Pager *sqlite3BtreePager(Btree*);
+
+
+#ifdef SQLITE_TEST
+int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
+void sqlite3BtreeCursorList(Btree*);
+#endif
+
+#ifdef SQLITE_DEBUG
+int sqlite3BtreePageDump(Btree*, int, int recursive);
+#else
+#define sqlite3BtreePageDump(X,Y,Z) SQLITE_OK
+#endif
+
+#endif /* _BTREE_H_ */
diff --git a/src/sqlite/build.c b/src/sqlite/build.c
new file mode 100644
index 0000000..f63f0cb
--- /dev/null
+++ b/src/sqlite/build.c
@@ -0,0 +1,2881 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the SQLite parser
+** when syntax rules are reduced. The routines in this file handle the
+** following kinds of SQL syntax:
+**
+** CREATE TABLE
+** DROP TABLE
+** CREATE INDEX
+** DROP INDEX
+** creating ID lists
+** BEGIN TRANSACTION
+** COMMIT
+** ROLLBACK
+**
+** $Id: build.c,v 1.1.1.1 2006/02/03 20:35:22 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include <ctype.h>
+
+/*
+** This routine is called when a new SQL statement is beginning to
+** be parsed. Initialize the pParse structure as needed.
+*/
+void sqlite3BeginParse(Parse *pParse, int explainFlag){
+ pParse->explain = explainFlag;
+ pParse->nVar = 0;
+}
+
+/*
+** This routine is called after a single SQL statement has been
+** parsed and a VDBE program to execute that statement has been
+** prepared. This routine puts the finishing touches on the
+** VDBE program and resets the pParse structure for the next
+** parse.
+**
+** Note that if an error occurred, it might be the case that
+** no VDBE code was generated.
+*/
+void sqlite3FinishCoding(Parse *pParse){
+ sqlite3 *db;
+ Vdbe *v;
+
+ if( sqlite3_malloc_failed ) return;
+ if( pParse->nested ) return;
+ if( !pParse->pVdbe ){
+ if( pParse->rc==SQLITE_OK && pParse->nErr ){
+ pParse->rc = SQLITE_ERROR;
+ }
+ return;
+ }
+
+ /* Begin by generating some termination code at the end of the
+ ** vdbe program
+ */
+ db = pParse->db;
+ v = sqlite3GetVdbe(pParse);
+ if( v ){
+ sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
+
+ /* The cookie mask contains one bit for each database file open.
+ ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
+ ** set for each database that is used. Generate code to start a
+ ** transaction on each used database and to verify the schema cookie
+ ** on each used database.
+ */
+ if( pParse->cookieGoto>0 ){
+ u32 mask;
+ int iDb;
+ sqlite3VdbeChangeP2(v, pParse->cookieGoto-1, sqlite3VdbeCurrentAddr(v));
+ for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
+ if( (mask & pParse->cookieMask)==0 ) continue;
+ sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
+ sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
+ }
+ sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
+ }
+
+ /* Add a No-op that contains the complete text of the compiled SQL
+ ** statement as its P3 argument. This does not change the functionality
+ ** of the program.
+ **
+ ** This is used to implement sqlite3_trace().
+ */
+ sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);
+ }
+
+
+ /* Get the VDBE program ready for execution
+ */
+ if( v && pParse->nErr==0 ){
+ FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
+ sqlite3VdbeTrace(v, trace);
+ sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
+ pParse->nTab+3, pParse->nMaxDepth+1, pParse->explain);
+ pParse->rc = SQLITE_DONE;
+ pParse->colNamesSet = 0;
+ }else if( pParse->rc==SQLITE_OK ){
+ pParse->rc = SQLITE_ERROR;
+ }
+ pParse->nTab = 0;
+ pParse->nMem = 0;
+ pParse->nSet = 0;
+ pParse->nVar = 0;
+ pParse->cookieMask = 0;
+ pParse->cookieGoto = 0;
+}
+
+/*
+** Run the parser and code generator recursively in order to generate
+** code for the SQL statement given onto the end of the pParse context
+** currently under construction. When the parser is run recursively
+** this way, the final OP_Halt is not appended and other initialization
+** and finalization steps are omitted because those are handling by the
+** outermost parser.
+**
+** Not everything is nestable. This facility is designed to permit
+** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use
+** care if you decide to try to use this routine for some other purposes.
+*/
+void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
+ va_list ap;
+ char *zSql;
+ int rc;
+# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
+ char saveBuf[SAVE_SZ];
+
+ if( pParse->nErr ) return;
+ assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
+ va_start(ap, zFormat);
+ zSql = sqlite3VMPrintf(zFormat, ap);
+ va_end(ap);
+ if( zSql==0 ){
+ return; /* A malloc must have failed */
+ }
+ pParse->nested++;
+ memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
+ memset(&pParse->nVar, 0, SAVE_SZ);
+ rc = sqlite3RunParser(pParse, zSql, 0);
+ sqliteFree(zSql);
+ memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
+ pParse->nested--;
+}
+
+/*
+** Locate the in-memory structure that describes a particular database
+** table given the name of that table and (optionally) the name of the
+** database containing the table. Return NULL if not found.
+**
+** If zDatabase is 0, all databases are searched for the table and the
+** first matching table is returned. (No checking for duplicate table
+** names is done.) The search order is TEMP first, then MAIN, then any
+** auxiliary databases added using the ATTACH command.
+**
+** See also sqlite3LocateTable().
+*/
+Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
+ Table *p = 0;
+ int i;
+ assert( zName!=0 );
+ assert( (db->flags & SQLITE_Initialized) || db->init.busy );
+ for(i=OMIT_TEMPDB; i<db->nDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
+ p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
+ if( p ) break;
+ }
+ return p;
+}
+
+/*
+** Locate the in-memory structure that describes a particular database
+** table given the name of that table and (optionally) the name of the
+** database containing the table. Return NULL if not found. Also leave an
+** error message in pParse->zErrMsg.
+**
+** The difference between this routine and sqlite3FindTable() is that this
+** routine leaves an error message in pParse->zErrMsg where
+** sqlite3FindTable() does not.
+*/
+Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
+ Table *p;
+
+ /* 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 0;
+ }
+
+ p = sqlite3FindTable(pParse->db, zName, 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);
+ }
+ pParse->checkSchema = 1;
+ }
+ return p;
+}
+
+/*
+** Locate the in-memory structure that describes
+** a particular index given the name of that index
+** and the name of the database that contains the index.
+** Return NULL if not found.
+**
+** If zDatabase is 0, all databases are searched for the
+** table and the first matching index is returned. (No checking
+** for duplicate index names is done.) The search order is
+** TEMP first, then MAIN, then any auxiliary databases added
+** using the ATTACH command.
+*/
+Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
+ Index *p = 0;
+ int i;
+ assert( (db->flags & SQLITE_Initialized) || db->init.busy );
+ for(i=OMIT_TEMPDB; i<db->nDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
+ p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
+ if( p ) break;
+ }
+ return p;
+}
+
+/*
+** Reclaim the memory used by an index
+*/
+static void freeIndex(Index *p){
+ sqliteFree(p->zColAff);
+ sqliteFree(p);
+}
+
+/*
+** Remove the given index from the index hash table, and free
+** its memory structures.
+**
+** The index is removed from the database hash tables but
+** it is not unlinked from the Table that it indexes.
+** Unlinking from the Table must be done by the calling function.
+*/
+static void sqliteDeleteIndex(sqlite3 *db, Index *p){
+ Index *pOld;
+
+ 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);
+ }
+ freeIndex(p);
+}
+
+/*
+** For the index called zIdxName which is found in the database iDb,
+** unlike that index from its Table then remove the index from
+** the index hash table and free all memory structures associated
+** with the index.
+*/
+void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
+ Index *pIndex;
+ int len;
+
+ len = strlen(zIdxName);
+ pIndex = sqlite3HashInsert(&db->aDb[iDb].idxHash, zIdxName, len+1, 0);
+ if( pIndex ){
+ if( pIndex->pTable->pIndex==pIndex ){
+ pIndex->pTable->pIndex = pIndex->pNext;
+ }else{
+ Index *p;
+ for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
+ if( p && p->pNext==pIndex ){
+ p->pNext = pIndex->pNext;
+ }
+ }
+ freeIndex(pIndex);
+ }
+ db->flags |= SQLITE_InternChanges;
+}
+
+/*
+** Erase all schema information from the in-memory hash tables of
+** a single database. This routine is called to reclaim memory
+** before the database closes. It is also called during a rollback
+** if there were schema changes during the transaction or if a
+** schema-cookie mismatch occurs.
+**
+** If iDb<=0 then reset the internal schema tables for all database
+** files. If iDb>=2 then reset the internal schema for only the
+** single file indicated.
+*/
+void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
+ HashElem *pElem;
+ Hash temp1;
+ Hash temp2;
+ int i, j;
+
+ assert( iDb>=0 && iDb<db->nDb );
+ db->flags &= ~SQLITE_Initialized;
+ for(i=iDb; i<db->nDb; i++){
+ Db *pDb = &db->aDb[i];
+ temp1 = pDb->tblHash;
+ temp2 = pDb->trigHash;
+ sqlite3HashInit(&pDb->trigHash, SQLITE_HASH_STRING, 0);
+ sqlite3HashClear(&pDb->aFKey);
+ sqlite3HashClear(&pDb->idxHash);
+ for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
+ sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
+ }
+ sqlite3HashClear(&temp2);
+ sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0);
+ for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
+ Table *pTab = sqliteHashData(pElem);
+ sqlite3DeleteTable(db, pTab);
+ }
+ sqlite3HashClear(&temp1);
+ pDb->pSeqTab = 0;
+ DbClearProperty(db, i, DB_SchemaLoaded);
+ if( iDb>0 ) return;
+ }
+ assert( iDb==0 );
+ db->flags &= ~SQLITE_InternChanges;
+
+ /* If one or more of the auxiliary database files has been closed,
+ ** then remove then from the auxiliary database list. We take the
+ ** opportunity to do this here since we have just deleted all of the
+ ** schema hash tables and therefore do not have to make any changes
+ ** to any of those tables.
+ */
+ for(i=0; i<db->nDb; i++){
+ struct Db *pDb = &db->aDb[i];
+ if( pDb->pBt==0 ){
+ if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
+ pDb->pAux = 0;
+ }
+ }
+ for(i=j=2; i<db->nDb; i++){
+ struct Db *pDb = &db->aDb[i];
+ if( pDb->pBt==0 ){
+ sqliteFree(pDb->zName);
+ pDb->zName = 0;
+ continue;
+ }
+ if( j<i ){
+ db->aDb[j] = db->aDb[i];
+ }
+ j++;
+ }
+ memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
+ db->nDb = j;
+ if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
+ memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
+ sqliteFree(db->aDb);
+ db->aDb = db->aDbStatic;
+ }
+}
+
+/*
+** This routine is called whenever a rollback occurs. If there were
+** schema changes during the transaction, then we have to reset the
+** internal hash tables and reload them from disk.
+*/
+void sqlite3RollbackInternalChanges(sqlite3 *db){
+ if( db->flags & SQLITE_InternChanges ){
+ sqlite3ResetInternalSchema(db, 0);
+ }
+}
+
+/*
+** This routine is called when a commit occurs.
+*/
+void sqlite3CommitInternalChanges(sqlite3 *db){
+ db->flags &= ~SQLITE_InternChanges;
+}
+
+/*
+** Clear the column names from a table or view.
+*/
+static void sqliteResetColumnNames(Table *pTable){
+ int i;
+ Column *pCol;
+ assert( pTable!=0 );
+ if( (pCol = pTable->aCol)!=0 ){
+ for(i=0; i<pTable->nCol; i++, pCol++){
+ sqliteFree(pCol->zName);
+ sqlite3ExprDelete(pCol->pDflt);
+ sqliteFree(pCol->zType);
+ }
+ sqliteFree(pTable->aCol);
+ }
+ pTable->aCol = 0;
+ pTable->nCol = 0;
+}
+
+/*
+** Remove the memory data structures associated with the given
+** Table. No changes are made to disk by this routine.
+**
+** This routine just deletes the data structure. It does not unlink
+** the table data structure from the hash table. Nor does it remove
+** foreign keys from the sqlite.aFKey hash table. But it does destroy
+** memory structures of the indices and foreign keys associated with
+** the table.
+**
+** Indices associated with the table are unlinked from the "db"
+** data structure if db!=NULL. If db==NULL, indices attached to
+** the table are deleted, but it is assumed they have already been
+** unlinked.
+*/
+void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
+ Index *pIndex, *pNext;
+ FKey *pFKey, *pNextFKey;
+
+ if( pTable==0 ) return;
+
+ /* Do not delete the table until the reference count reaches zero. */
+ pTable->nRef--;
+ if( pTable->nRef>0 ){
+ return;
+ }
+ assert( pTable->nRef==0 );
+
+ /* Delete all indices associated with this table
+ */
+ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
+ pNext = pIndex->pNext;
+ assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
+ sqliteDeleteIndex(db, pIndex);
+ }
+
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ /* Delete all foreign keys associated with this table. The keys
+ ** should have already been unlinked from the db->aFKey hash table
+ */
+ for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
+ pNextFKey = pFKey->pNextFrom;
+ assert( pTable->iDb<db->nDb );
+ assert( sqlite3HashFind(&db->aDb[pTable->iDb].aFKey,
+ pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
+ sqliteFree(pFKey);
+ }
+#endif
+
+ /* Delete the Table structure itself.
+ */
+ sqliteResetColumnNames(pTable);
+ sqliteFree(pTable->zName);
+ sqliteFree(pTable->zColAff);
+ sqlite3SelectDelete(pTable->pSelect);
+ sqliteFree(pTable);
+}
+
+/*
+** Unlink the given table from the hash tables and the delete the
+** table structure with all its indices and foreign keys.
+*/
+void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
+ Table *p;
+ FKey *pF1, *pF2;
+ Db *pDb;
+
+ assert( db!=0 );
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( zTabName && zTabName[0] );
+ pDb = &db->aDb[iDb];
+ p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0);
+ if( p ){
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
+ int nTo = strlen(pF1->zTo) + 1;
+ pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo);
+ if( pF2==pF1 ){
+ sqlite3HashInsert(&pDb->aFKey, pF1->zTo, nTo, pF1->pNextTo);
+ }else{
+ while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
+ if( pF2 ){
+ pF2->pNextTo = pF1->pNextTo;
+ }
+ }
+ }
+#endif
+ sqlite3DeleteTable(db, p);
+ }
+ db->flags |= SQLITE_InternChanges;
+}
+
+/*
+** Given a token, return a string that consists of the text of that
+** token with any quotations removed. Space to hold the returned string
+** is obtained from sqliteMalloc() and must be freed by the calling
+** function.
+**
+** Tokens are often just pointers into the original SQL text and so
+** are not \000 terminated and are not persistent. The returned string
+** is \000 terminated and is persistent.
+*/
+char *sqlite3NameFromToken(Token *pName){
+ char *zName;
+ if( pName ){
+ zName = sqliteStrNDup(pName->z, pName->n);
+ sqlite3Dequote(zName);
+ }else{
+ zName = 0;
+ }
+ return zName;
+}
+
+/*
+** Open the sqlite_master table stored in database number iDb for
+** writing. The table is opened using cursor 0.
+*/
+void sqlite3OpenMasterTable(Vdbe *v, int iDb){
+ sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
+ sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
+}
+
+/*
+** The token *pName contains the name of a database (either "main" or
+** "temp" or the name of an attached db). This routine returns the
+** 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 i = -1; /* Database number */
+ int n; /* Number of characters in the name */
+ Db *pDb; /* A database whose name space is being searched */
+ char *zName; /* Name we are searching for */
+
+ zName = sqlite3NameFromToken(pName);
+ if( zName ){
+ n = strlen(zName);
+ for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
+ if( (!OMIT_TEMPDB || i!=1 ) && n==strlen(pDb->zName) &&
+ 0==sqlite3StrICmp(pDb->zName, zName) ){
+ break;
+ }
+ }
+ sqliteFree(zName);
+ }
+ return i;
+}
+
+/* The table or view or trigger name is passed to this routine via tokens
+** pName1 and pName2. If the table name was fully qualified, for example:
+**
+** CREATE TABLE xxx.yyy (...);
+**
+** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
+** the table name is not fully qualified, i.e.:
+**
+** CREATE TABLE yyy(...);
+**
+** Then pName1 is set to "yyy" and pName2 is "".
+**
+** This routine sets the *ppUnqual pointer to point at the token (pName1 or
+** pName2) that stores the unqualified table name. The index of the
+** database "xxx" is returned.
+*/
+int sqlite3TwoPartName(
+ Parse *pParse, /* Parsing and code generating context */
+ Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */
+ Token *pName2, /* The "yyy" in the name "xxx.yyy" */
+ Token **pUnqual /* Write the unqualified object name here */
+){
+ int iDb; /* Database holding the object */
+ sqlite3 *db = pParse->db;
+
+ if( pName2 && pName2->n>0 ){
+ assert( !db->init.busy );
+ *pUnqual = pName2;
+ iDb = findDb(db, pName1);
+ if( iDb<0 ){
+ sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
+ pParse->nErr++;
+ return -1;
+ }
+ }else{
+ assert( db->init.iDb==0 || db->init.busy );
+ iDb = db->init.iDb;
+ *pUnqual = pName1;
+ }
+ return iDb;
+}
+
+/*
+** This routine is used to check if the UTF-8 string zName is a legal
+** unqualified name for a new schema object (table, index, view or
+** trigger). All names are legal except those that begin with the string
+** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
+** is reserved for internal use.
+*/
+int sqlite3CheckObjectName(Parse *pParse, const char *zName){
+ if( !pParse->db->init.busy && pParse->nested==0
+ && (pParse->db->flags & SQLITE_WriteSchema)==0
+ && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
+ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
+ return SQLITE_ERROR;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Begin constructing a new table representation in memory. This is
+** the first of several action routines that get called in response
+** to a CREATE TABLE statement. In particular, this routine is called
+** after seeing tokens "CREATE" and "TABLE" and the table name. The
+** pStart token is the CREATE and pName is the table name. The isTemp
+** flag is true if the table should be stored in the auxiliary database
+** file instead of in the main database file. This is normally the case
+** when the "TEMP" or "TEMPORARY" keyword occurs in between
+** CREATE and TABLE.
+**
+** The new table record is initialized and put in pParse->pNewTable.
+** As more of the CREATE TABLE statement is parsed, additional action
+** routines will be called to add more information to this record.
+** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine
+** is called to complete the construction of the new table record.
+*/
+void sqlite3StartTable(
+ Parse *pParse, /* Parser context */
+ Token *pStart, /* The "CREATE" token */
+ Token *pName1, /* First part of the name of the table or view */
+ Token *pName2, /* Second part of the name of the table or view */
+ int isTemp, /* True if this is a TEMP table */
+ int isView /* True if this is a VIEW */
+){
+ Table *pTable;
+ Index *pIdx;
+ char *zName = 0; /* The name of the new table */
+ sqlite3 *db = pParse->db;
+ Vdbe *v;
+ int iDb; /* Database number to create the table in */
+ Token *pName; /* Unqualified name of the table to create */
+
+ /* The table or view name to create is passed to this routine via tokens
+ ** pName1 and pName2. If the table name was fully qualified, for example:
+ **
+ ** CREATE TABLE xxx.yyy (...);
+ **
+ ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
+ ** the table name is not fully qualified, i.e.:
+ **
+ ** CREATE TABLE yyy(...);
+ **
+ ** Then pName1 is set to "yyy" and pName2 is "".
+ **
+ ** The call below sets the pName pointer to point at the token (pName1 or
+ ** pName2) that stores the unqualified table name. The variable iDb is
+ ** set to the index of the database that the table or view is to be
+ ** created in.
+ */
+ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+ if( iDb<0 ) return;
+ if( !OMIT_TEMPDB && isTemp && iDb>1 ){
+ /* If creating a temp table, the name may not be qualified */
+ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
+ return;
+ }
+ if( !OMIT_TEMPDB && isTemp ) iDb = 1;
+
+ pParse->sNameToken = *pName;
+ zName = sqlite3NameFromToken(pName);
+ if( zName==0 ) return;
+ if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ goto begin_table_error;
+ }
+ if( db->init.iDb==1 ) isTemp = 1;
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ assert( (isTemp & 1)==isTemp );
+ {
+ int code;
+ char *zDb = db->aDb[iDb].zName;
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
+ goto begin_table_error;
+ }
+ if( isView ){
+ if( !OMIT_TEMPDB && isTemp ){
+ code = SQLITE_CREATE_TEMP_VIEW;
+ }else{
+ code = SQLITE_CREATE_VIEW;
+ }
+ }else{
+ if( !OMIT_TEMPDB && isTemp ){
+ code = SQLITE_CREATE_TEMP_TABLE;
+ }else{
+ code = SQLITE_CREATE_TABLE;
+ }
+ }
+ if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
+ goto begin_table_error;
+ }
+ }
+#endif
+
+ /* Make sure the new table name does not collide with an existing
+ ** index or table name in the same database. Issue an error message if
+ ** it does.
+ */
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+ goto begin_table_error;
+ }
+ pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
+ if( pTable ){
+ sqlite3ErrorMsg(pParse, "table %T already exists", pName);
+ goto begin_table_error;
+ }
+ if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 &&
+ ( iDb==0 || !db->init.busy) ){
+ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
+ goto begin_table_error;
+ }
+ pTable = sqliteMalloc( sizeof(Table) );
+ if( pTable==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ pParse->nErr++;
+ goto begin_table_error;
+ }
+ pTable->zName = zName;
+ pTable->nCol = 0;
+ pTable->aCol = 0;
+ pTable->iPKey = -1;
+ pTable->pIndex = 0;
+ pTable->iDb = iDb;
+ pTable->nRef = 1;
+ if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable);
+ pParse->pNewTable = pTable;
+
+ /* If this is the magic sqlite_sequence table used by autoincrement,
+ ** then record a pointer to this table in the main database structure
+ ** so that INSERT can find the table easily.
+ */
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ if( strcmp(zName, "sqlite_sequence")==0 ){
+ db->aDb[iDb].pSeqTab = pTable;
+ }
+#endif
+
+ /* Begin generating the code that will insert the table record into
+ ** the SQLITE_MASTER table. Note in particular that we must go ahead
+ ** and allocate the record number for the table entry now. Before any
+ ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause
+ ** indices to be created and the table record must come before the
+ ** indices. Hence, the record number for the table must be allocated
+ ** now.
+ */
+ if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
+ int lbl;
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+
+ /* If the file format and encoding in the database have not been set,
+ ** set them now.
+ */
+ sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */
+ lbl = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_If, 0, lbl);
+ sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
+ sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
+ sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
+ sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
+ sqlite3VdbeResolveLabel(v, lbl);
+
+ /* This just creates a place-holder record in the sqlite_master table.
+ ** The record created does not contain anything yet. It will be replaced
+ ** by the real entry in code generated at sqlite3EndTable().
+ **
+ ** The rowid for the new entry is left on the top of the stack.
+ ** The rowid value is needed by the code that sqlite3EndTable will
+ ** generate.
+ */
+#ifndef SQLITE_OMIT_VIEW
+ if( isView ){
+ sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+ }else
+#endif
+ {
+ sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
+ }
+ sqlite3OpenMasterTable(v, iDb);
+ sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Close, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+ }
+
+ /* Normal (non-error) return. */
+ return;
+
+ /* If an error occurs, we jump here */
+begin_table_error:
+ sqliteFree(zName);
+ return;
+}
+
+/*
+** This macro is used to compare two strings in a case-insensitive manner.
+** It is slightly faster than calling sqlite3StrICmp() directly, but
+** produces larger code.
+**
+** WARNING: This macro is not compatible with the strcmp() family. It
+** returns true if the two strings are equal, otherwise false.
+*/
+#define STRICMP(x, y) (\
+sqlite3UpperToLower[*(unsigned char *)(x)]== \
+sqlite3UpperToLower[*(unsigned char *)(y)] \
+&& sqlite3StrICmp((x)+1,(y)+1)==0 )
+
+/*
+** Add a new column to the table currently being constructed.
+**
+** The parser calls this routine once for each column declaration
+** in a CREATE TABLE statement. sqlite3StartTable() gets called
+** first to get things going. Then this routine is called for each
+** column.
+*/
+void sqlite3AddColumn(Parse *pParse, Token *pName){
+ Table *p;
+ int i;
+ char *z;
+ Column *pCol;
+ if( (p = pParse->pNewTable)==0 ) return;
+ z = sqlite3NameFromToken(pName);
+ if( z==0 ) return;
+ for(i=0; i<p->nCol; i++){
+ if( STRICMP(z, p->aCol[i].zName) ){
+ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
+ sqliteFree(z);
+ return;
+ }
+ }
+ if( (p->nCol & 0x7)==0 ){
+ Column *aNew;
+ aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
+ if( aNew==0 ){
+ sqliteFree(z);
+ return;
+ }
+ p->aCol = aNew;
+ }
+ pCol = &p->aCol[p->nCol];
+ memset(pCol, 0, sizeof(p->aCol[0]));
+ pCol->zName = z;
+
+ /* If there is no type specified, columns have the default affinity
+ ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
+ ** be called next to set pCol->affinity correctly.
+ */
+ pCol->affinity = SQLITE_AFF_NONE;
+ pCol->pColl = pParse->db->pDfltColl;
+ p->nCol++;
+}
+
+/*
+** This routine is called by the parser while in the middle of
+** parsing a CREATE TABLE statement. A "NOT NULL" constraint has
+** been seen on a column. This routine sets the notNull flag on
+** the column currently under construction.
+*/
+void sqlite3AddNotNull(Parse *pParse, int onError){
+ Table *p;
+ int i;
+ if( (p = pParse->pNewTable)==0 ) return;
+ i = p->nCol-1;
+ if( i>=0 ) p->aCol[i].notNull = onError;
+}
+
+/*
+** Scan the column type name zType (length nType) and return the
+** associated affinity type.
+**
+** This routine does a case-independent search of zType for the
+** substrings in the following table. If one of the substrings is
+** found, the corresponding affinity is returned. If zType contains
+** more than one of the substrings, entries toward the top of
+** the table take priority. For example, if zType is 'BLOBINT',
+** SQLITE_AFF_INTEGER is returned.
+**
+** Substring | Affinity
+** --------------------------------
+** 'INT' | SQLITE_AFF_INTEGER
+** 'CHAR' | SQLITE_AFF_TEXT
+** 'CLOB' | SQLITE_AFF_TEXT
+** 'TEXT' | SQLITE_AFF_TEXT
+** 'BLOB' | SQLITE_AFF_NONE
+**
+** If none of the substrings in the above table are found,
+** SQLITE_AFF_NUMERIC is returned.
+*/
+static char sqlite3AffinityType(const char *zType, int nType){
+ u32 h = 0;
+ char aff = SQLITE_AFF_NUMERIC;
+ const unsigned char *zIn = zType;
+ const unsigned char *zEnd = (zIn+nType);
+
+ while( zIn!=zEnd ){
+ h = (h<<8) + sqlite3UpperToLower[*zIn];
+ zIn++;
+ if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
+ aff = SQLITE_AFF_TEXT;
+ }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */
+ aff = SQLITE_AFF_TEXT;
+ }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */
+ aff = SQLITE_AFF_TEXT;
+ }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */
+ && aff==SQLITE_AFF_NUMERIC ){
+ aff = SQLITE_AFF_NONE;
+ }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */
+ aff = SQLITE_AFF_INTEGER;
+ break;
+ }
+ }
+
+ return aff;
+}
+
+/*
+** This routine is called by the parser while in the middle of
+** parsing a CREATE TABLE statement. The pFirst token is the first
+** token in the sequence of tokens that describe the type of the
+** column currently under construction. pLast is the last token
+** in the sequence. Use this information to construct a string
+** that contains the typename of the column and store that string
+** in zType.
+*/
+void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
+ Table *p;
+ int i, j;
+ int n;
+ char *z;
+ const unsigned char *zIn;
+
+ Column *pCol;
+ if( (p = pParse->pNewTable)==0 ) return;
+ i = p->nCol-1;
+ if( i<0 ) return;
+ pCol = &p->aCol[i];
+ 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; i<n; i++){
+ int c = zIn[i];
+ if( isspace(c) ) continue;
+ z[j++] = c;
+ }
+ z[j] = 0;
+ pCol->affinity = sqlite3AffinityType(z, n);
+}
+
+/*
+** The expression is the default value for the most recently added column
+** of the table currently under construction.
+**
+** Default value expressions must be constant. Raise an exception if this
+** is not the case.
+**
+** This routine is called by the parser while in the middle of
+** parsing a CREATE TABLE statement.
+*/
+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);
+ }
+ sqlite3ExprDelete(pExpr);
+}
+
+/*
+** Designate the PRIMARY KEY for the table. pList is a list of names
+** of columns that form the primary key. If pList is NULL, then the
+** most recently added column of the table is the primary key.
+**
+** A table can have at most one primary key. If the table already has
+** a primary key (and this is the second primary key) then create an
+** error.
+**
+** If the PRIMARY KEY is on a single column whose datatype is INTEGER,
+** then we will try to use that column as the rowid. Set the Table.iPKey
+** field of the table under construction to be the index of the
+** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is
+** no INTEGER PRIMARY KEY.
+**
+** If the key is not an INTEGER PRIMARY KEY, then create a unique
+** index for the key. No index is created for INTEGER PRIMARY KEYs.
+*/
+void sqlite3AddPrimaryKey(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List of field names to be indexed */
+ int onError, /* What to do with a uniqueness conflict */
+ int autoInc /* True if the AUTOINCREMENT keyword is present */
+){
+ Table *pTab = pParse->pNewTable;
+ char *zType = 0;
+ int iCol = -1, i;
+ if( pTab==0 ) goto primary_key_exit;
+ if( pTab->hasPrimKey ){
+ sqlite3ErrorMsg(pParse,
+ "table \"%s\" has more than one primary key", pTab->zName);
+ goto primary_key_exit;
+ }
+ pTab->hasPrimKey = 1;
+ if( pList==0 ){
+ iCol = pTab->nCol - 1;
+ pTab->aCol[iCol].isPrimKey = 1;
+ }else{
+ for(i=0; i<pList->nExpr; i++){
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
+ break;
+ }
+ }
+ if( iCol<pTab->nCol ) pTab->aCol[iCol].isPrimKey = 1;
+ }
+ if( pList->nExpr>1 ) iCol = -1;
+ }
+ if( iCol>=0 && iCol<pTab->nCol ){
+ zType = pTab->aCol[iCol].zType;
+ }
+ if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){
+ pTab->iPKey = iCol;
+ pTab->keyConf = onError;
+ pTab->autoInc = autoInc;
+ }else if( autoInc ){
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
+ "INTEGER PRIMARY KEY");
+#endif
+ }else{
+ sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);
+ pList = 0;
+ }
+
+primary_key_exit:
+ sqlite3ExprListDelete(pList);
+ return;
+}
+
+/*
+** Set the collation function of the most recently parsed table column
+** to the CollSeq given.
+*/
+void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
+ Table *p;
+ Index *pIdx;
+ CollSeq *pColl;
+ int i;
+
+ if( (p = pParse->pNewTable)==0 ) return;
+ i = p->nCol-1;
+
+ pColl = sqlite3LocateCollSeq(pParse, zType, nType);
+ p->aCol[i].pColl = pColl;
+
+ /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
+ ** then an index may have been created on this column before the
+ ** collation type was added. Correct this if it is the case.
+ */
+ for(pIdx = p->pIndex; pIdx; pIdx=pIdx->pNext){
+ assert( pIdx->nColumn==1 );
+ if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl;
+ }
+}
+
+/*
+** Call sqlite3CheckCollSeq() for all collating sequences in an index,
+** in order to verify that all the necessary collating sequences are
+** loaded.
+*/
+int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){
+ if( pIdx ){
+ int i;
+ for(i=0; i<pIdx->nColumn; i++){
+ if( sqlite3CheckCollSeq(pParse, pIdx->keyInfo.aColl[i]) ){
+ return SQLITE_ERROR;
+ }
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** This function returns the collation sequence for database native text
+** encoding identified by the string zName, length nName.
+**
+** If the requested collation sequence is not available, or not available
+** in the database native encoding, the collation factory is invoked to
+** request it. If the collation factory does not supply such a sequence,
+** and the sequence is available in another text encoding, then that is
+** returned instead.
+**
+** If no versions of the requested collations sequence are available, or
+** another error occurs, NULL is returned and an error message written into
+** pParse.
+*/
+CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
+ sqlite3 *db = pParse->db;
+ u8 enc = db->enc;
+ u8 initbusy = db->init.busy;
+
+ CollSeq *pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
+ if( !initbusy && (!pColl || !pColl->xCmp) ){
+ pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
+ if( !pColl ){
+ if( nName<0 ){
+ nName = strlen(zName);
+ }
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
+ pColl = 0;
+ }
+ }
+
+ return pColl;
+}
+
+
+/*
+** Generate code that will increment the schema cookie.
+**
+** The schema cookie is used to determine when the schema for the
+** database changes. After each schema change, the cookie value
+** changes. When a process first reads the schema it records the
+** cookie. Thereafter, whenever it goes to access the database,
+** it checks the cookie to make sure the schema has not changed
+** since it was last read.
+**
+** This plan is not completely bullet-proof. It is possible for
+** the schema to change multiple times and for the cookie to be
+** set back to prior value. But schema changes are infrequent
+** and the probability of hitting the same cookie value is only
+** 1 chance in 2^32. So we're safe enough.
+*/
+void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){
+ sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].schema_cookie+1, 0);
+ sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
+}
+
+/*
+** Measure the number of characters needed to output the given
+** identifier. The number returned includes any quotes used
+** but does not include the null terminator.
+**
+** The estimate is conservative. It might be larger that what is
+** really needed.
+*/
+static int identLength(const char *z){
+ int n;
+ for(n=0; *z; n++, z++){
+ if( *z=='"' ){ n++; }
+ }
+ return n + 2;
+}
+
+/*
+** Write an identifier onto the end of the given string. Add
+** quote characters as needed.
+*/
+static void identPut(char *z, int *pIdx, char *zSignedIdent){
+ unsigned char *zIdent = (unsigned char*)zSignedIdent;
+ int i, j, needQuote;
+ i = *pIdx;
+ for(j=0; zIdent[j]; j++){
+ if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
+ }
+ needQuote = zIdent[j]!=0 || isdigit(zIdent[0])
+ || sqlite3KeywordCode(zIdent, j)!=TK_ID;
+ if( needQuote ) z[i++] = '"';
+ for(j=0; zIdent[j]; j++){
+ z[i++] = zIdent[j];
+ if( zIdent[j]=='"' ) z[i++] = '"';
+ }
+ if( needQuote ) z[i++] = '"';
+ z[i] = 0;
+ *pIdx = i;
+}
+
+/*
+** Generate a CREATE TABLE statement appropriate for the given
+** table. Memory to hold the text of the statement is obtained
+** from sqliteMalloc() and must be freed by the calling function.
+*/
+static char *createTableStmt(Table *p){
+ int i, k, n;
+ char *zStmt;
+ char *zSep, *zSep2, *zEnd, *z;
+ Column *pCol;
+ n = 0;
+ for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
+ n += identLength(pCol->zName);
+ z = pCol->zType;
+ if( z ){
+ n += (strlen(z) + 1);
+ }
+ }
+ n += identLength(p->zName);
+ if( n<50 ){
+ zSep = "";
+ zSep2 = ",";
+ zEnd = ")";
+ }else{
+ zSep = "\n ";
+ zSep2 = ",\n ";
+ zEnd = "\n)";
+ }
+ n += 35 + 6*p->nCol;
+ zStmt = sqliteMallocRaw( n );
+ if( zStmt==0 ) return 0;
+ strcpy(zStmt, !OMIT_TEMPDB&&p->iDb==1 ? "CREATE TEMP TABLE ":"CREATE TABLE ");
+ k = strlen(zStmt);
+ identPut(zStmt, &k, p->zName);
+ zStmt[k++] = '(';
+ for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
+ strcpy(&zStmt[k], zSep);
+ k += strlen(&zStmt[k]);
+ zSep = zSep2;
+ identPut(zStmt, &k, pCol->zName);
+ if( (z = pCol->zType)!=0 ){
+ zStmt[k++] = ' ';
+ strcpy(&zStmt[k], z);
+ k += strlen(z);
+ }
+ }
+ strcpy(&zStmt[k], zEnd);
+ return zStmt;
+}
+
+/*
+** This routine is called to report the final ")" that terminates
+** a CREATE TABLE statement.
+**
+** The table structure that other action routines have been building
+** is added to the internal hash tables, assuming no errors have
+** occurred.
+**
+** An entry for the table is made in the master table on disk, unless
+** this is a temporary table or db->init.busy==1. When db->init.busy==1
+** it means we are reading the sqlite_master table because we just
+** connected to the database or because the sqlite_master table has
+** recently changed, so the entry for this table already exists in
+** the sqlite_master table. We do not want to create it again.
+**
+** If the pSelect argument is not NULL, it means that this routine
+** was called to create a table generated from a
+** "CREATE TABLE ... AS SELECT ..." statement. The column names of
+** the new table will match the result set of the SELECT.
+*/
+void sqlite3EndTable(
+ Parse *pParse, /* Parse context */
+ Token *pCons, /* The ',' token after the last column defn. */
+ Token *pEnd, /* The final ')' token in the CREATE TABLE */
+ Select *pSelect /* Select from a "CREATE ... AS SELECT" */
+){
+ Table *p;
+ sqlite3 *db = pParse->db;
+
+ if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3_malloc_failed ) return;
+ p = pParse->pNewTable;
+ if( p==0 ) return;
+
+ assert( !db->init.busy || !pSelect );
+
+ /* If the db->init.busy is 1 it means we are reading the SQL off the
+ ** "sqlite_master" or "sqlite_temp_master" table on the disk.
+ ** So do not write to the disk again. Extract the root page number
+ ** for the table from the db->init.newTnum field. (The page number
+ ** should have been put there by the sqliteOpenCb routine.)
+ */
+ if( db->init.busy ){
+ p->tnum = db->init.newTnum;
+ }
+
+ /* If not initializing, then create a record for the new table
+ ** in the SQLITE_MASTER table of the database. The record number
+ ** for the new table entry should already be on the stack.
+ **
+ ** If this is a TEMPORARY table, write the entry into the auxiliary
+ ** file instead of into the main database file.
+ */
+ if( !db->init.busy ){
+ int n;
+ Vdbe *v;
+ char *zType; /* "view" or "table" */
+ char *zType2; /* "VIEW" or "TABLE" */
+ char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */
+
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return;
+
+ sqlite3VdbeAddOp(v, OP_Close, 0, 0);
+
+ /* Create the rootpage for the new table and push it onto the stack.
+ ** A view has no rootpage, so just push a zero onto the stack for
+ ** views. Initialize zType at the same time.
+ */
+ if( p->pSelect==0 ){
+ /* A regular table */
+ /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */
+ zType = "table";
+ zType2 = "TABLE";
+#ifndef SQLITE_OMIT_VIEW
+ }else{
+ /* A view */
+ /* sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */
+ zType = "view";
+ zType2 = "VIEW";
+#endif
+ }
+
+ /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
+ ** statement to populate the new table. The root-page number for the
+ ** new table is on the top of the vdbe stack.
+ **
+ ** Once the SELECT has been coded by sqlite3Select(), it is in a
+ ** suitable state to query for the column names and types to be used
+ ** by the new table.
+ */
+ if( pSelect ){
+ Table *pSelTab;
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Integer, p->iDb, 0);
+ sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0);
+ pParse->nTab = 2;
+ sqlite3Select(pParse, pSelect, SRT_Table, 1, 0, 0, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Close, 1, 0);
+ if( pParse->nErr==0 ){
+ pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
+ if( pSelTab==0 ) return;
+ assert( p->aCol==0 );
+ p->nCol = pSelTab->nCol;
+ p->aCol = pSelTab->aCol;
+ pSelTab->nCol = 0;
+ pSelTab->aCol = 0;
+ sqlite3DeleteTable(0, pSelTab);
+ }
+ }
+
+ /* Compute the complete text of the CREATE statement */
+ if( pSelect ){
+ zStmt = createTableStmt(p);
+ }else{
+ n = pEnd->z - pParse->sNameToken.z + 1;
+ zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z);
+ }
+
+ /* A slot for the record has already been allocated in the
+ ** SQLITE_MASTER table. We just need to update that slot with all
+ ** the information we've collected. The rowid for the preallocated
+ ** slot is the 2nd item on the stack. The top of the stack is the
+ ** root page for the new table (or a 0 if this is a view).
+ */
+ sqlite3NestedParse(pParse,
+ "UPDATE %Q.%s "
+ "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q "
+ "WHERE rowid=#1",
+ db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb),
+ zType,
+ p->zName,
+ p->zName,
+ zStmt
+ );
+ sqliteFree(zStmt);
+ sqlite3ChangeCookie(db, v, p->iDb);
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ /* Check to see if we need to create an sqlite_sequence table for
+ ** keeping track of autoincrement keys.
+ */
+ if( p->autoInc ){
+ Db *pDb = &db->aDb[p->iDb];
+ if( pDb->pSeqTab==0 ){
+ sqlite3NestedParse(pParse,
+ "CREATE TABLE %Q.sqlite_sequence(name,seq)",
+ pDb->zName
+ );
+ }
+ }
+#endif
+
+ /* Reparse everything to update our internal data structures */
+ sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
+ sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
+ }
+
+
+ /* Add the table to the in-memory representation of the database.
+ */
+ if( db->init.busy && pParse->nErr==0 ){
+ Table *pOld;
+ FKey *pFKey;
+ Db *pDb = &db->aDb[p->iDb];
+ pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p);
+ if( pOld ){
+ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
+ return;
+ }
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
+ int nTo = strlen(pFKey->zTo) + 1;
+ pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo);
+ sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey);
+ }
+#endif
+ pParse->pNewTable = 0;
+ db->nTable++;
+ db->flags |= SQLITE_InternChanges;
+
+#ifndef SQLITE_OMIT_ALTERTABLE
+ if( !p->pSelect ){
+ assert( !pSelect && pCons && pEnd );
+ if( pCons->z==0 ) pCons = pEnd;
+ p->addColOffset = 13 + (pCons->z - pParse->sNameToken.z);
+ }
+#endif
+ }
+}
+
+#ifndef SQLITE_OMIT_VIEW
+/*
+** The parser calls this routine in order to create a new VIEW
+*/
+void sqlite3CreateView(
+ Parse *pParse, /* The parsing context */
+ Token *pBegin, /* The CREATE token that begins the statement */
+ Token *pName1, /* The token that holds the name of the view */
+ Token *pName2, /* The token that holds the name of the view */
+ Select *pSelect, /* A SELECT statement that will become the new view */
+ int isTemp /* TRUE for a TEMPORARY view */
+){
+ Table *p;
+ int n;
+ const unsigned char *z;
+ Token sEnd;
+ DbFixer sFix;
+ Token *pName;
+
+ if( pParse->nVar>0 ){
+ sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
+ sqlite3SelectDelete(pSelect);
+ return;
+ }
+ sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1);
+ p = pParse->pNewTable;
+ if( p==0 || pParse->nErr ){
+ sqlite3SelectDelete(pSelect);
+ return;
+ }
+ sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+ if( sqlite3FixInit(&sFix, pParse, p->iDb, "view", pName)
+ && sqlite3FixSelect(&sFix, pSelect)
+ ){
+ sqlite3SelectDelete(pSelect);
+ return;
+ }
+
+ /* Make a copy of the entire SELECT statement that defines the view.
+ ** This will force all the Expr.token.z values to be dynamically
+ ** allocated rather than point to the input string - which means that
+ ** they will persist after the current sqlite3_exec() call returns.
+ */
+ p->pSelect = sqlite3SelectDup(pSelect);
+ sqlite3SelectDelete(pSelect);
+ if( !pParse->db->init.busy ){
+ sqlite3ViewGetColumnNames(pParse, p);
+ }
+
+ /* Locate the end of the CREATE VIEW statement. Make sEnd point to
+ ** the end.
+ */
+ sEnd = pParse->sLastToken;
+ if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
+ sEnd.z += sEnd.n;
+ }
+ sEnd.n = 0;
+ n = sEnd.z - pBegin->z;
+ z = (const unsigned char*)pBegin->z;
+ while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
+ sEnd.z = &z[n-1];
+ sEnd.n = 1;
+
+ /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
+ sqlite3EndTable(pParse, 0, &sEnd, 0);
+ return;
+}
+#endif /* SQLITE_OMIT_VIEW */
+
+#ifndef SQLITE_OMIT_VIEW
+/*
+** The Table structure pTable is really a VIEW. Fill in the names of
+** the columns of the view in the pTable structure. Return the number
+** of errors. If an error is seen leave an error message in pParse->zErrMsg.
+*/
+int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
+ Table *pSelTab; /* A fake table from which we get the result set */
+ Select *pSel; /* Copy of the SELECT that implements the view */
+ int nErr = 0; /* Number of errors encountered */
+ int n; /* Temporarily holds the number of cursors assigned */
+
+ assert( pTable );
+
+ /* A positive nCol means the columns names for this view are
+ ** already known.
+ */
+ if( pTable->nCol>0 ) return 0;
+
+ /* A negative nCol is a special marker meaning that we are currently
+ ** trying to compute the column names. If we enter this routine with
+ ** a negative nCol, it means two or more views form a loop, like this:
+ **
+ ** CREATE VIEW one AS SELECT * FROM two;
+ ** CREATE VIEW two AS SELECT * FROM one;
+ **
+ ** 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( pTable->nCol<0 ){
+ sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
+ return 1;
+ }
+
+ /* If we get this far, it means we need to compute the table names.
+ ** Note that the call to sqlite3ResultSetOfSelect() will expand any
+ ** "*" elements in the results set of the view and will assign cursors
+ ** to the elements of the FROM clause. But we do not want these changes
+ ** to be permanent. So the computation is done on a copy of the SELECT
+ ** statement that defines the view.
+ */
+ assert( pTable->pSelect );
+ pSel = sqlite3SelectDup(pTable->pSelect);
+ n = pParse->nTab;
+ sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
+ pTable->nCol = -1;
+ pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
+ pParse->nTab = n;
+ if( pSelTab ){
+ assert( pTable->aCol==0 );
+ pTable->nCol = pSelTab->nCol;
+ pTable->aCol = pSelTab->aCol;
+ pSelTab->nCol = 0;
+ pSelTab->aCol = 0;
+ sqlite3DeleteTable(0, pSelTab);
+ DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
+ }else{
+ pTable->nCol = 0;
+ nErr++;
+ }
+ sqlite3SelectDelete(pSel);
+ return nErr;
+}
+#endif /* SQLITE_OMIT_VIEW */
+
+#ifndef SQLITE_OMIT_VIEW
+/*
+** Clear the column names from every VIEW in database idx.
+*/
+static void sqliteViewResetAll(sqlite3 *db, int idx){
+ HashElem *i;
+ if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
+ for(i=sqliteHashFirst(&db->aDb[idx].tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ if( pTab->pSelect ){
+ sqliteResetColumnNames(pTab);
+ }
+ }
+ DbClearProperty(db, idx, DB_UnresetViews);
+}
+#else
+# define sqliteViewResetAll(A,B)
+#endif /* SQLITE_OMIT_VIEW */
+
+/*
+** This function is called by the VDBE to adjust the internal schema
+** used by SQLite when the btree layer moves a table root page. The
+** root-page of a table or index in database iDb has changed from iFrom
+** to iTo.
+*/
+#ifndef SQLITE_OMIT_AUTOVACUUM
+void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
+ HashElem *pElem;
+
+ for(pElem=sqliteHashFirst(&pDb->tblHash); pElem; pElem=sqliteHashNext(pElem)){
+ Table *pTab = sqliteHashData(pElem);
+ if( pTab->tnum==iFrom ){
+ pTab->tnum = iTo;
+ return;
+ }
+ }
+ for(pElem=sqliteHashFirst(&pDb->idxHash); pElem; pElem=sqliteHashNext(pElem)){
+ Index *pIdx = sqliteHashData(pElem);
+ if( pIdx->tnum==iFrom ){
+ pIdx->tnum = iTo;
+ return;
+ }
+ }
+ assert(0);
+}
+#endif
+
+/*
+** Write code to erase the table with root-page iTable from database iDb.
+** Also write code to modify the sqlite_master table and internal schema
+** if a root-page of another table is moved by the btree-layer whilst
+** erasing iTable (this can happen with an auto-vacuum database).
+*/
+static void destroyRootPage(Parse *pParse, int iTable, int iDb){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* OP_Destroy pushes an integer onto the stack. If this integer
+ ** is non-zero, then it is the root page number of a table moved to
+ ** location iTable. The following code modifies the sqlite_master table to
+ ** reflect this.
+ **
+ ** The "#0" in the SQL is a special constant that means whatever value
+ ** is on the top of the stack. See sqlite3RegisterExpr().
+ */
+ sqlite3NestedParse(pParse,
+ "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0",
+ pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable);
+#endif
+}
+
+/*
+** Write VDBE code to erase table pTab and all associated indices on disk.
+** Code to update the sqlite_master tables and internal schema definitions
+** in case a root-page belonging to another table is moved by the btree layer
+** is also added (this can happen with an auto-vacuum database).
+*/
+static void destroyTable(Parse *pParse, Table *pTab){
+#ifdef SQLITE_OMIT_AUTOVACUUM
+ Index *pIdx;
+ destroyRootPage(pParse, pTab->tnum, pTab->iDb);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ destroyRootPage(pParse, pIdx->tnum, pIdx->iDb);
+ }
+#else
+ /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
+ ** is not defined), then it is important to call OP_Destroy on the
+ ** table and index root-pages in order, starting with the numerically
+ ** largest root-page number. This guarantees that none of the root-pages
+ ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
+ ** following were coded:
+ **
+ ** OP_Destroy 4 0
+ ** ...
+ ** OP_Destroy 5 0
+ **
+ ** and root page 5 happened to be the largest root-page number in the
+ ** database, then root page 5 would be moved to page 4 by the
+ ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit
+ ** a free-list page.
+ */
+ int iTab = pTab->tnum;
+ int iDestroyed = 0;
+
+ while( 1 ){
+ Index *pIdx;
+ int iLargest = 0;
+
+ if( iDestroyed==0 || iTab<iDestroyed ){
+ iLargest = iTab;
+ }
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int iIdx = pIdx->tnum;
+ assert( pIdx->iDb==pTab->iDb );
+ if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
+ iLargest = iIdx;
+ }
+ }
+ if( iLargest==0 ) return;
+ destroyRootPage(pParse, iLargest, pTab->iDb);
+ iDestroyed = iLargest;
+ }
+#endif
+}
+
+/*
+** This routine is called to do the work of a DROP TABLE statement.
+** pName is the name of the table to be dropped.
+*/
+void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
+ Table *pTab;
+ Vdbe *v;
+ sqlite3 *db = pParse->db;
+ int iDb;
+
+ if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table;
+ assert( pName->nSrc==1 );
+ pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);
+
+ if( pTab==0 ) goto exit_drop_table;
+ iDb = pTab->iDb;
+ assert( iDb>=0 && iDb<db->nDb );
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int code;
+ const char *zTab = SCHEMA_TABLE(pTab->iDb);
+ const char *zDb = db->aDb[pTab->iDb].zName;
+ if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
+ goto exit_drop_table;
+ }
+ if( isView ){
+ if( !OMIT_TEMPDB && iDb==1 ){
+ code = SQLITE_DROP_TEMP_VIEW;
+ }else{
+ code = SQLITE_DROP_VIEW;
+ }
+ }else{
+ if( !OMIT_TEMPDB && iDb==1 ){
+ code = SQLITE_DROP_TEMP_TABLE;
+ }else{
+ code = SQLITE_DROP_TABLE;
+ }
+ }
+ if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){
+ goto exit_drop_table;
+ }
+ if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
+ goto exit_drop_table;
+ }
+ }
+#endif
+ if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){
+ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
+ goto exit_drop_table;
+ }
+
+#ifndef SQLITE_OMIT_VIEW
+ /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
+ ** on a table.
+ */
+ if( isView && pTab->pSelect==0 ){
+ sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
+ goto exit_drop_table;
+ }
+ if( !isView && pTab->pSelect ){
+ sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
+ goto exit_drop_table;
+ }
+#endif
+
+ /* Generate code to remove the table from the master table
+ ** on disk.
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v ){
+ Trigger *pTrigger;
+ int iDb = pTab->iDb;
+ Db *pDb = &db->aDb[iDb];
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+
+ /* Drop all triggers associated with the table being dropped. Code
+ ** is generated to remove entries from sqlite_master and/or
+ ** sqlite_temp_master if required.
+ */
+ pTrigger = pTab->pTrigger;
+ while( pTrigger ){
+ assert( pTrigger->iDb==iDb || pTrigger->iDb==1 );
+ sqlite3DropTriggerPtr(pParse, pTrigger, 1);
+ pTrigger = pTrigger->pNext;
+ }
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ /* Remove any entries of the sqlite_sequence table associated with
+ ** the table being dropped. This is done before the table is dropped
+ ** at the btree level, in case the sqlite_sequence table needs to
+ ** move as a result of the drop (can happen in auto-vacuum mode).
+ */
+ if( pTab->autoInc ){
+ sqlite3NestedParse(pParse,
+ "DELETE FROM %s.sqlite_sequence WHERE name=%Q",
+ pDb->zName, pTab->zName
+ );
+ }
+#endif
+
+ /* Drop all SQLITE_MASTER table and index entries that refer to the
+ ** table. The program name loops through the master table and deletes
+ ** every row that refers to a table of the same name as the one being
+ ** dropped. Triggers are handled seperately because a trigger can be
+ ** created in the temp database that refers to a table in another
+ ** database.
+ */
+ sqlite3NestedParse(pParse,
+ "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
+ pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
+ if( !isView ){
+ destroyTable(pParse, pTab);
+ }
+
+ /* Remove the table entry from SQLite's internal schema and modify
+ ** the schema cookie.
+ */
+ sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
+ sqlite3ChangeCookie(db, v, iDb);
+ }
+ sqliteViewResetAll(db, iDb);
+
+exit_drop_table:
+ sqlite3SrcListDelete(pName);
+}
+
+/*
+** This routine is called to create a new foreign key on the table
+** currently under construction. pFromCol determines which columns
+** in the current table point to the foreign key. If pFromCol==0 then
+** connect the key to the last column inserted. pTo is the name of
+** the table referred to. pToCol is a list of tables in the other
+** pTo table that the foreign key points to. flags contains all
+** information about the conflict resolution algorithms specified
+** in the ON DELETE, ON UPDATE and ON INSERT clauses.
+**
+** An FKey structure is created and added to the table currently
+** under construction in the pParse->pNewTable field. The new FKey
+** is not linked into db->aFKey at this point - that does not happen
+** until sqlite3EndTable().
+**
+** The foreign key is set for IMMEDIATE processing. A subsequent call
+** to sqlite3DeferForeignKey() might change this to DEFERRED.
+*/
+void sqlite3CreateForeignKey(
+ Parse *pParse, /* Parsing context */
+ ExprList *pFromCol, /* Columns in this table that point to other table */
+ Token *pTo, /* Name of the other table */
+ ExprList *pToCol, /* Columns in the other table */
+ int flags /* Conflict resolution algorithms. */
+){
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ FKey *pFKey = 0;
+ Table *p = pParse->pNewTable;
+ int nByte;
+ int i;
+ int nCol;
+ char *z;
+
+ assert( pTo!=0 );
+ if( p==0 || pParse->nErr ) goto fk_end;
+ if( pFromCol==0 ){
+ int iCol = p->nCol-1;
+ if( iCol<0 ) goto fk_end;
+ if( pToCol && pToCol->nExpr!=1 ){
+ sqlite3ErrorMsg(pParse, "foreign key on %s"
+ " should reference only one column of table %T",
+ p->aCol[iCol].zName, pTo);
+ goto fk_end;
+ }
+ nCol = 1;
+ }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){
+ sqlite3ErrorMsg(pParse,
+ "number of columns in foreign key does not match the number of "
+ "columns in the referenced table");
+ goto fk_end;
+ }else{
+ nCol = pFromCol->nExpr;
+ }
+ nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1;
+ if( pToCol ){
+ for(i=0; i<pToCol->nExpr; i++){
+ nByte += strlen(pToCol->a[i].zName) + 1;
+ }
+ }
+ pFKey = sqliteMalloc( nByte );
+ if( pFKey==0 ) goto fk_end;
+ pFKey->pFrom = p;
+ pFKey->pNextFrom = p->pFKey;
+ z = (char*)&pFKey[1];
+ pFKey->aCol = (struct sColMap*)z;
+ z += sizeof(struct sColMap)*nCol;
+ pFKey->zTo = z;
+ memcpy(z, pTo->z, pTo->n);
+ z[pTo->n] = 0;
+ z += pTo->n+1;
+ pFKey->pNextTo = 0;
+ pFKey->nCol = nCol;
+ if( pFromCol==0 ){
+ pFKey->aCol[0].iFrom = p->nCol-1;
+ }else{
+ for(i=0; i<nCol; i++){
+ int j;
+ for(j=0; j<p->nCol; j++){
+ if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
+ pFKey->aCol[i].iFrom = j;
+ break;
+ }
+ }
+ if( j>=p->nCol ){
+ sqlite3ErrorMsg(pParse,
+ "unknown column \"%s\" in foreign key definition",
+ pFromCol->a[i].zName);
+ goto fk_end;
+ }
+ }
+ }
+ if( pToCol ){
+ for(i=0; i<nCol; i++){
+ int n = strlen(pToCol->a[i].zName);
+ pFKey->aCol[i].zCol = z;
+ memcpy(z, pToCol->a[i].zName, n);
+ z[n] = 0;
+ z += n+1;
+ }
+ }
+ pFKey->isDeferred = 0;
+ pFKey->deleteConf = flags & 0xff;
+ pFKey->updateConf = (flags >> 8 ) & 0xff;
+ pFKey->insertConf = (flags >> 16 ) & 0xff;
+
+ /* Link the foreign key to the table as the last step.
+ */
+ p->pFKey = pFKey;
+ pFKey = 0;
+
+fk_end:
+ sqliteFree(pFKey);
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
+ sqlite3ExprListDelete(pFromCol);
+ sqlite3ExprListDelete(pToCol);
+}
+
+/*
+** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED
+** clause is seen as part of a foreign key definition. The isDeferred
+** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE.
+** The behavior of the most recently created foreign key is adjusted
+** accordingly.
+*/
+void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ Table *pTab;
+ FKey *pFKey;
+ if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
+ pFKey->isDeferred = isDeferred;
+#endif
+}
+
+/*
+** Generate code that will erase and refill index *pIdx. This is
+** used to initialize a newly created index or to recompute the
+** content of an index in response to a REINDEX command.
+**
+** if memRootPage is not negative, it means that the index is newly
+** created. The memory cell specified by memRootPage contains the
+** root page number of the index. If memRootPage is negative, then
+** the index already exists and must be cleared before being refilled and
+** the root page number of the index is taken from pIndex->tnum.
+*/
+static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
+ Table *pTab = pIndex->pTable; /* The table that is indexed */
+ int iTab = pParse->nTab; /* Btree cursor used for pTab */
+ int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */
+ int addr1; /* Address of top of loop */
+ int tnum; /* Root page of index */
+ Vdbe *v; /* Generate code into this virtual machine */
+ int isUnique; /* True for a unique index */
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
+ pParse->db->aDb[pIndex->iDb].zName ) ){
+ return;
+ }
+#endif
+
+ /* Ensure all the required collation sequences are available. This
+ ** routine will invoke the collation-needed callback if necessary (and
+ ** if one has been registered).
+ */
+ if( sqlite3CheckIndexCollSeq(pParse, pIndex) ){
+ return;
+ }
+
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return;
+ if( memRootPage>=0 ){
+ sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0);
+ tnum = 0;
+ }else{
+ tnum = pIndex->tnum;
+ sqlite3VdbeAddOp(v, OP_Clear, tnum, pIndex->iDb);
+ }
+ sqlite3VdbeAddOp(v, OP_Integer, pIndex->iDb, 0);
+ sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum,
+ (char*)&pIndex->keyInfo, P3_KEYINFO);
+ sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqlite3VdbeAddOp(v, OP_OpenRead, iTab, pTab->tnum);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pTab->nCol);
+ addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
+ sqlite3GenerateIndexKey(v, pIndex, iTab);
+ isUnique = pIndex->onError!=OE_None;
+ sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, isUnique);
+ if( isUnique ){
+ sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
+ }
+ sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1);
+ sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v));
+ sqlite3VdbeAddOp(v, OP_Close, iTab, 0);
+ sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
+}
+
+/*
+** Create a new index for an SQL table. pName1.pName2 is the name of the index
+** and pTblList is the name of the table that is to be indexed. Both will
+** be NULL for a primary key or an index that is created to satisfy a
+** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable
+** as the table to be indexed. pParse->pNewTable is a table that is
+** currently being constructed by a CREATE TABLE statement.
+**
+** pList is a list of columns to be indexed. pList will be NULL if this
+** is a primary key or unique-constraint on the most recent column added
+** to the table currently under construction.
+*/
+void sqlite3CreateIndex(
+ Parse *pParse, /* All information about this parse */
+ Token *pName1, /* First part of index name. May be NULL */
+ Token *pName2, /* Second part of index name. May be NULL */
+ SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
+ ExprList *pList, /* A list of columns to be indexed */
+ int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
+ Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */
+ Token *pEnd /* The ")" that closes the CREATE INDEX statement */
+){
+ Table *pTab = 0; /* Table to be indexed */
+ Index *pIndex = 0; /* The index to be created */
+ char *zName = 0;
+ int i, j;
+ Token nullId; /* Fake token for an empty ID list */
+ DbFixer sFix; /* For assigning database names to pTable */
+ sqlite3 *db = pParse->db;
+
+ int iDb; /* Index of the database that is being written */
+ Token *pName = 0; /* Unqualified name of the index to create */
+
+ if( pParse->nErr || sqlite3_malloc_failed ) goto exit_create_index;
+
+ /*
+ ** Find the table that is to be indexed. Return early if not found.
+ */
+ if( pTblName!=0 ){
+
+ /* Use the two-part index name to determine the database
+ ** to search for the table. 'Fix' the table name to this db
+ ** before looking up the table.
+ */
+ assert( pName1 && pName2 );
+ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+ if( iDb<0 ) goto exit_create_index;
+
+#ifndef SQLITE_OMIT_TEMPDB
+ /* If the index name was unqualified, check if the the table
+ ** is a temp table. If so, set the database to 1.
+ */
+ pTab = sqlite3SrcListLookup(pParse, pTblName);
+ if( pName2 && pName2->n==0 && pTab && pTab->iDb==1 ){
+ iDb = 1;
+ }
+#endif
+
+ if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
+ sqlite3FixSrcList(&sFix, pTblName)
+ ){
+ goto exit_create_index;
+ }
+ pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName,
+ pTblName->a[0].zDatabase);
+ if( !pTab ) goto exit_create_index;
+ assert( iDb==pTab->iDb );
+ }else{
+ assert( pName==0 );
+ pTab = pParse->pNewTable;
+ iDb = pTab->iDb;
+ }
+
+ if( pTab==0 || pParse->nErr ) goto exit_create_index;
+ if( pTab->readOnly ){
+ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
+ goto exit_create_index;
+ }
+#ifndef SQLITE_OMIT_VIEW
+ if( pTab->pSelect ){
+ sqlite3ErrorMsg(pParse, "views may not be indexed");
+ goto exit_create_index;
+ }
+#endif
+
+ /*
+ ** Find the name of the index. Make sure there is not already another
+ ** index or table with the same name.
+ **
+ ** Exception: If we are reading the names of permanent indices from the
+ ** sqlite_master table (because some other process changed the schema) and
+ ** one of the index names collides with the name of a temporary table or
+ ** index, then we will continue to process this index.
+ **
+ ** If pName==0 it means that we are
+ ** dealing with a primary key or UNIQUE constraint. We have to invent our
+ ** own name.
+ */
+ if( pName ){
+ zName = sqlite3NameFromToken(pName);
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
+ if( zName==0 ) goto exit_create_index;
+ if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ goto exit_create_index;
+ }
+ if( !db->init.busy ){
+ Index *pISameName; /* Another index with the same name */
+ Table *pTSameName; /* A table with same name as the index */
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
+ if( (pISameName = sqlite3FindIndex(db, zName, db->aDb[iDb].zName))!=0 ){
+ sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+ goto exit_create_index;
+ }
+ if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
+ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
+ goto exit_create_index;
+ }
+ }
+ }else{
+ char zBuf[30];
+ int n;
+ Index *pLoop;
+ for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
+ sprintf(zBuf,"_%d",n);
+ zName = 0;
+ sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0);
+ if( zName==0 ) goto exit_create_index;
+ }
+
+ /* Check for authorization to create an index.
+ */
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ const char *zDb = db->aDb[iDb].zName;
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
+ goto exit_create_index;
+ }
+ i = SQLITE_CREATE_INDEX;
+ if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
+ if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
+ goto exit_create_index;
+ }
+ }
+#endif
+
+ /* If pList==0, it means this routine was called to make a primary
+ ** key out of the last column added to the table under construction.
+ ** So create a fake list to simulate this.
+ */
+ if( pList==0 ){
+ nullId.z = pTab->aCol[pTab->nCol-1].zName;
+ nullId.n = strlen(nullId.z);
+ pList = sqlite3ExprListAppend(0, 0, &nullId);
+ if( pList==0 ) goto exit_create_index;
+ }
+
+ /*
+ ** Allocate the index structure.
+ */
+ pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
+ (sizeof(int) + 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];
+ strcpy(pIndex->zName, zName);
+ pIndex->pTable = pTab;
+ pIndex->nColumn = pList->nExpr;
+ pIndex->onError = onError;
+ pIndex->autoIndex = pName==0;
+ pIndex->iDb = iDb;
+
+ /* Scan the names of the columns of the table to be indexed and
+ ** load the column indices into the Index structure. Report an error
+ ** if any column is not found.
+ */
+ for(i=0; i<pList->nExpr; i++){
+ for(j=0; j<pTab->nCol; j++){
+ if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
+ }
+ if( j>=pTab->nCol ){
+ sqlite3ErrorMsg(pParse, "table %s has no column named %s",
+ pTab->zName, pList->a[i].zName);
+ goto exit_create_index;
+ }
+ pIndex->aiColumn[i] = j;
+ if( pList->a[i].pExpr ){
+ assert( pList->a[i].pExpr->pColl );
+ pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl;
+ }else{
+ pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;
+ }
+ assert( pIndex->keyInfo.aColl[i] );
+ if( !db->init.busy &&
+ sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i])
+ ){
+ goto exit_create_index;
+ }
+ }
+ pIndex->keyInfo.nField = pList->nExpr;
+
+ if( pTab==pParse->pNewTable ){
+ /* This routine has been called to create an automatic index as a
+ ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
+ ** a PRIMARY KEY or UNIQUE clause following the column definitions.
+ ** i.e. one of:
+ **
+ ** CREATE TABLE t(x PRIMARY KEY, y);
+ ** CREATE TABLE t(x, y, UNIQUE(x, y));
+ **
+ ** Either way, check to see if the table already has such an index. If
+ ** so, don't bother creating this one. This only applies to
+ ** automatically created indices. Users can do as they wish with
+ ** explicit indices.
+ */
+ Index *pIdx;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int k;
+ assert( pIdx->onError!=OE_None );
+ assert( pIdx->autoIndex );
+ assert( pIndex->onError!=OE_None );
+
+ if( pIdx->nColumn!=pIndex->nColumn ) continue;
+ for(k=0; k<pIdx->nColumn; k++){
+ if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
+ if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;
+ }
+ if( k==pIdx->nColumn ){
+ if( pIdx->onError!=pIndex->onError ){
+ /* This constraint creates the same index as a previous
+ ** constraint specified somewhere in the CREATE TABLE statement.
+ ** However the ON CONFLICT clauses are different. If both this
+ ** constraint and the previous equivalent constraint have explicit
+ ** ON CONFLICT clauses this is an error. Otherwise, use the
+ ** explicitly specified behaviour for the index.
+ */
+ if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
+ sqlite3ErrorMsg(pParse,
+ "conflicting ON CONFLICT clauses specified", 0);
+ }
+ if( pIdx->onError==OE_Default ){
+ pIdx->onError = pIndex->onError;
+ }
+ }
+ goto exit_create_index;
+ }
+ }
+ }
+
+ /* Link the new Index structure to its table and to the other
+ ** in-memory database structures.
+ */
+ if( db->init.busy ){
+ Index *p;
+ p = sqlite3HashInsert(&db->aDb[pIndex->iDb].idxHash,
+ pIndex->zName, strlen(pIndex->zName)+1, pIndex);
+ if( p ){
+ assert( p==pIndex ); /* Malloc must have failed */
+ goto exit_create_index;
+ }
+ db->flags |= SQLITE_InternChanges;
+ if( pTblName!=0 ){
+ pIndex->tnum = db->init.newTnum;
+ }
+ }
+
+ /* If the db->init.busy is 0 then create the index on disk. This
+ ** involves writing the index into the master table and filling in the
+ ** index with the current table contents.
+ **
+ ** The db->init.busy is 0 when the user first enters a CREATE INDEX
+ ** command. db->init.busy is 1 when a database is opened and
+ ** CREATE INDEX statements are read out of the master table. In
+ ** the latter case the index already exists on disk, which is why
+ ** we don't want to recreate it.
+ **
+ ** If pTblName==0 it means this index is generated as a primary key
+ ** or UNIQUE constraint of a CREATE TABLE statement. Since the table
+ ** has just been created, it contains no data and the index initialization
+ ** step can be skipped.
+ */
+ else if( db->init.busy==0 ){
+ Vdbe *v;
+ char *zStmt;
+ int iMem = pParse->nMem++;
+
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto exit_create_index;
+
+ /* Create the rootpage for the index
+ */
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
+ sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
+
+ /* Gather the complete text of the CREATE INDEX statement into
+ ** the zStmt variable
+ */
+ if( pStart && pEnd ){
+ /* A named index with an explicit CREATE INDEX statement */
+ zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s",
+ onError==OE_None ? "" : " UNIQUE",
+ pEnd->z - pName->z + 1,
+ pName->z);
+ }else{
+ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
+ /* zStmt = sqlite3MPrintf(""); */
+ zStmt = 0;
+ }
+
+ /* Add an entry in sqlite_master for this index
+ */
+ sqlite3NestedParse(pParse,
+ "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);",
+ db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
+ pIndex->zName,
+ pTab->zName,
+ zStmt
+ );
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteFree(zStmt);
+
+ /* Fill the index with data and reparse the schema. Code an OP_Expire
+ ** to invalidate all pre-compiled statements.
+ */
+ if( pTblName ){
+ sqlite3RefillIndex(pParse, pIndex, iMem);
+ sqlite3ChangeCookie(db, v, iDb);
+ sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
+ sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC);
+ sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
+ }
+ }
+
+ /* When adding an index to the list of indices for a table, make
+ ** sure all indices labeled OE_Replace come after all those labeled
+ ** OE_Ignore. This is necessary for the correct operation of UPDATE
+ ** and INSERT.
+ */
+ if( db->init.busy || pTblName==0 ){
+ if( onError!=OE_Replace || pTab->pIndex==0
+ || pTab->pIndex->onError==OE_Replace){
+ pIndex->pNext = pTab->pIndex;
+ pTab->pIndex = pIndex;
+ }else{
+ Index *pOther = pTab->pIndex;
+ while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
+ pOther = pOther->pNext;
+ }
+ pIndex->pNext = pOther->pNext;
+ pOther->pNext = pIndex;
+ }
+ pIndex = 0;
+ }
+
+ /* Clean up before exiting */
+exit_create_index:
+ if( pIndex ){
+ freeIndex(pIndex);
+ }
+ sqlite3ExprListDelete(pList);
+ sqlite3SrcListDelete(pTblName);
+ sqliteFree(zName);
+ return;
+}
+
+/*
+** This routine will drop an existing named index. This routine
+** implements the DROP INDEX statement.
+*/
+void sqlite3DropIndex(Parse *pParse, SrcList *pName){
+ Index *pIndex;
+ Vdbe *v;
+ sqlite3 *db = pParse->db;
+
+ if( pParse->nErr || sqlite3_malloc_failed ){
+ goto exit_drop_index;
+ }
+ assert( pName->nSrc==1 );
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+ goto exit_drop_index;
+ }
+ pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
+ if( pIndex==0 ){
+ sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
+ pParse->checkSchema = 1;
+ goto exit_drop_index;
+ }
+ if( pIndex->autoIndex ){
+ sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
+ "or PRIMARY KEY constraint cannot be dropped", 0);
+ goto exit_drop_index;
+ }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int code = SQLITE_DROP_INDEX;
+ Table *pTab = pIndex->pTable;
+ const char *zDb = db->aDb[pIndex->iDb].zName;
+ const char *zTab = SCHEMA_TABLE(pIndex->iDb);
+ if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
+ goto exit_drop_index;
+ }
+ if( !OMIT_TEMPDB && pIndex->iDb ) code = SQLITE_DROP_TEMP_INDEX;
+ if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
+ goto exit_drop_index;
+ }
+ }
+#endif
+
+ /* Generate code to remove the index and from the master table */
+ v = sqlite3GetVdbe(pParse);
+ if( v ){
+ int iDb = pIndex->iDb;
+ sqlite3NestedParse(pParse,
+ "DELETE FROM %Q.%s WHERE name=%Q",
+ db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
+ pIndex->zName
+ );
+ sqlite3ChangeCookie(db, v, iDb);
+ destroyRootPage(pParse, pIndex->tnum, iDb);
+ sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0);
+ }
+
+exit_drop_index:
+ sqlite3SrcListDelete(pName);
+}
+
+/*
+** Append a new element to the given IdList. Create a new IdList if
+** need be.
+**
+** A new IdList is returned, or NULL if malloc() fails.
+*/
+IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){
+ if( pList==0 ){
+ pList = sqliteMalloc( sizeof(IdList) );
+ if( pList==0 ) return 0;
+ pList->nAlloc = 0;
+ }
+ if( pList->nId>=pList->nAlloc ){
+ struct IdList_item *a;
+ pList->nAlloc = pList->nAlloc*2 + 5;
+ a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
+ if( a==0 ){
+ sqlite3IdListDelete(pList);
+ return 0;
+ }
+ pList->a = a;
+ }
+ memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
+ pList->a[pList->nId].zName = sqlite3NameFromToken(pToken);
+ pList->nId++;
+ return pList;
+}
+
+/*
+** 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.
+**
+** A new SrcList is returned, or NULL if malloc() fails.
+**
+** If pDatabase is not null, it means that the table has an optional
+** database name prefix. Like this: "database.table". The pDatabase
+** points to the table name and the pTable points to the database name.
+** The SrcList.a[].zName field is filled with the table name which might
+** come from pTable (if pDatabase is NULL) or from pDatabase.
+** SrcList.a[].zDatabase is filled with the database name from pTable,
+** or with NULL if no database is specified.
+**
+** In other words, if call like this:
+**
+** sqlite3SrcListAppend(A,B,0);
+**
+** Then B is a table name and the database name is unspecified. If called
+** like this:
+**
+** sqlite3SrcListAppend(A,B,C);
+**
+** Then C is the table name and B is the database name.
+*/
+SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
+ struct SrcList_item *pItem;
+ if( pList==0 ){
+ pList = sqliteMalloc( sizeof(SrcList) );
+ if( pList==0 ) return 0;
+ pList->nAlloc = 1;
+ }
+ if( pList->nSrc>=pList->nAlloc ){
+ SrcList *pNew;
+ pList->nAlloc *= 2;
+ pNew = sqliteRealloc(pList,
+ sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
+ if( pNew==0 ){
+ sqlite3SrcListDelete(pList);
+ return 0;
+ }
+ pList = pNew;
+ }
+ pItem = &pList->a[pList->nSrc];
+ memset(pItem, 0, sizeof(pList->a[0]));
+ if( pDatabase && pDatabase->z==0 ){
+ pDatabase = 0;
+ }
+ if( pDatabase && pTable ){
+ Token *pTemp = pDatabase;
+ pDatabase = pTable;
+ pTable = pTemp;
+ }
+ pItem->zName = sqlite3NameFromToken(pTable);
+ pItem->zDatabase = sqlite3NameFromToken(pDatabase);
+ pItem->iCursor = -1;
+ pList->nSrc++;
+ return pList;
+}
+
+/*
+** Assign cursors to all tables in a SrcList
+*/
+void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
+ int i;
+ struct SrcList_item *pItem;
+ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
+ if( pItem->iCursor>=0 ) break;
+ pItem->iCursor = pParse->nTab++;
+ if( pItem->pSelect ){
+ sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
+ }
+ }
+}
+
+/*
+** Add an alias to the last identifier on the given identifier list.
+*/
+void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){
+ if( pList && pList->nSrc>0 ){
+ pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken);
+ }
+}
+
+/*
+** Delete an IdList.
+*/
+void sqlite3IdListDelete(IdList *pList){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nId; 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; i<pList->nId; i++){
+ if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
+ }
+ return -1;
+}
+
+/*
+** Delete an entire SrcList including all its substructure.
+*/
+void sqlite3SrcListDelete(SrcList *pList){
+ int i;
+ struct SrcList_item *pItem;
+ if( pList==0 ) return;
+ for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
+ sqliteFree(pItem->zDatabase);
+ sqliteFree(pItem->zName);
+ sqliteFree(pItem->zAlias);
+ sqlite3DeleteTable(0, pItem->pTab);
+ sqlite3SelectDelete(pItem->pSelect);
+ sqlite3ExprDelete(pItem->pOn);
+ sqlite3IdListDelete(pItem->pUsing);
+ }
+ sqliteFree(pList);
+}
+
+/*
+** Begin a transaction
+*/
+void sqlite3BeginTransaction(Parse *pParse, int type){
+ sqlite3 *db;
+ Vdbe *v;
+ int i;
+
+ if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
+ if( pParse->nErr || sqlite3_malloc_failed ) return;
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
+
+ v = sqlite3GetVdbe(pParse);
+ if( !v ) return;
+ if( type!=TK_DEFERRED ){
+ for(i=0; i<db->nDb; i++){
+ sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
+}
+
+/*
+** Commit a transaction
+*/
+void sqlite3CommitTransaction(Parse *pParse){
+ sqlite3 *db;
+ Vdbe *v;
+
+ if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
+ if( pParse->nErr || sqlite3_malloc_failed ) return;
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
+
+ v = sqlite3GetVdbe(pParse);
+ if( v ){
+ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
+ }
+}
+
+/*
+** Rollback a transaction
+*/
+void sqlite3RollbackTransaction(Parse *pParse){
+ sqlite3 *db;
+ Vdbe *v;
+
+ if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
+ if( pParse->nErr || sqlite3_malloc_failed ) return;
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
+
+ v = sqlite3GetVdbe(pParse);
+ if( v ){
+ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
+ }
+}
+
+/*
+** Make sure the TEMP database is open and available for use. Return
+** the number of errors. Leave any error messages in the pParse structure.
+*/
+static int sqlite3OpenTempDatabase(Parse *pParse){
+ sqlite3 *db = pParse->db;
+ if( db->aDb[1].pBt==0 && !pParse->explain ){
+ int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
+ if( rc!=SQLITE_OK ){
+ sqlite3ErrorMsg(pParse, "unable to open a temporary database "
+ "file for storing temporary tables");
+ pParse->rc = rc;
+ return 1;
+ }
+ if( db->flags & !db->autoCommit ){
+ rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
+ if( rc!=SQLITE_OK ){
+ sqlite3ErrorMsg(pParse, "unable to get a write lock on "
+ "the temporary database file");
+ pParse->rc = rc;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Generate VDBE code that will verify the schema cookie and start
+** a read-transaction for all named database files.
+**
+** It is important that all schema cookies be verified and all
+** read transactions be started before anything else happens in
+** the VDBE program. But this routine can be called after much other
+** code has been generated. So here is what we do:
+**
+** The first time this routine is called, we code an OP_Goto that
+** will jump to a subroutine at the end of the program. Then we
+** record every database that needs its schema verified in the
+** pParse->cookieMask field. Later, after all other code has been
+** generated, the subroutine that does the cookie verifications and
+** starts the transactions will be coded and the OP_Goto P2 value
+** will be made to point to that subroutine. The generation of the
+** cookie verification subroutine code happens in sqlite3FinishCoding().
+**
+** If iDb<0 then code the OP_Goto only - don't set flag to verify the
+** schema on any databases. This can be used to position the OP_Goto
+** early in the code, before we know if any database tables will be used.
+*/
+void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
+ sqlite3 *db;
+ Vdbe *v;
+ int mask;
+
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return; /* This only happens if there was a prior error */
+ db = pParse->db;
+ if( pParse->cookieGoto==0 ){
+ pParse->cookieGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0)+1;
+ }
+ if( iDb>=0 ){
+ assert( iDb<db->nDb );
+ assert( db->aDb[iDb].pBt!=0 || iDb==1 );
+ assert( iDb<32 );
+ mask = 1<<iDb;
+ if( (pParse->cookieMask & mask)==0 ){
+ pParse->cookieMask |= mask;
+ pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie;
+ if( !OMIT_TEMPDB && iDb==1 ){
+ sqlite3OpenTempDatabase(pParse);
+ }
+ }
+ }
+}
+
+/*
+** Generate VDBE code that prepares for doing an operation that
+** might change the database.
+**
+** This routine starts a new transaction if we are not already within
+** a transaction. If we are already within a transaction, then a checkpoint
+** is set if the setStatement parameter is true. A checkpoint should
+** be set for operations that might fail (due to a constraint) part of
+** the way through and which will need to undo some writes without having to
+** rollback the whole transaction. For operations where all constraints
+** can be checked before any changes are made to the database, it is never
+** necessary to undo a write and the checkpoint should not be set.
+**
+** Only database iDb and the temp database are made writable by this call.
+** If iDb==0, then the main and temp databases are made writable. If
+** iDb==1 then only the temp database is made writable. If iDb>1 then the
+** specified auxiliary database and the temp database are made writable.
+*/
+void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ pParse->writeMask |= 1<<iDb;
+ if( setStatement && pParse->nested==0 ){
+ sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
+ }
+ if( (OMIT_TEMPDB || iDb!=1) && pParse->db->aDb[1].pBt!=0 ){
+ sqlite3BeginWriteOperation(pParse, setStatement, 1);
+ }
+}
+
+/*
+** Check to see if pIndex uses the collating sequence pColl. Return
+** true if it does and false if it does not.
+*/
+#ifndef SQLITE_OMIT_REINDEX
+static int collationMatch(CollSeq *pColl, Index *pIndex){
+ int n = pIndex->keyInfo.nField;
+ CollSeq **pp = pIndex->keyInfo.aColl;
+ while( n-- ){
+ if( *pp==pColl ) return 1;
+ pp++;
+ }
+ return 0;
+}
+#endif
+
+/*
+** Recompute all indices of pTab that use the collating sequence pColl.
+** If pColl==0 then recompute all indices of pTab.
+*/
+#ifndef SQLITE_OMIT_REINDEX
+void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
+ Index *pIndex; /* An index associated with pTab */
+
+ for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
+ if( pColl==0 || collationMatch(pColl,pIndex) ){
+ sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);
+ sqlite3RefillIndex(pParse, pIndex, -1);
+ }
+ }
+}
+#endif
+
+/*
+** Recompute all indices of all tables in all databases where the
+** indices use the collating sequence pColl. If pColl==0 then recompute
+** all indices everywhere.
+*/
+#ifndef SQLITE_OMIT_REINDEX
+void reindexDatabases(Parse *pParse, CollSeq *pColl){
+ Db *pDb; /* A single database */
+ int iDb; /* The database index number */
+ sqlite3 *db = pParse->db; /* The database connection */
+ HashElem *k; /* For looping over tables in pDb */
+ Table *pTab; /* A table in the database */
+
+ for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
+ if( pDb==0 ) continue;
+ for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){
+ pTab = (Table*)sqliteHashData(k);
+ reindexTable(pParse, pTab, pColl);
+ }
+ }
+}
+#endif
+
+/*
+** Generate code for the REINDEX command.
+**
+** REINDEX -- 1
+** REINDEX <collation> -- 2
+** REINDEX ?<database>.?<tablename> -- 3
+** REINDEX ?<database>.?<indexname> -- 4
+**
+** Form 1 causes all indices in all attached databases to be rebuilt.
+** Form 2 rebuilds all indices in all databases that use the named
+** collating function. Forms 3 and 4 rebuild the named index or all
+** indices associated with the named table.
+*/
+#ifndef SQLITE_OMIT_REINDEX
+void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
+ CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */
+ char *z; /* Name of a table or index */
+ const char *zDb; /* Name of the database */
+ Table *pTab; /* A table in the database */
+ Index *pIndex; /* An index associated with pTab */
+ int iDb; /* The database index number */
+ sqlite3 *db = pParse->db; /* The database connection */
+ Token *pObjName; /* Name of the table or index to be reindexed */
+
+ /* Read the database schema. If an error occurs, leave an error message
+ ** and code in pParse and return NULL. */
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+ return;
+ }
+
+ if( pName1==0 || pName1->z==0 ){
+ reindexDatabases(pParse, 0);
+ return;
+ }else if( pName2==0 || pName2->z==0 ){
+ pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0);
+ if( pColl ){
+ reindexDatabases(pParse, pColl);
+ return;
+ }
+ }
+ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
+ if( iDb<0 ) return;
+ z = sqlite3NameFromToken(pObjName);
+ zDb = db->aDb[iDb].zName;
+ pTab = sqlite3FindTable(db, z, zDb);
+ if( pTab ){
+ reindexTable(pParse, pTab, 0);
+ sqliteFree(z);
+ return;
+ }
+ pIndex = sqlite3FindIndex(db, z, zDb);
+ sqliteFree(z);
+ if( pIndex ){
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3RefillIndex(pParse, pIndex, -1);
+ return;
+ }
+ sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
+}
+#endif
diff --git a/src/sqlite/callback.c b/src/sqlite/callback.c
new file mode 100644
index 0000000..a90fdf6
--- /dev/null
+++ b/src/sqlite/callback.c
@@ -0,0 +1,306 @@
+/*
+** 2005 May 23
+**
+** 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 functions used to access the internal hash tables
+** of user defined functions and collation sequences.
+**
+** $Id: callback.c,v 1.1.1.1 2006/02/03 20:35:09 hoganrobert Exp $
+*/
+
+#include "sqliteInt.h"
+
+/*
+** Invoke the 'collation needed' callback to request a collation sequence
+** in the database text encoding of name zName, length nName.
+** If the collation sequence
+*/
+static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
+ assert( !db->xCollNeeded || !db->xCollNeeded16 );
+ if( nName<0 ) nName = strlen(zName);
+ if( db->xCollNeeded ){
+ char *zExternal = sqliteStrNDup(zName, nName);
+ if( !zExternal ) return;
+ db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
+ sqliteFree(zExternal);
+ }
+#ifndef SQLITE_OMIT_UTF16
+ if( db->xCollNeeded16 ){
+ char const *zExternal;
+ sqlite3_value *pTmp = sqlite3GetTransientValue(db);
+ sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
+ zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
+ if( !zExternal ) return;
+ db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
+ }
+#endif
+}
+
+/*
+** This routine is called if the collation factory fails to deliver a
+** collation function in the best encoding but there may be other versions
+** of this collation function (for other text encodings) available. Use one
+** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
+** possible.
+*/
+static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
+ CollSeq *pColl2;
+ char *z = pColl->zName;
+ int n = strlen(z);
+ int i;
+ static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
+ for(i=0; i<3; i++){
+ pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
+ if( pColl2->xCmp!=0 ){
+ memcpy(pColl, pColl2, sizeof(CollSeq));
+ return SQLITE_OK;
+ }
+ }
+ return SQLITE_ERROR;
+}
+
+/*
+** This function is responsible for invoking the collation factory callback
+** or substituting a collation sequence of a different encoding when the
+** requested collation sequence is not available in the database native
+** encoding.
+**
+** If it is not NULL, then pColl must point to the database native encoding
+** collation sequence with name zName, length nName.
+**
+** The return value is either the collation sequence to be used in database
+** db for collation type name zName, length nName, or NULL, if no collation
+** sequence can be found.
+*/
+CollSeq *sqlite3GetCollSeq(
+ sqlite3* db,
+ CollSeq *pColl,
+ const char *zName,
+ int nName
+){
+ CollSeq *p;
+
+ p = pColl;
+ if( !p ){
+ p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
+ }
+ if( !p || !p->xCmp ){
+ /* No collation sequence of this type for this encoding is registered.
+ ** Call the collation factory to see if it can supply us with one.
+ */
+ callCollNeeded(db, zName, nName);
+ p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
+ }
+ if( p && !p->xCmp && synthCollSeq(db, p) ){
+ p = 0;
+ }
+ assert( !p || p->xCmp );
+ return p;
+}
+
+/*
+** This routine is called on a collation sequence before it is used to
+** check that it is defined. An undefined collation sequence exists when
+** a database is loaded that contains references to collation sequences
+** that have not been defined by sqlite3_create_collation() etc.
+**
+** If required, this routine calls the 'collation needed' callback to
+** request a definition of the collating sequence. If this doesn't work,
+** an equivalent collating sequence that uses a text encoding different
+** from the main database is substituted, if one is available.
+*/
+int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
+ if( pColl ){
+ const char *zName = pColl->zName;
+ CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
+ if( !p ){
+ if( pParse->nErr==0 ){
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
+ }
+ pParse->nErr++;
+ return SQLITE_ERROR;
+ }
+ }
+ return SQLITE_OK;
+}
+
+
+
+/*
+** Locate and return an entry from the db.aCollSeq hash table. If the entry
+** specified by zName and nName is not found and parameter 'create' is
+** true, then create a new entry. Otherwise return NULL.
+**
+** Each pointer stored in the sqlite3.aCollSeq hash table contains an
+** array of three CollSeq structures. The first is the collation sequence
+** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
+**
+** Stored immediately after the three collation sequences is a copy of
+** the collation sequence name. A pointer to this string is stored in
+** each collation sequence structure.
+*/
+static CollSeq * findCollSeqEntry(
+ sqlite3 *db,
+ const char *zName,
+ int nName,
+ int create
+){
+ CollSeq *pColl;
+ if( nName<0 ) nName = strlen(zName);
+ pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
+
+ if( 0==pColl && create ){
+ pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
+ if( pColl ){
+ CollSeq *pDel = 0;
+ pColl[0].zName = (char*)&pColl[3];
+ pColl[0].enc = SQLITE_UTF8;
+ pColl[1].zName = (char*)&pColl[3];
+ pColl[1].enc = SQLITE_UTF16LE;
+ pColl[2].zName = (char*)&pColl[3];
+ pColl[2].enc = SQLITE_UTF16BE;
+ memcpy(pColl[0].zName, zName, nName);
+ pColl[0].zName[nName] = 0;
+ pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
+
+ /* If a malloc() failure occured in sqlite3HashInsert(), it will
+ ** return the pColl pointer to be deleted (because it wasn't added
+ ** to the hash table).
+ */
+ assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) );
+ sqliteFree(pDel);
+ }
+ }
+ return pColl;
+}
+
+/*
+** Parameter zName points to a UTF-8 encoded string nName bytes long.
+** Return the CollSeq* pointer for the collation sequence named zName
+** for the encoding 'enc' from the database 'db'.
+**
+** If the entry specified is not found and 'create' is true, then create a
+** new entry. Otherwise return NULL.
+*/
+CollSeq *sqlite3FindCollSeq(
+ sqlite3 *db,
+ u8 enc,
+ const char *zName,
+ int nName,
+ int create
+){
+ CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);
+ assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+ assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
+ if( pColl ) pColl += enc-1;
+ return pColl;
+}
+
+/*
+** Locate a user function given a name, a number of arguments and a flag
+** indicating whether the function prefers UTF-16 over UTF-8. Return a
+** pointer to the FuncDef structure that defines that function, or return
+** NULL if the function does not exist.
+**
+** If the createFlag argument is true, then a new (blank) FuncDef
+** structure is created and liked into the "db" structure if a
+** no matching function previously existed. When createFlag is true
+** and the nArg parameter is -1, then only a function that accepts
+** any number of arguments will be returned.
+**
+** If createFlag is false and nArg is -1, then the first valid
+** function found is returned. A function is valid if either xFunc
+** or xStep is non-zero.
+**
+** If createFlag is false, then a function with the required name and
+** number of arguments may be returned even if the eTextRep flag does not
+** match that requested.
+*/
+FuncDef *sqlite3FindFunction(
+ sqlite3 *db, /* An open database */
+ const char *zName, /* Name of the function. Not null-terminated */
+ int nName, /* Number of characters in the name */
+ int nArg, /* Number of arguments. -1 means any number */
+ u8 enc, /* Preferred text encoding */
+ int createFlag /* Create new entry if true and does not otherwise exist */
+){
+ FuncDef *p; /* Iterator variable */
+ FuncDef *pFirst; /* First function with this name */
+ FuncDef *pBest = 0; /* Best match found so far */
+ int bestmatch = 0;
+
+
+ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
+ if( nArg<-1 ) nArg = -1;
+
+ pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
+ for(p=pFirst; p; p=p->pNext){
+ /* During the search for the best function definition, bestmatch is set
+ ** as follows to indicate the quality of the match with the definition
+ ** pointed to by pBest:
+ **
+ ** 0: pBest is NULL. No match has been found.
+ ** 1: A variable arguments function that prefers UTF-8 when a UTF-16
+ ** encoding is requested, or vice versa.
+ ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
+ ** requested, or vice versa.
+ ** 3: A variable arguments function using the same text encoding.
+ ** 4: A function with the exact number of arguments requested that
+ ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
+ ** 5: A function with the exact number of arguments requested that
+ ** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
+ ** 6: An exact match.
+ **
+ ** A larger value of 'matchqual' indicates a more desirable match.
+ */
+ if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
+ int match = 1; /* Quality of this match */
+ if( p->nArg==nArg || nArg==-1 ){
+ match = 4;
+ }
+ if( enc==p->iPrefEnc ){
+ match += 2;
+ }
+ else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
+ (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
+ match += 1;
+ }
+
+ if( match>bestmatch ){
+ pBest = p;
+ bestmatch = match;
+ }
+ }
+ }
+
+ /* If the createFlag parameter is true, and the seach did not reveal an
+ ** exact match for the name, number of arguments and encoding, then add a
+ ** new entry to the hash table and return it.
+ */
+ if( createFlag && bestmatch<6 &&
+ (pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){
+ pBest->nArg = nArg;
+ pBest->pNext = pFirst;
+ pBest->zName = (char*)&pBest[1];
+ pBest->iPrefEnc = enc;
+ memcpy(pBest->zName, zName, nName);
+ pBest->zName[nName] = 0;
+ if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
+ sqliteFree(pBest);
+ return 0;
+ }
+ }
+
+ if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
+ return pBest;
+ }
+ return 0;
+}
diff --git a/src/sqlite/date.c b/src/sqlite/date.c
new file mode 100644
index 0000000..dd6e521
--- /dev/null
+++ b/src/sqlite/date.c
@@ -0,0 +1,1000 @@
+/*
+** 2003 October 31
+**
+** 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 the C functions that implement date and time
+** functions for SQLite.
+**
+** There is only one exported symbol in this file - the function
+** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
+** All other code has file scope.
+**
+** $Id: date.c,v 1.1.1.1 2006/02/03 20:35:11 hoganrobert Exp $
+**
+** NOTES:
+**
+** SQLite processes all times and dates as Julian Day numbers. The
+** dates and times are stored as the number of days since noon
+** in Greenwich on November 24, 4714 B.C. according to the Gregorian
+** calendar system.
+**
+** 1970-01-01 00:00:00 is JD 2440587.5
+** 2000-01-01 00:00:00 is JD 2451544.5
+**
+** This implemention requires years to be expressed as a 4-digit number
+** which means that only dates between 0000-01-01 and 9999-12-31 can
+** be represented, even though julian day numbers allow a much wider
+** range of dates.
+**
+** The Gregorian calendar system is used for all dates and times,
+** even those that predate the Gregorian calendar. Historians usually
+** use the Julian calendar for dates prior to 1582-10-15 and for some
+** dates afterwards, depending on locale. Beware of this difference.
+**
+** The conversion algorithms are implemented based on descriptions
+** in the following text:
+**
+** Jean Meeus
+** Astronomical Algorithms, 2nd Edition, 1998
+** ISBM 0-943396-61-1
+** Willmann-Bell, Inc
+** Richmond, Virginia (USA)
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+
+#ifndef SQLITE_OMIT_DATETIME_FUNCS
+
+/*
+** A structure for holding a single date and time.
+*/
+typedef struct DateTime DateTime;
+struct DateTime {
+ double rJD; /* The julian day number */
+ int Y, M, D; /* Year, month, and day */
+ int h, m; /* Hour and minutes */
+ int tz; /* Timezone offset in minutes */
+ double s; /* Seconds */
+ char validYMD; /* True if Y,M,D are valid */
+ char validHMS; /* True if h,m,s are valid */
+ char validJD; /* True if rJD is valid */
+ char validTZ; /* True if tz is valid */
+};
+
+
+/*
+** Convert zDate into one or more integers. Additional arguments
+** come in groups of 5 as follows:
+**
+** N number of digits in the integer
+** min minimum allowed value of the integer
+** max maximum allowed value of the integer
+** nextC first character after the integer
+** pVal where to write the integers value.
+**
+** Conversions continue until one with nextC==0 is encountered.
+** The function returns the number of successful conversions.
+*/
+static int getDigits(const char *zDate, ...){
+ va_list ap;
+ int val;
+ int N;
+ int min;
+ int max;
+ int nextC;
+ int *pVal;
+ int cnt = 0;
+ va_start(ap, zDate);
+ do{
+ N = va_arg(ap, int);
+ min = va_arg(ap, int);
+ max = va_arg(ap, int);
+ nextC = va_arg(ap, int);
+ pVal = va_arg(ap, int*);
+ val = 0;
+ while( N-- ){
+ if( !isdigit(*(u8*)zDate) ){
+ return cnt;
+ }
+ val = val*10 + *zDate - '0';
+ zDate++;
+ }
+ if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
+ return cnt;
+ }
+ *pVal = val;
+ zDate++;
+ cnt++;
+ }while( nextC );
+ return cnt;
+}
+
+/*
+** 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;
+}
+
+/*
+** Parse a timezone extension on the end of a date-time.
+** The extension is of the form:
+**
+** (+/-)HH:MM
+**
+** If the parse is successful, write the number of minutes
+** of change in *pnMin and return 0. If a parser error occurs,
+** return 0.
+**
+** A missing specifier is not considered an error.
+*/
+static int parseTimezone(const char *zDate, DateTime *p){
+ int sgn = 0;
+ int nHr, nMn;
+ while( isspace(*(u8*)zDate) ){ zDate++; }
+ p->tz = 0;
+ if( *zDate=='-' ){
+ sgn = -1;
+ }else if( *zDate=='+' ){
+ sgn = +1;
+ }else{
+ return *zDate!=0;
+ }
+ zDate++;
+ if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
+ return 1;
+ }
+ zDate += 5;
+ p->tz = sgn*(nMn + nHr*60);
+ while( isspace(*(u8*)zDate) ){ zDate++; }
+ return *zDate!=0;
+}
+
+/*
+** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
+** The HH, MM, and SS must each be exactly 2 digits. The
+** fractional seconds FFFF can be one or more digits.
+**
+** Return 1 if there is a parsing error and 0 on success.
+*/
+static int parseHhMmSs(const char *zDate, DateTime *p){
+ int h, m, s;
+ double ms = 0.0;
+ if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
+ return 1;
+ }
+ zDate += 5;
+ if( *zDate==':' ){
+ zDate++;
+ if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
+ return 1;
+ }
+ zDate += 2;
+ if( *zDate=='.' && isdigit((u8)zDate[1]) ){
+ double rScale = 1.0;
+ zDate++;
+ while( isdigit(*(u8*)zDate) ){
+ ms = ms*10.0 + *zDate - '0';
+ rScale *= 10.0;
+ zDate++;
+ }
+ ms /= rScale;
+ }
+ }else{
+ s = 0;
+ }
+ p->validJD = 0;
+ p->validHMS = 1;
+ p->h = h;
+ p->m = m;
+ p->s = s + ms;
+ if( parseTimezone(zDate, p) ) return 1;
+ p->validTZ = p->tz!=0;
+ return 0;
+}
+
+/*
+** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
+** that the YYYY-MM-DD is according to the Gregorian calendar.
+**
+** Reference: Meeus page 61
+*/
+static void computeJD(DateTime *p){
+ int Y, M, D, A, B, X1, X2;
+
+ if( p->validJD ) return;
+ if( p->validYMD ){
+ Y = p->Y;
+ M = p->M;
+ D = p->D;
+ }else{
+ Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */
+ M = 1;
+ D = 1;
+ }
+ if( M<=2 ){
+ Y--;
+ M += 12;
+ }
+ A = Y/100;
+ B = 2 - A + (A/4);
+ X1 = 365.25*(Y+4716);
+ X2 = 30.6001*(M+1);
+ p->rJD = X1 + X2 + D + B - 1524.5;
+ p->validJD = 1;
+ p->validYMD = 0;
+ if( p->validHMS ){
+ p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
+ if( p->validTZ ){
+ p->rJD += p->tz*60/86400.0;
+ p->validHMS = 0;
+ p->validTZ = 0;
+ }
+ }
+}
+
+/*
+** Parse dates of the form
+**
+** YYYY-MM-DD HH:MM:SS.FFF
+** YYYY-MM-DD HH:MM:SS
+** YYYY-MM-DD HH:MM
+** YYYY-MM-DD
+**
+** Write the result into the DateTime structure and return 0
+** on success and 1 if the input string is not a well-formed
+** date.
+*/
+static int parseYyyyMmDd(const char *zDate, DateTime *p){
+ int Y, M, D, neg;
+
+ if( zDate[0]=='-' ){
+ zDate++;
+ neg = 1;
+ }else{
+ neg = 0;
+ }
+ if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
+ return 1;
+ }
+ zDate += 10;
+ while( isspace(*(u8*)zDate) || 'T'==*(u8*)zDate ){ zDate++; }
+ if( parseHhMmSs(zDate, p)==0 ){
+ /* We got the time */
+ }else if( *zDate==0 ){
+ p->validHMS = 0;
+ }else{
+ return 1;
+ }
+ p->validJD = 0;
+ p->validYMD = 1;
+ p->Y = neg ? -Y : Y;
+ p->M = M;
+ p->D = D;
+ if( p->validTZ ){
+ computeJD(p);
+ }
+ return 0;
+}
+
+/*
+** Attempt to parse the given string into a Julian Day Number. Return
+** the number of errors.
+**
+** The following are acceptable forms for the input string:
+**
+** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
+** DDDD.DD
+** now
+**
+** In the first form, the +/-HH:MM is always optional. The fractional
+** seconds extension (the ".FFF") is optional. The seconds portion
+** (":SS.FFF") is option. The year and date can be omitted as long
+** as there is a time string. The time string can be omitted as long
+** as there is a year and date.
+*/
+static int parseDateOrTime(const char *zDate, DateTime *p){
+ memset(p, 0, sizeof(*p));
+ if( parseYyyyMmDd(zDate,p)==0 ){
+ return 0;
+ }else if( parseHhMmSs(zDate, p)==0 ){
+ return 0;
+ }else if( sqlite3StrICmp(zDate,"now")==0){
+ double r;
+ sqlite3OsCurrentTime(&r);
+ p->rJD = r;
+ p->validJD = 1;
+ return 0;
+ }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){
+ p->rJD = sqlite3AtoF(zDate, 0);
+ p->validJD = 1;
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Compute the Year, Month, and Day from the julian day number.
+*/
+static void computeYMD(DateTime *p){
+ int Z, A, B, C, D, E, X1;
+ if( p->validYMD ) return;
+ if( !p->validJD ){
+ p->Y = 2000;
+ p->M = 1;
+ p->D = 1;
+ }else{
+ Z = p->rJD + 0.5;
+ A = (Z - 1867216.25)/36524.25;
+ A = Z + 1 + A - (A/4);
+ B = A + 1524;
+ C = (B - 122.1)/365.25;
+ D = 365.25*C;
+ E = (B-D)/30.6001;
+ X1 = 30.6001*E;
+ p->D = B - D - X1;
+ p->M = E<14 ? E-1 : E-13;
+ p->Y = p->M>2 ? C - 4716 : C - 4715;
+ }
+ p->validYMD = 1;
+}
+
+/*
+** Compute the Hour, Minute, and Seconds from the julian day number.
+*/
+static void computeHMS(DateTime *p){
+ int Z, s;
+ if( p->validHMS ) return;
+ Z = p->rJD + 0.5;
+ s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
+ p->s = 0.001*s;
+ s = p->s;
+ p->s -= s;
+ p->h = s/3600;
+ s -= p->h*3600;
+ p->m = s/60;
+ p->s += s - p->m*60;
+ p->validHMS = 1;
+}
+
+/*
+** Compute both YMD and HMS
+*/
+static void computeYMD_HMS(DateTime *p){
+ computeYMD(p);
+ computeHMS(p);
+}
+
+/*
+** Clear the YMD and HMS and the TZ
+*/
+static void clearYMD_HMS_TZ(DateTime *p){
+ p->validYMD = 0;
+ p->validHMS = 0;
+ p->validTZ = 0;
+}
+
+/*
+** Compute the difference (in days) between localtime and UTC (a.k.a. GMT)
+** for the time value p where p is in UTC.
+*/
+static double localtimeOffset(DateTime *p){
+ DateTime x, y;
+ time_t t;
+ struct tm *pTm;
+ x = *p;
+ computeYMD_HMS(&x);
+ if( x.Y<1971 || x.Y>=2038 ){
+ x.Y = 2000;
+ x.M = 1;
+ x.D = 1;
+ x.h = 0;
+ x.m = 0;
+ x.s = 0.0;
+ } else {
+ int s = x.s + 0.5;
+ x.s = s;
+ }
+ x.tz = 0;
+ x.validJD = 0;
+ computeJD(&x);
+ t = (x.rJD-2440587.5)*86400.0 + 0.5;
+ sqlite3OsEnterMutex();
+ pTm = localtime(&t);
+ y.Y = pTm->tm_year + 1900;
+ y.M = pTm->tm_mon + 1;
+ y.D = pTm->tm_mday;
+ y.h = pTm->tm_hour;
+ y.m = pTm->tm_min;
+ y.s = pTm->tm_sec;
+ sqlite3OsLeaveMutex();
+ y.validYMD = 1;
+ y.validHMS = 1;
+ y.validJD = 0;
+ y.validTZ = 0;
+ computeJD(&y);
+ return y.rJD - x.rJD;
+}
+
+/*
+** Process a modifier to a date-time stamp. The modifiers are
+** as follows:
+**
+** NNN days
+** NNN hours
+** NNN minutes
+** NNN.NNNN seconds
+** NNN months
+** NNN years
+** start of month
+** start of year
+** start of week
+** start of day
+** weekday N
+** unixepoch
+** localtime
+** utc
+**
+** Return 0 on success and 1 if there is any kind of error.
+*/
+static int parseModifier(const char *zMod, DateTime *p){
+ int rc = 1;
+ int n;
+ double r;
+ char *z, zBuf[30];
+ z = zBuf;
+ for(n=0; n<sizeof(zBuf)-1 && zMod[n]; n++){
+ z[n] = tolower(zMod[n]);
+ }
+ z[n] = 0;
+ switch( z[0] ){
+ case 'l': {
+ /* localtime
+ **
+ ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
+ ** show local time.
+ */
+ if( strcmp(z, "localtime")==0 ){
+ computeJD(p);
+ p->rJD += localtimeOffset(p);
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }
+ break;
+ }
+ case 'u': {
+ /*
+ ** unixepoch
+ **
+ ** Treat the current value of p->rJD as the number of
+ ** seconds since 1970. Convert to a real julian day number.
+ */
+ if( strcmp(z, "unixepoch")==0 && p->validJD ){
+ p->rJD = p->rJD/86400.0 + 2440587.5;
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }else if( strcmp(z, "utc")==0 ){
+ double c1;
+ computeJD(p);
+ c1 = localtimeOffset(p);
+ p->rJD -= c1;
+ clearYMD_HMS_TZ(p);
+ p->rJD += c1 - localtimeOffset(p);
+ rc = 0;
+ }
+ break;
+ }
+ case 'w': {
+ /*
+ ** weekday N
+ **
+ ** Move the date to the same time on the next occurrence of
+ ** weekday N where 0==Sunday, 1==Monday, and so forth. If the
+ ** date is already on the appropriate weekday, this is a no-op.
+ */
+ if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
+ && (n=r)==r && n>=0 && r<7 ){
+ int Z;
+ computeYMD_HMS(p);
+ p->validTZ = 0;
+ p->validJD = 0;
+ computeJD(p);
+ Z = p->rJD + 1.5;
+ Z %= 7;
+ if( Z>n ) Z -= 7;
+ p->rJD += n - Z;
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }
+ break;
+ }
+ case 's': {
+ /*
+ ** start of TTTTT
+ **
+ ** Move the date backwards to the beginning of the current day,
+ ** or month or year.
+ */
+ if( strncmp(z, "start of ", 9)!=0 ) break;
+ z += 9;
+ computeYMD(p);
+ p->validHMS = 1;
+ p->h = p->m = 0;
+ p->s = 0.0;
+ p->validTZ = 0;
+ p->validJD = 0;
+ if( strcmp(z,"month")==0 ){
+ p->D = 1;
+ rc = 0;
+ }else if( strcmp(z,"year")==0 ){
+ computeYMD(p);
+ p->M = 1;
+ p->D = 1;
+ rc = 0;
+ }else if( strcmp(z,"day")==0 ){
+ rc = 0;
+ }
+ break;
+ }
+ case '+':
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ n = getValue(z, &r);
+ if( n<=0 ) break;
+ if( z[n]==':' ){
+ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
+ ** specified number of hours, minutes, seconds, and fractional seconds
+ ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
+ ** omitted.
+ */
+ const char *z2 = z;
+ DateTime tx;
+ int day;
+ if( !isdigit(*(u8*)z2) ) z2++;
+ memset(&tx, 0, sizeof(tx));
+ if( parseHhMmSs(z2, &tx) ) break;
+ computeJD(&tx);
+ tx.rJD -= 0.5;
+ day = (int)tx.rJD;
+ tx.rJD -= day;
+ if( z[0]=='-' ) tx.rJD = -tx.rJD;
+ computeJD(p);
+ clearYMD_HMS_TZ(p);
+ p->rJD += tx.rJD;
+ rc = 0;
+ break;
+ }
+ z += n;
+ while( isspace(*(u8*)z) ) z++;
+ n = strlen(z);
+ if( n>10 || n<3 ) break;
+ if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
+ computeJD(p);
+ rc = 0;
+ if( n==3 && strcmp(z,"day")==0 ){
+ p->rJD += r;
+ }else if( n==4 && strcmp(z,"hour")==0 ){
+ p->rJD += r/24.0;
+ }else if( n==6 && strcmp(z,"minute")==0 ){
+ p->rJD += r/(24.0*60.0);
+ }else if( n==6 && strcmp(z,"second")==0 ){
+ p->rJD += r/(24.0*60.0*60.0);
+ }else if( n==5 && strcmp(z,"month")==0 ){
+ int x, y;
+ computeYMD_HMS(p);
+ p->M += r;
+ x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
+ p->Y += x;
+ p->M -= x*12;
+ p->validJD = 0;
+ computeJD(p);
+ y = r;
+ if( y!=r ){
+ p->rJD += (r - y)*30.0;
+ }
+ }else if( n==4 && strcmp(z,"year")==0 ){
+ computeYMD_HMS(p);
+ p->Y += r;
+ p->validJD = 0;
+ computeJD(p);
+ }else{
+ rc = 1;
+ }
+ clearYMD_HMS_TZ(p);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ return rc;
+}
+
+/*
+** Process time function arguments. argv[0] is a date-time stamp.
+** argv[1] and following are modifiers. Parse them all and write
+** the resulting time into the DateTime structure p. Return 0
+** on success and 1 if there are any errors.
+*/
+static int isDate(int argc, sqlite3_value **argv, DateTime *p){
+ int i;
+ if( argc==0 ) return 1;
+ if( SQLITE_NULL==sqlite3_value_type(argv[0]) ||
+ parseDateOrTime(sqlite3_value_text(argv[0]), p) ) return 1;
+ for(i=1; i<argc; i++){
+ if( SQLITE_NULL==sqlite3_value_type(argv[i]) ||
+ parseModifier(sqlite3_value_text(argv[i]), p) ) return 1;
+ }
+ return 0;
+}
+
+
+/*
+** The following routines implement the various date and time functions
+** of SQLite.
+*/
+
+/*
+** julianday( TIMESTRING, MOD, MOD, ...)
+**
+** Return the julian day number of the date specified in the arguments
+*/
+static void juliandayFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ computeJD(&x);
+ sqlite3_result_double(context, x.rJD);
+ }
+}
+
+/*
+** datetime( TIMESTRING, MOD, MOD, ...)
+**
+** Return YYYY-MM-DD HH:MM:SS
+*/
+static void datetimeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ char zBuf[100];
+ computeYMD_HMS(&x);
+ sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m,
+ (int)(x.s));
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+ }
+}
+
+/*
+** time( TIMESTRING, MOD, MOD, ...)
+**
+** Return HH:MM:SS
+*/
+static void timeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ char zBuf[100];
+ computeHMS(&x);
+ sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+ }
+}
+
+/*
+** date( TIMESTRING, MOD, MOD, ...)
+**
+** Return YYYY-MM-DD
+*/
+static void dateFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ char zBuf[100];
+ computeYMD(&x);
+ sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+ }
+}
+
+/*
+** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
+**
+** Return a string described by FORMAT. Conversions as follows:
+**
+** %d day of month
+** %f ** fractional seconds SS.SSS
+** %H hour 00-24
+** %j day of year 000-366
+** %J ** Julian day number
+** %m month 01-12
+** %M minute 00-59
+** %s seconds since 1970-01-01
+** %S seconds 00-59
+** %w day of week 0-6 sunday==0
+** %W week of year 00-53
+** %Y year 0000-9999
+** %% %
+*/
+static void strftimeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ int n, i, j;
+ char *z;
+ const char *zFmt = sqlite3_value_text(argv[0]);
+ char zBuf[100];
+ if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return;
+ for(i=0, n=1; zFmt[i]; i++, n++){
+ if( zFmt[i]=='%' ){
+ switch( zFmt[i+1] ){
+ case 'd':
+ case 'H':
+ case 'm':
+ case 'M':
+ case 'S':
+ case 'W':
+ n++;
+ /* fall thru */
+ case 'w':
+ case '%':
+ break;
+ case 'f':
+ n += 8;
+ break;
+ case 'j':
+ n += 3;
+ break;
+ case 'Y':
+ n += 8;
+ break;
+ case 's':
+ case 'J':
+ n += 50;
+ break;
+ default:
+ return; /* ERROR. return a NULL */
+ }
+ i++;
+ }
+ }
+ if( n<sizeof(zBuf) ){
+ z = zBuf;
+ }else{
+ z = sqliteMalloc( n );
+ if( z==0 ) return;
+ }
+ computeJD(&x);
+ computeYMD_HMS(&x);
+ for(i=j=0; zFmt[i]; i++){
+ if( zFmt[i]!='%' ){
+ z[j++] = zFmt[i];
+ }else{
+ i++;
+ switch( zFmt[i] ){
+ case 'd': sprintf(&z[j],"%02d",x.D); j+=2; break;
+ case 'f': {
+ int s = x.s;
+ int ms = (x.s - s)*1000.0;
+ sprintf(&z[j],"%02d.%03d",s,ms);
+ j += strlen(&z[j]);
+ break;
+ }
+ case 'H': sprintf(&z[j],"%02d",x.h); j+=2; break;
+ case 'W': /* Fall thru */
+ case 'j': {
+ int n; /* Number of days since 1st day of year */
+ DateTime y = x;
+ y.validJD = 0;
+ y.M = 1;
+ y.D = 1;
+ computeJD(&y);
+ n = x.rJD - y.rJD;
+ if( zFmt[i]=='W' ){
+ int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
+ wd = ((int)(x.rJD+0.5)) % 7;
+ sprintf(&z[j],"%02d",(n+7-wd)/7);
+ j += 2;
+ }else{
+ sprintf(&z[j],"%03d",n+1);
+ j += 3;
+ }
+ break;
+ }
+ case 'J': sprintf(&z[j],"%.16g",x.rJD); j+=strlen(&z[j]); break;
+ case 'm': sprintf(&z[j],"%02d",x.M); j+=2; break;
+ case 'M': sprintf(&z[j],"%02d",x.m); j+=2; break;
+ case 's': {
+ sprintf(&z[j],"%d",(int)((x.rJD-2440587.5)*86400.0 + 0.5));
+ j += strlen(&z[j]);
+ break;
+ }
+ case 'S': sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
+ case 'w': z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
+ case 'Y': sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
+ case '%': z[j++] = '%'; break;
+ }
+ }
+ }
+ z[j] = 0;
+ sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+ if( z!=zBuf ){
+ sqliteFree(z);
+ }
+}
+
+/*
+** current_time()
+**
+** This function returns the same value as time('now').
+*/
+static void ctimeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3_value *pVal = sqlite3ValueNew();
+ if( pVal ){
+ sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
+ timeFunc(context, 1, &pVal);
+ sqlite3ValueFree(pVal);
+ }
+}
+
+/*
+** current_date()
+**
+** This function returns the same value as date('now').
+*/
+static void cdateFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3_value *pVal = sqlite3ValueNew();
+ if( pVal ){
+ sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
+ dateFunc(context, 1, &pVal);
+ sqlite3ValueFree(pVal);
+ }
+}
+
+/*
+** current_timestamp()
+**
+** This function returns the same value as datetime('now').
+*/
+static void ctimestampFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3_value *pVal = sqlite3ValueNew();
+ if( pVal ){
+ sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
+ datetimeFunc(context, 1, &pVal);
+ sqlite3ValueFree(pVal);
+ }
+}
+#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
+
+#ifdef SQLITE_OMIT_DATETIME_FUNCS
+/*
+** If the library is compiled to omit the full-scale date and time
+** handling (to get a smaller binary), the following minimal version
+** of the functions current_time(), current_date() and current_timestamp()
+** are included instead. This is to support column declarations that
+** include "DEFAULT CURRENT_TIME" etc.
+**
+** This function uses the C-library functions time(), gmtime()
+** and strftime(). The format string to pass to strftime() is supplied
+** as the user-data for the function.
+*/
+static void currentTimeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ time_t t;
+ char *zFormat = (char *)sqlite3_user_data(context);
+ char zBuf[20];
+
+ time(&t);
+#ifdef SQLITE_TEST
+ {
+ extern int sqlite3_current_time; /* See os_XXX.c */
+ if( sqlite3_current_time ){
+ t = sqlite3_current_time;
+ }
+ }
+#endif
+
+ sqlite3OsEnterMutex();
+ strftime(zBuf, 20, zFormat, gmtime(&t));
+ sqlite3OsLeaveMutex();
+
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+}
+#endif
+
+/*
+** This function registered all of the above C functions as SQL
+** functions. This should be the only routine in this file with
+** external linkage.
+*/
+void sqlite3RegisterDateTimeFunctions(sqlite3 *db){
+#ifndef SQLITE_OMIT_DATETIME_FUNCS
+ static const struct {
+ char *zName;
+ int nArg;
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+ } aFuncs[] = {
+ { "julianday", -1, juliandayFunc },
+ { "date", -1, dateFunc },
+ { "time", -1, timeFunc },
+ { "datetime", -1, datetimeFunc },
+ { "strftime", -1, strftimeFunc },
+ { "current_time", 0, ctimeFunc },
+ { "current_timestamp", 0, ctimestampFunc },
+ { "current_date", 0, cdateFunc },
+ };
+ int i;
+
+ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
+ sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
+ SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
+ }
+#else
+ static const struct {
+ char *zName;
+ char *zFormat;
+ } aFuncs[] = {
+ { "current_time", "%H:%M:%S" },
+ { "current_date", "%Y-%m-%d" },
+ { "current_timestamp", "%Y-%m-%d %H:%M:%S" }
+ };
+ int i;
+
+ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
+ sqlite3_create_function(db, aFuncs[i].zName, 0, SQLITE_UTF8,
+ aFuncs[i].zFormat, currentTimeFunc, 0, 0);
+ }
+#endif
+}
diff --git a/src/sqlite/delete.c b/src/sqlite/delete.c
new file mode 100644
index 0000000..2908885
--- /dev/null
+++ b/src/sqlite/delete.c
@@ -0,0 +1,447 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** in order to generate code for DELETE FROM statements.
+**
+** $Id: delete.c,v 1.1.1.1 2006/02/03 20:35:13 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** Look up every table that is named in pSrc. If any table is not found,
+** add an error message to pParse->zErrMsg and return NULL. If all tables
+** are found, return a pointer to the last table.
+*/
+Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
+ Table *pTab = 0;
+ int i;
+ struct SrcList_item *pItem;
+ for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
+ pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
+ sqlite3DeleteTable(pParse->db, pItem->pTab);
+ pItem->pTab = pTab;
+ if( pTab ){
+ pTab->nRef++;
+ }
+ }
+ return pTab;
+}
+
+/*
+** Check to make sure the given table is writable. If it is not
+** writable, generate an error message and return 1. If it is
+** writable return 0;
+*/
+int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
+ if( pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0
+ && pParse->nested==0 ){
+ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
+ return 1;
+ }
+#ifndef SQLITE_OMIT_VIEW
+ if( !viewOk && pTab->pSelect ){
+ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+/*
+** Generate code that will open a table for reading.
+*/
+void sqlite3OpenTableForReading(
+ Vdbe *v, /* Generate code into this VDBE */
+ int iCur, /* The cursor number of the table */
+ 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_SetNumColumns, iCur, pTab->nCol);
+}
+
+
+/*
+** Generate code for a DELETE FROM statement.
+**
+** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
+** \________/ \________________/
+** pTabList pWhere
+*/
+void sqlite3DeleteFrom(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* The table from which we should delete things */
+ Expr *pWhere /* The WHERE clause. May be null */
+){
+ Vdbe *v; /* The virtual database engine */
+ Table *pTab; /* The table from which records will be deleted */
+ const char *zDb; /* Name of database holding pTab */
+ int end, addr = 0; /* A couple addresses of generated code */
+ int i; /* Loop counter */
+ WhereInfo *pWInfo; /* Information about the WHERE clause */
+ Index *pIdx; /* For looping over indices of the table */
+ int iCur; /* VDBE Cursor number for pTab */
+ sqlite3 *db; /* Main database structure */
+ AuthContext sContext; /* Authorization context */
+ int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */
+ NameContext sNC; /* Name context to resolve expressions in */
+
+#ifndef SQLITE_OMIT_TRIGGER
+ int isView; /* True if attempting to delete from a view */
+ int triggers_exist = 0; /* True if any triggers exist */
+#endif
+
+ sContext.pParse = 0;
+ if( pParse->nErr || sqlite3_malloc_failed ){
+ goto delete_from_cleanup;
+ }
+ db = pParse->db;
+ assert( pTabList->nSrc==1 );
+
+ /* Locate the table which we want to delete. This table has to be
+ ** put in an SrcList structure because some of the subroutines we
+ ** will be calling are designed to work with multiple tables and expect
+ ** an SrcList* parameter instead of just a Table* parameter.
+ */
+ pTab = sqlite3SrcListLookup(pParse, pTabList);
+ if( pTab==0 ) goto delete_from_cleanup;
+
+ /* Figure out if we have any triggers and if the table being
+ ** deleted from is a view
+ */
+#ifndef SQLITE_OMIT_TRIGGER
+ triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0);
+ isView = pTab->pSelect!=0;
+#else
+# define triggers_exist 0
+# define isView 0
+#endif
+#ifdef SQLITE_OMIT_VIEW
+# undef isView
+# define isView 0
+#endif
+
+ if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
+ goto delete_from_cleanup;
+ }
+ assert( pTab->iDb<db->nDb );
+ zDb = db->aDb[pTab->iDb].zName;
+ if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
+ goto delete_from_cleanup;
+ }
+
+ /* If pTab is really a view, make sure it has been initialized.
+ */
+ if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
+ goto delete_from_cleanup;
+ }
+
+ /* Allocate a cursor used to store the old.* data for a trigger.
+ */
+ if( triggers_exist ){
+ oldIdx = pParse->nTab++;
+ }
+
+ /* Resolve the column names in the WHERE clause.
+ */
+ assert( pTabList->nSrc==1 );
+ iCur = pTabList->a[0].iCursor = pParse->nTab++;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ sNC.pSrcList = pTabList;
+ if( sqlite3ExprResolveNames(&sNC, pWhere) ){
+ goto delete_from_cleanup;
+ }
+
+ /* Start the view context
+ */
+ if( isView ){
+ sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
+ }
+
+ /* Begin generating code.
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ){
+ goto delete_from_cleanup;
+ }
+ if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+ sqlite3BeginWriteOperation(pParse, triggers_exist, pTab->iDb);
+
+ /* If we are trying to delete from a view, construct that view into
+ ** a temporary table.
+ */
+ if( isView ){
+ Select *pView = sqlite3SelectDup(pTab->pSelect);
+ sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0);
+ sqlite3SelectDelete(pView);
+ }
+
+ /* Initialize the counter of the number of rows deleted, if
+ ** we are counting rows.
+ */
+ if( db->flags & SQLITE_CountRows ){
+ sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+ }
+
+ /* Special case: A DELETE without a WHERE clause deletes everything.
+ ** It is easier just to erase the whole table. Note, however, that
+ ** this means that the row change count will be incorrect.
+ */
+ if( pWhere==0 && !triggers_exist ){
+ if( db->flags & SQLITE_CountRows ){
+ /* If counting rows deleted, just count the total number of
+ ** entries in the table. */
+ int endOfLoop = sqlite3VdbeMakeLabel(v);
+ int addr;
+ if( !isView ){
+ sqlite3OpenTableForReading(v, iCur, pTab);
+ }
+ sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
+ addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
+ sqlite3VdbeResolveLabel(v, endOfLoop);
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+ if( !isView ){
+ sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
+ }
+ }
+ }
+
+ /* The usual case: There is a WHERE clause so we have to scan through
+ ** the table and pick which records to delete.
+ */
+ else{
+ /* Ensure all required collation sequences are available. */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
+ goto delete_from_cleanup;
+ }
+ }
+
+ /* Begin the database scan
+ */
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
+ if( pWInfo==0 ) goto delete_from_cleanup;
+
+ /* Remember the rowid of every item to be deleted.
+ */
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
+ if( db->flags & SQLITE_CountRows ){
+ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
+ }
+
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+
+ /* Open the pseudo-table used to store OLD if there are triggers.
+ */
+ if( triggers_exist ){
+ sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
+ }
+
+ /* Delete every item whose key was written to the list during the
+ ** 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);
+ if( !isView ){
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ sqlite3OpenTableForReading(v, iCur, pTab);
+ }
+ sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
+ if( !isView ){
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+
+ (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
+ -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
+ addr);
+ }
+
+ 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
+ ** before the trigger fires. If there are no row triggers, the
+ ** cursors are opened only once on the outside the loop.
+ */
+ sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
+
+ /* This is the beginning of the delete loop when there are no
+ ** row triggers */
+ if( !triggers_exist ){
+ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
+ }
+
+ /* Delete the row */
+ sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
+ }
+
+ /* If there are row triggers, close all cursors then invoke
+ ** the AFTER triggers
+ */
+ if( triggers_exist ){
+ if( !isView ){
+ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
+ }
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+ (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
+ oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
+ addr);
+ }
+
+ /* 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 ){
+ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
+ }
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+ }
+
+ /*
+ ** Return the number of rows that were deleted. If this routine is
+ ** generating code because of a call to sqlite3NestedParse(), do not
+ ** invoke the callback function.
+ */
+ if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
+ sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
+ }
+
+delete_from_cleanup:
+ sqlite3AuthContextPop(&sContext);
+ sqlite3SrcListDelete(pTabList);
+ sqlite3ExprDelete(pWhere);
+ return;
+}
+
+/*
+** This routine generates VDBE code that causes a single row of a
+** single table to be deleted.
+**
+** The VDBE must be in a particular state when this routine is called.
+** These are the requirements:
+**
+** 1. A read/write cursor pointing to pTab, the table containing the row
+** to be deleted, must be opened as cursor number "base".
+**
+** 2. Read/write cursors for all indices of pTab must be open as
+** cursor number base+i for the i-th index.
+**
+** 3. The record number of the row to be deleted must be on the top
+** of the stack.
+**
+** This routine pops the top of the stack to remove the record number
+** and then generates code to remove both the table record and all index
+** entries that point to that record.
+*/
+void sqlite3GenerateRowDelete(
+ sqlite3 *db, /* The database containing the index */
+ Vdbe *v, /* Generate code into this VDBE */
+ Table *pTab, /* Table containing the row to be deleted */
+ int iCur, /* Cursor number for the table */
+ int count /* Increment the row change counter */
+){
+ int addr;
+ addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
+ sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
+ sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
+}
+
+/*
+** This routine generates VDBE code that causes the deletion of all
+** index entries associated with a single row of a single table.
+**
+** The VDBE must be in a particular state when this routine is called.
+** These are the requirements:
+**
+** 1. A read/write cursor pointing to pTab, the table containing the row
+** to be deleted, must be opened as cursor number "iCur".
+**
+** 2. Read/write cursors for all indices of pTab must be open as
+** cursor number iCur+i for the i-th index.
+**
+** 3. The "iCur" cursor must be pointing to the row that is to be
+** deleted.
+*/
+void sqlite3GenerateRowIndexDelete(
+ sqlite3 *db, /* The database containing the index */
+ Vdbe *v, /* Generate code into this VDBE */
+ Table *pTab, /* Table containing the row to be deleted */
+ int iCur, /* Cursor number for the table */
+ char *aIdxUsed /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */
+){
+ int i;
+ Index *pIdx;
+
+ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
+ sqlite3GenerateIndexKey(v, pIdx, iCur);
+ sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
+ }
+}
+
+/*
+** Generate code that will assemble an index key and put it on the top
+** of the tack. The key with be for index pIdx which is an index on pTab.
+** iCur is the index of a cursor open on the pTab table and pointing to
+** the entry that needs indexing.
+*/
+void sqlite3GenerateIndexKey(
+ Vdbe *v, /* Generate code into this VDBE */
+ Index *pIdx, /* The index for which to generate a key */
+ int iCur /* Cursor number for the pIdx->pTable table */
+){
+ int j;
+ Table *pTab = pIdx->pTable;
+
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ for(j=0; j<pIdx->nColumn; j++){
+ int idx = pIdx->aiColumn[j];
+ if( idx==pTab->iPKey ){
+ sqlite3VdbeAddOp(v, OP_Dup, j, 0);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
+ sqlite3ColumnDefault(v, pTab, idx);
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
+ sqlite3IndexAffinityStr(v, pIdx);
+}
diff --git a/src/sqlite/expr.c b/src/sqlite/expr.c
new file mode 100644
index 0000000..c17676e
--- /dev/null
+++ b/src/sqlite/expr.c
@@ -0,0 +1,2071 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains routines used for analyzing expressions and
+** for generating VDBE code that evaluates expressions in SQLite.
+**
+** $Id: expr.c,v 1.1.1.1 2006/02/03 20:35:12 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include <ctype.h>
+
+/*
+** Return the 'affinity' of the expression pExpr if any.
+**
+** If pExpr is a column, a reference to a column via an 'AS' alias,
+** or a sub-select with a column as the return value, then the
+** affinity of that column is returned. Otherwise, 0x00 is returned,
+** indicating no affinity for the expression.
+**
+** i.e. the WHERE clause expresssions in the following statements all
+** have an affinity:
+**
+** CREATE TABLE t1(a);
+** SELECT * FROM t1 WHERE a;
+** SELECT a AS b FROM t1 WHERE b;
+** SELECT * FROM t1 WHERE (select a from t1);
+*/
+char sqlite3ExprAffinity(Expr *pExpr){
+ if( pExpr->op==TK_AS ){
+ return sqlite3ExprAffinity(pExpr->pLeft);
+ }
+ if( pExpr->op==TK_SELECT ){
+ return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
+ }
+ return pExpr->affinity;
+}
+
+/*
+** Return the default collation sequence for the expression pExpr. If
+** there is no default collation type, return 0.
+*/
+CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
+ CollSeq *pColl = 0;
+ if( pExpr ){
+ pColl = pExpr->pColl;
+ if( pExpr->op==TK_AS && !pColl ){
+ return sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+ }
+ }
+ if( sqlite3CheckCollSeq(pParse, pColl) ){
+ pColl = 0;
+ }
+ return pColl;
+}
+
+/*
+** pExpr is an operand of a comparison operator. aff2 is the
+** type affinity of the other operand. This routine returns the
+** type affinity that should be used for the comparison operator.
+*/
+char sqlite3CompareAffinity(Expr *pExpr, char aff2){
+ char aff1 = sqlite3ExprAffinity(pExpr);
+ if( aff1 && aff2 ){
+ /* Both sides of the comparison are columns. If one has numeric or
+ ** integer affinity, use that. Otherwise use no affinity.
+ */
+ if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){
+ return SQLITE_AFF_INTEGER;
+ }else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
+ return SQLITE_AFF_NUMERIC;
+ }else{
+ return SQLITE_AFF_NONE;
+ }
+ }else if( !aff1 && !aff2 ){
+ /* Neither side of the comparison is a column. Compare the
+ ** results directly.
+ */
+ /* return SQLITE_AFF_NUMERIC; // Ticket #805 */
+ return SQLITE_AFF_NONE;
+ }else{
+ /* One side is a column, the other is not. Use the columns affinity. */
+ return (aff1 + aff2);
+ }
+}
+
+/*
+** pExpr is a comparison operator. Return the type affinity that should
+** be applied to both operands prior to doing the comparison.
+*/
+static char comparisonAffinity(Expr *pExpr){
+ char aff;
+ assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
+ pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
+ pExpr->op==TK_NE );
+ assert( pExpr->pLeft );
+ aff = sqlite3ExprAffinity(pExpr->pLeft);
+ if( pExpr->pRight ){
+ aff = sqlite3CompareAffinity(pExpr->pRight, aff);
+ }
+ else if( pExpr->pSelect ){
+ aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff);
+ }
+ else if( !aff ){
+ aff = SQLITE_AFF_NUMERIC;
+ }
+ return aff;
+}
+
+/*
+** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
+** idx_affinity is the affinity of an indexed column. Return true
+** if the index with affinity idx_affinity may be used to implement
+** the comparison in pExpr.
+*/
+int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
+ char aff = comparisonAffinity(pExpr);
+ return
+ (aff==SQLITE_AFF_NONE) ||
+ (aff==SQLITE_AFF_NUMERIC && idx_affinity==SQLITE_AFF_INTEGER) ||
+ (aff==SQLITE_AFF_INTEGER && idx_affinity==SQLITE_AFF_NUMERIC) ||
+ (aff==idx_affinity);
+}
+
+/*
+** Return the P1 value that should be used for a binary comparison
+** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
+** If jumpIfNull is true, then set the low byte of the returned
+** P1 value to tell the opcode to jump if either expression
+** evaluates to NULL.
+*/
+static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
+ char aff = sqlite3ExprAffinity(pExpr2);
+ return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0);
+}
+
+/*
+** Return a pointer to the collation sequence that should be used by
+** a binary comparison operator comparing pLeft and pRight.
+**
+** If the left hand expression has a collating sequence type, then it is
+** used. Otherwise the collation sequence for the right hand expression
+** is used, or the default (BINARY) if neither expression has a collating
+** type.
+*/
+static CollSeq* binaryCompareCollSeq(Parse *pParse, Expr *pLeft, Expr *pRight){
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pLeft);
+ if( !pColl ){
+ pColl = sqlite3ExprCollSeq(pParse, pRight);
+ }
+ return pColl;
+}
+
+/*
+** Generate code for a comparison operator.
+*/
+static int codeCompare(
+ Parse *pParse, /* The parsing (and code generating) context */
+ Expr *pLeft, /* The left operand */
+ Expr *pRight, /* The right operand */
+ int opcode, /* The comparison opcode */
+ int dest, /* Jump here if true. */
+ int jumpIfNull /* If true, jump if either operand is NULL */
+){
+ int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
+ CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight);
+ return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ);
+}
+
+/*
+** Construct a new expression node and return a pointer to it. Memory
+** for this node is obtained from sqliteMalloc(). The calling function
+** is responsible for making sure the node eventually gets freed.
+*/
+Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
+ Expr *pNew;
+ pNew = sqliteMalloc( sizeof(Expr) );
+ if( pNew==0 ){
+ /* When malloc fails, delete pLeft and pRight. Expressions passed to
+ ** this function must always be allocated with sqlite3Expr() for this
+ ** reason.
+ */
+ sqlite3ExprDelete(pLeft);
+ sqlite3ExprDelete(pRight);
+ return 0;
+ }
+ pNew->op = op;
+ pNew->pLeft = pLeft;
+ pNew->pRight = pRight;
+ pNew->iAgg = -1;
+ if( pToken ){
+ assert( pToken->dyn==0 );
+ pNew->span = pNew->token = *pToken;
+ }else if( pLeft && pRight ){
+ sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
+ }
+ return pNew;
+}
+
+/*
+** When doing a nested parse, you can include terms in an expression
+** that look like this: #0 #1 #2 ... These terms refer to elements
+** on the stack. "#0" (or just "#") means the top of the stack.
+** "#1" means the next down on the stack. And so forth. #-1 means
+** memory location 0. #-2 means memory location 1. And so forth.
+**
+** This routine is called by the parser to deal with on of those terms.
+** It immediately generates code to store the value in a memory location.
+** The returns an expression that will code to extract the value from
+** that memory location as needed.
+*/
+Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
+ Vdbe *v = pParse->pVdbe;
+ Expr *p;
+ int depth;
+ if( v==0 ) return 0;
+ if( pParse->nested==0 ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
+ return 0;
+ }
+ p = sqlite3Expr(TK_REGISTER, 0, 0, pToken);
+ if( p==0 ){
+ return 0; /* Malloc failed */
+ }
+ depth = atoi(&pToken->z[1]);
+ if( depth>=0 ){
+ p->iTable = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
+ }else{
+ p->iTable = -1-depth;
+ }
+ return p;
+}
+
+/*
+** Join two expressions using an AND operator. If either expression is
+** NULL, then just return the other expression.
+*/
+Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){
+ if( pLeft==0 ){
+ return pRight;
+ }else if( pRight==0 ){
+ return pLeft;
+ }else{
+ return sqlite3Expr(TK_AND, pLeft, pRight, 0);
+ }
+}
+
+/*
+** Set the Expr.span field of the given expression to span all
+** text between the two given tokens.
+*/
+void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
+ assert( pRight!=0 );
+ assert( pLeft!=0 );
+ if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){
+ assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
+ if( pLeft->dyn==0 && pRight->dyn==0 ){
+ pExpr->span.z = pLeft->z;
+ pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
+ }else{
+ pExpr->span.z = 0;
+ }
+ }
+}
+
+/*
+** Construct a new expression node for a function with multiple
+** arguments.
+*/
+Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
+ Expr *pNew;
+ pNew = sqliteMalloc( sizeof(Expr) );
+ if( pNew==0 ){
+ sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
+ return 0;
+ }
+ pNew->op = TK_FUNCTION;
+ pNew->pList = pList;
+ if( pToken ){
+ assert( pToken->dyn==0 );
+ pNew->token = *pToken;
+ }else{
+ pNew->token.z = 0;
+ }
+ pNew->span = pNew->token;
+ return pNew;
+}
+
+/*
+** Assign a variable number to an expression that encodes a wildcard
+** in the original SQL statement.
+**
+** Wildcards consisting of a single "?" are assigned the next sequential
+** variable number.
+**
+** Wildcards of the form "?nnn" are assigned the number "nnn". We make
+** sure "nnn" is not too be to avoid a denial of service attack when
+** the SQL statement comes from an external source.
+**
+** Wildcards of the form ":aaa" or "$aaa" are assigned the same number
+** as the previous instance of the same wildcard. Or if this is the first
+** instance of the wildcard, the next sequenial variable number is
+** assigned.
+*/
+void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
+ Token *pToken;
+ if( pExpr==0 ) return;
+ pToken = &pExpr->token;
+ assert( pToken->n>=1 );
+ assert( pToken->z!=0 );
+ assert( pToken->z[0]!=0 );
+ if( pToken->n==1 ){
+ /* Wildcard of the form "?". Assign the next variable number */
+ pExpr->iTable = ++pParse->nVar;
+ }else if( pToken->z[0]=='?' ){
+ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and
+ ** use it as the variable number */
+ int i;
+ pExpr->iTable = i = atoi(&pToken->z[1]);
+ if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
+ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
+ SQLITE_MAX_VARIABLE_NUMBER);
+ }
+ if( i>pParse->nVar ){
+ pParse->nVar = i;
+ }
+ }else{
+ /* Wildcards of the form ":aaa" or "$aaa". Reuse the same variable
+ ** number as the prior appearance of the same name, or if the name
+ ** has never appeared before, reuse the same variable number
+ */
+ int i, n;
+ n = pToken->n;
+ for(i=0; i<pParse->nVarExpr; i++){
+ Expr *pE;
+ if( (pE = pParse->apVarExpr[i])!=0
+ && pE->token.n==n
+ && memcmp(pE->token.z, pToken->z, n)==0 ){
+ pExpr->iTable = pE->iTable;
+ break;
+ }
+ }
+ if( i>=pParse->nVarExpr ){
+ pExpr->iTable = ++pParse->nVar;
+ if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
+ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
+ pParse->apVarExpr = sqliteRealloc(pParse->apVarExpr,
+ pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
+ }
+ if( !sqlite3_malloc_failed ){
+ assert( pParse->apVarExpr!=0 );
+ pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
+ }
+ }
+ }
+}
+
+/*
+** Recursively delete an expression tree.
+*/
+void sqlite3ExprDelete(Expr *p){
+ if( p==0 ) return;
+ if( p->span.dyn ) sqliteFree((char*)p->span.z);
+ if( p->token.dyn ) sqliteFree((char*)p->token.z);
+ sqlite3ExprDelete(p->pLeft);
+ sqlite3ExprDelete(p->pRight);
+ sqlite3ExprListDelete(p->pList);
+ sqlite3SelectDelete(p->pSelect);
+ sqliteFree(p);
+}
+
+
+/*
+** The following group of routines make deep copies of expressions,
+** expression lists, ID lists, and select statements. The copies can
+** be deleted (by being passed to their respective ...Delete() routines)
+** without effecting the originals.
+**
+** The expression list, ID, and source lists return by sqlite3ExprListDup(),
+** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded
+** by subsequent calls to sqlite*ListAppend() routines.
+**
+** Any tables that the SrcList might point to are not duplicated.
+*/
+Expr *sqlite3ExprDup(Expr *p){
+ Expr *pNew;
+ if( p==0 ) return 0;
+ pNew = sqliteMallocRaw( sizeof(*p) );
+ if( pNew==0 ) return 0;
+ memcpy(pNew, p, sizeof(*pNew));
+ if( p->token.z!=0 ){
+ pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
+ pNew->token.dyn = 1;
+ }else{
+ assert( pNew->token.z==0 );
+ }
+ pNew->span.z = 0;
+ pNew->pLeft = sqlite3ExprDup(p->pLeft);
+ pNew->pRight = sqlite3ExprDup(p->pRight);
+ pNew->pList = sqlite3ExprListDup(p->pList);
+ pNew->pSelect = sqlite3SelectDup(p->pSelect);
+ pNew->pTab = p->pTab;
+ return pNew;
+}
+void sqlite3TokenCopy(Token *pTo, Token *pFrom){
+ if( pTo->dyn ) sqliteFree((char*)pTo->z);
+ if( pFrom->z ){
+ pTo->n = pFrom->n;
+ pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
+ pTo->dyn = 1;
+ }else{
+ pTo->z = 0;
+ }
+}
+ExprList *sqlite3ExprListDup(ExprList *p){
+ ExprList *pNew;
+ struct ExprList_item *pItem, *pOldItem;
+ int i;
+ if( p==0 ) return 0;
+ pNew = sqliteMalloc( sizeof(*pNew) );
+ if( pNew==0 ) return 0;
+ pNew->nExpr = pNew->nAlloc = p->nExpr;
+ pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
+ if( pItem==0 ){
+ sqliteFree(pNew);
+ return 0;
+ }
+ pOldItem = p->a;
+ for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
+ Expr *pNewExpr, *pOldExpr;
+ pItem->pExpr = pNewExpr = sqlite3ExprDup(pOldExpr = pOldItem->pExpr);
+ if( pOldExpr->span.z!=0 && pNewExpr ){
+ /* Always make a copy of the span for top-level expressions in the
+ ** expression list. The logic in SELECT processing that determines
+ ** the names of columns in the result set needs this information */
+ sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
+ }
+ assert( pNewExpr==0 || pNewExpr->span.z!=0
+ || pOldExpr->span.z==0 || sqlite3_malloc_failed );
+ pItem->zName = sqliteStrDup(pOldItem->zName);
+ pItem->sortOrder = pOldItem->sortOrder;
+ pItem->isAgg = pOldItem->isAgg;
+ pItem->done = 0;
+ }
+ return pNew;
+}
+
+/*
+** If cursors, triggers, views and subqueries are all omitted from
+** the build, then none of the following routines, except for
+** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
+** called with a NULL argument.
+*/
+#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
+ || !defined(SQLITE_OMIT_SUBQUERY)
+SrcList *sqlite3SrcListDup(SrcList *p){
+ SrcList *pNew;
+ int i;
+ int nByte;
+ if( p==0 ) return 0;
+ nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
+ pNew = sqliteMallocRaw( nByte );
+ if( pNew==0 ) return 0;
+ pNew->nSrc = pNew->nAlloc = p->nSrc;
+ for(i=0; i<p->nSrc; i++){
+ struct SrcList_item *pNewItem = &pNew->a[i];
+ struct SrcList_item *pOldItem = &p->a[i];
+ Table *pTab;
+ pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
+ pNewItem->zName = sqliteStrDup(pOldItem->zName);
+ pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
+ pNewItem->jointype = pOldItem->jointype;
+ pNewItem->iCursor = pOldItem->iCursor;
+ pTab = pNewItem->pTab = pOldItem->pTab;
+ if( pTab ){
+ pTab->nRef++;
+ }
+ pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
+ pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
+ pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing);
+ pNewItem->colUsed = pOldItem->colUsed;
+ }
+ return pNew;
+}
+IdList *sqlite3IdListDup(IdList *p){
+ IdList *pNew;
+ int i;
+ if( p==0 ) return 0;
+ pNew = sqliteMallocRaw( sizeof(*pNew) );
+ if( pNew==0 ) return 0;
+ pNew->nId = pNew->nAlloc = p->nId;
+ pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
+ if( pNew->a==0 ){
+ sqliteFree(pNew);
+ return 0;
+ }
+ for(i=0; i<p->nId; i++){
+ struct IdList_item *pNewItem = &pNew->a[i];
+ struct IdList_item *pOldItem = &p->a[i];
+ pNewItem->zName = sqliteStrDup(pOldItem->zName);
+ pNewItem->idx = pOldItem->idx;
+ }
+ return pNew;
+}
+Select *sqlite3SelectDup(Select *p){
+ Select *pNew;
+ if( p==0 ) return 0;
+ pNew = sqliteMallocRaw( sizeof(*p) );
+ if( pNew==0 ) return 0;
+ pNew->isDistinct = p->isDistinct;
+ pNew->pEList = sqlite3ExprListDup(p->pEList);
+ pNew->pSrc = sqlite3SrcListDup(p->pSrc);
+ pNew->pWhere = sqlite3ExprDup(p->pWhere);
+ pNew->pGroupBy = sqlite3ExprListDup(p->pGroupBy);
+ pNew->pHaving = sqlite3ExprDup(p->pHaving);
+ pNew->pOrderBy = sqlite3ExprListDup(p->pOrderBy);
+ pNew->op = p->op;
+ pNew->pPrior = sqlite3SelectDup(p->pPrior);
+ pNew->pLimit = sqlite3ExprDup(p->pLimit);
+ pNew->pOffset = sqlite3ExprDup(p->pOffset);
+ pNew->iLimit = -1;
+ pNew->iOffset = -1;
+ pNew->ppOpenTemp = 0;
+ pNew->isResolved = p->isResolved;
+ pNew->isAgg = p->isAgg;
+ return pNew;
+}
+#else
+Select *sqlite3SelectDup(Select *p){
+ assert( p==0 );
+ return 0;
+}
+#endif
+
+
+/*
+** Add a new element to the end of an expression list. If pList is
+** initially NULL, then create a new expression list.
+*/
+ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
+ if( pList==0 ){
+ pList = sqliteMalloc( sizeof(ExprList) );
+ if( pList==0 ){
+ goto no_mem;
+ }
+ assert( pList->nAlloc==0 );
+ }
+ if( pList->nAlloc<=pList->nExpr ){
+ struct ExprList_item *a;
+ int n = pList->nAlloc*2 + 4;
+ a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
+ if( a==0 ){
+ goto no_mem;
+ }
+ pList->a = a;
+ pList->nAlloc = n;
+ }
+ assert( pList->a!=0 );
+ if( pExpr || pName ){
+ struct ExprList_item *pItem = &pList->a[pList->nExpr++];
+ memset(pItem, 0, sizeof(*pItem));
+ pItem->zName = sqlite3NameFromToken(pName);
+ pItem->pExpr = pExpr;
+ }
+ return pList;
+
+no_mem:
+ /* Avoid leaking memory if malloc has failed. */
+ sqlite3ExprDelete(pExpr);
+ sqlite3ExprListDelete(pList);
+ return 0;
+}
+
+/*
+** Delete an entire expression list.
+*/
+void sqlite3ExprListDelete(ExprList *pList){
+ int i;
+ struct ExprList_item *pItem;
+ if( pList==0 ) return;
+ assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
+ assert( pList->nExpr<=pList->nAlloc );
+ for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
+ sqlite3ExprDelete(pItem->pExpr);
+ sqliteFree(pItem->zName);
+ }
+ sqliteFree(pList->a);
+ sqliteFree(pList);
+}
+
+/*
+** Walk an expression tree. Call xFunc for each node visited.
+**
+** The return value from xFunc determines whether the tree walk continues.
+** 0 means continue walking the tree. 1 means do not walk children
+** of the current node but continue with siblings. 2 means abandon
+** the tree walk completely.
+**
+** The return value from this routine is 1 to abandon the tree walk
+** and 0 to continue.
+*/
+static int walkExprList(ExprList *, int (*)(void *, Expr*), void *);
+static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){
+ int rc;
+ if( pExpr==0 ) return 0;
+ rc = (*xFunc)(pArg, pExpr);
+ if( rc==0 ){
+ if( walkExprTree(pExpr->pLeft, xFunc, pArg) ) return 1;
+ if( walkExprTree(pExpr->pRight, xFunc, pArg) ) return 1;
+ if( walkExprList(pExpr->pList, xFunc, pArg) ) return 1;
+ }
+ return rc>1;
+}
+
+/*
+** Call walkExprTree() for every expression in list p.
+*/
+static int walkExprList(ExprList *p, int (*xFunc)(void *, Expr*), void *pArg){
+ int i;
+ struct ExprList_item *pItem;
+ if( !p ) return 0;
+ for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){
+ if( walkExprTree(pItem->pExpr, xFunc, pArg) ) return 1;
+ }
+ return 0;
+}
+
+/*
+** Call walkExprTree() for every expression in Select p, not including
+** expressions that are part of sub-selects in any FROM clause or the LIMIT
+** or OFFSET expressions..
+*/
+static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){
+ walkExprList(p->pEList, xFunc, pArg);
+ walkExprTree(p->pWhere, xFunc, pArg);
+ walkExprList(p->pGroupBy, xFunc, pArg);
+ walkExprTree(p->pHaving, xFunc, pArg);
+ walkExprList(p->pOrderBy, xFunc, pArg);
+ return 0;
+}
+
+
+/*
+** This routine is designed as an xFunc for walkExprTree().
+**
+** pArg is really a pointer to an integer. If we can tell by looking
+** at pExpr that the expression that contains pExpr is not a constant
+** expression, then set *pArg to 0 and return 2 to abandon the tree walk.
+** If pExpr does does not disqualify the expression from being a constant
+** then do nothing.
+**
+** After walking the whole tree, if no nodes are found that disqualify
+** the expression as constant, then we assume the whole expression
+** is constant. See sqlite3ExprIsConstant() for additional information.
+*/
+static int exprNodeIsConstant(void *pArg, Expr *pExpr){
+ switch( pExpr->op ){
+ case TK_ID:
+ case TK_COLUMN:
+ case TK_DOT:
+ case TK_AGG_FUNCTION:
+ case TK_FUNCTION:
+#ifndef SQLITE_OMIT_SUBQUERY
+ case TK_SELECT:
+ case TK_EXISTS:
+#endif
+ *((int*)pArg) = 0;
+ return 2;
+ default:
+ return 0;
+ }
+}
+
+/*
+** Walk an expression tree. Return 1 if the expression is constant
+** and 0 if it involves variables.
+**
+** For the purposes of this function, a double-quoted string (ex: "abc")
+** is considered a variable but a single-quoted string (ex: 'abc') is
+** a constant.
+*/
+int sqlite3ExprIsConstant(Expr *p){
+ int isConst = 1;
+ walkExprTree(p, exprNodeIsConstant, &isConst);
+ return isConst;
+}
+
+/*
+** If the expression p codes a constant integer that is small enough
+** to fit in a 32-bit integer, return 1 and put the value of the integer
+** in *pValue. If the expression is not an integer or if it is too big
+** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
+*/
+int sqlite3ExprIsInteger(Expr *p, int *pValue){
+ switch( p->op ){
+ case TK_INTEGER: {
+ if( sqlite3GetInt32(p->token.z, pValue) ){
+ return 1;
+ }
+ break;
+ }
+ case TK_UPLUS: {
+ return sqlite3ExprIsInteger(p->pLeft, pValue);
+ }
+ case TK_UMINUS: {
+ int v;
+ if( sqlite3ExprIsInteger(p->pLeft, &v) ){
+ *pValue = -v;
+ return 1;
+ }
+ break;
+ }
+ default: break;
+ }
+ return 0;
+}
+
+/*
+** Return TRUE if the given string is a row-id column name.
+*/
+int sqlite3IsRowid(const char *z){
+ if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
+ if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
+ if( sqlite3StrICmp(z, "OID")==0 ) return 1;
+ return 0;
+}
+
+/*
+** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
+** that name in the set of source tables in pSrcList and make the pExpr
+** expression node refer back to that source column. The following changes
+** are made to pExpr:
+**
+** pExpr->iDb Set the index in db->aDb[] of the database holding
+** the table.
+** pExpr->iTable Set to the cursor number for the table obtained
+** from pSrcList.
+** pExpr->iColumn Set to the column number within the table.
+** pExpr->op Set to TK_COLUMN.
+** pExpr->pLeft Any expression this points to is deleted
+** pExpr->pRight Any expression this points to is deleted.
+**
+** The pDbToken is the name of the database (the "X"). This value may be
+** NULL meaning that name is of the form Y.Z or Z. Any available database
+** can be used. The pTableToken is the name of the table (the "Y"). This
+** value can be NULL if pDbToken is also NULL. If pTableToken is NULL it
+** means that the form of the name is Z and that columns from any table
+** can be used.
+**
+** If the name cannot be resolved unambiguously, leave an error message
+** in pParse and return non-zero. Return zero on success.
+*/
+static int lookupName(
+ Parse *pParse, /* The parsing context */
+ Token *pDbToken, /* Name of the database containing table, or NULL */
+ Token *pTableToken, /* Name of table containing column, or NULL */
+ Token *pColumnToken, /* Name of the column. */
+ NameContext *pNC, /* The name context used to resolve the name */
+ Expr *pExpr /* Make this EXPR node point to the selected column */
+){
+ char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */
+ char *zTab = 0; /* Name of the table. The "Y" in X.Y.Z or Y.Z */
+ char *zCol = 0; /* Name of the column. The "Z" */
+ int i, j; /* Loop counters */
+ int cnt = 0; /* Number of matching column names */
+ int cntTab = 0; /* Number of matching table names */
+ sqlite3 *db = pParse->db; /* The database */
+ struct SrcList_item *pItem; /* Use for looping over pSrcList items */
+ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
+ NameContext *pTopNC = pNC; /* First namecontext in the list */
+
+ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
+ zDb = sqlite3NameFromToken(pDbToken);
+ zTab = sqlite3NameFromToken(pTableToken);
+ zCol = sqlite3NameFromToken(pColumnToken);
+ if( sqlite3_malloc_failed ){
+ goto lookupname_end;
+ }
+
+ pExpr->iTable = -1;
+ while( pNC && cnt==0 ){
+ SrcList *pSrcList = pNC->pSrcList;
+ ExprList *pEList = pNC->pEList;
+
+ /* assert( zTab==0 || pEList==0 ); */
+ if( pSrcList ){
+ for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
+ Table *pTab = pItem->pTab;
+ Column *pCol;
+
+ if( pTab==0 ) continue;
+ assert( pTab->nCol>0 );
+ if( zTab ){
+ if( pItem->zAlias ){
+ char *zTabName = pItem->zAlias;
+ if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
+ }else{
+ char *zTabName = pTab->zName;
+ if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
+ if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
+ continue;
+ }
+ }
+ }
+ if( 0==(cntTab++) ){
+ pExpr->iTable = pItem->iCursor;
+ pExpr->iDb = pTab->iDb;
+ pMatch = pItem;
+ }
+ for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
+ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
+ IdList *pUsing;
+ cnt++;
+ pExpr->iTable = pItem->iCursor;
+ pMatch = pItem;
+ pExpr->iDb = pTab->iDb;
+ /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
+ pExpr->iColumn = j==pTab->iPKey ? -1 : j;
+ pExpr->affinity = pTab->aCol[j].affinity;
+ pExpr->pColl = pTab->aCol[j].pColl;
+ if( pItem->jointype & JT_NATURAL ){
+ /* If this match occurred in the left table of a natural join,
+ ** then skip the right table to avoid a duplicate match */
+ pItem++;
+ i++;
+ }
+ if( (pUsing = pItem->pUsing)!=0 ){
+ /* If this match occurs on a column that is in the USING clause
+ ** of a join, skip the search of the right table of the join
+ ** to avoid a duplicate match there. */
+ int k;
+ for(k=0; k<pUsing->nId; k++){
+ if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
+ pItem++;
+ i++;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+#ifndef SQLITE_OMIT_TRIGGER
+ /* If we have not already resolved the name, then maybe
+ ** it is a new.* or old.* trigger argument reference
+ */
+ if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){
+ TriggerStack *pTriggerStack = pParse->trigStack;
+ Table *pTab = 0;
+ if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){
+ pExpr->iTable = pTriggerStack->newIdx;
+ assert( pTriggerStack->pTab );
+ pTab = pTriggerStack->pTab;
+ }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){
+ pExpr->iTable = pTriggerStack->oldIdx;
+ assert( pTriggerStack->pTab );
+ pTab = pTriggerStack->pTab;
+ }
+
+ if( pTab ){
+ int j;
+ Column *pCol = pTab->aCol;
+
+ pExpr->iDb = pTab->iDb;
+ cntTab++;
+ for(j=0; j < pTab->nCol; j++, pCol++) {
+ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
+ cnt++;
+ pExpr->iColumn = j==pTab->iPKey ? -1 : j;
+ pExpr->affinity = pTab->aCol[j].affinity;
+ pExpr->pColl = pTab->aCol[j].pColl;
+ pExpr->pTab = pTab;
+ break;
+ }
+ }
+ }
+ }
+#endif /* !defined(SQLITE_OMIT_TRIGGER) */
+
+ /*
+ ** Perhaps the name is a reference to the ROWID
+ */
+ if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
+ cnt = 1;
+ pExpr->iColumn = -1;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
+ }
+
+ /*
+ ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
+ ** might refer to an result-set alias. This happens, for example, when
+ ** we are resolving names in the WHERE clause of the following command:
+ **
+ ** SELECT a+b AS x FROM table WHERE x<10;
+ **
+ ** In cases like this, replace pExpr with a copy of the expression that
+ ** forms the result set entry ("a+b" in the example) and return immediately.
+ ** Note that the expression in the result set should have already been
+ ** resolved by the time the WHERE clause is resolved.
+ */
+ if( cnt==0 && pEList!=0 && zTab==0 ){
+ for(j=0; j<pEList->nExpr; j++){
+ char *zAs = pEList->a[j].zName;
+ if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
+ assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+ pExpr->op = TK_AS;
+ pExpr->iColumn = j;
+ pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr);
+ cnt = 1;
+ assert( zTab==0 && zDb==0 );
+ goto lookupname_end_2;
+ }
+ }
+ }
+
+ /* Advance to the next name context. The loop will exit when either
+ ** we have a match (cnt>0) or when we run out of name contexts.
+ */
+ if( cnt==0 ){
+ pNC = pNC->pNext;
+ }
+ }
+
+ /*
+ ** If X and Y are NULL (in other words if only the column name Z is
+ ** supplied) and the value of Z is enclosed in double-quotes, then
+ ** Z is a string literal if it doesn't match any column names. In that
+ ** case, we need to return right away and not make any changes to
+ ** pExpr.
+ **
+ ** Because no reference was made to outer contexts, the pNC->nRef
+ ** fields are not changed in any context.
+ */
+ if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
+ sqliteFree(zCol);
+ return 0;
+ }
+
+ /*
+ ** cnt==0 means there was not match. cnt>1 means there were two or
+ ** more matches. Either way, we have an error.
+ */
+ if( cnt!=1 ){
+ char *z = 0;
+ char *zErr;
+ zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
+ if( zDb ){
+ sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, 0);
+ }else if( zTab ){
+ sqlite3SetString(&z, zTab, ".", zCol, 0);
+ }else{
+ z = sqliteStrDup(zCol);
+ }
+ sqlite3ErrorMsg(pParse, zErr, z);
+ sqliteFree(z);
+ pTopNC->nErr++;
+ }
+
+ /* If a column from a table in pSrcList is referenced, then record
+ ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
+ ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the
+ ** column number is greater than the number of bits in the bitmask
+ ** then set the high-order bit of the bitmask.
+ */
+ if( pExpr->iColumn>=0 && pMatch!=0 ){
+ int n = pExpr->iColumn;
+ if( n>=sizeof(Bitmask)*8 ){
+ n = sizeof(Bitmask)*8-1;
+ }
+ assert( pMatch->iCursor==pExpr->iTable );
+ pMatch->colUsed |= 1<<n;
+ }
+
+lookupname_end:
+ /* Clean up and return
+ */
+ sqliteFree(zDb);
+ sqliteFree(zTab);
+ sqlite3ExprDelete(pExpr->pLeft);
+ pExpr->pLeft = 0;
+ sqlite3ExprDelete(pExpr->pRight);
+ pExpr->pRight = 0;
+ pExpr->op = TK_COLUMN;
+lookupname_end_2:
+ sqliteFree(zCol);
+ if( cnt==1 ){
+ assert( pNC!=0 );
+ sqlite3AuthRead(pParse, pExpr, pNC->pSrcList);
+ if( pMatch && !pMatch->pSelect ){
+ pExpr->pTab = pMatch->pTab;
+ }
+ /* Increment the nRef value on all name contexts from TopNC up to
+ ** the point where the name matched. */
+ for(;;){
+ assert( pTopNC!=0 );
+ pTopNC->nRef++;
+ if( pTopNC==pNC ) break;
+ pTopNC = pTopNC->pNext;
+ }
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+/*
+** This routine is designed as an xFunc for walkExprTree().
+**
+** Resolve symbolic names into TK_COLUMN operators for the current
+** node in the expression tree. Return 0 to continue the search down
+** the tree or 2 to abort the tree walk.
+**
+** This routine also does error checking and name resolution for
+** function names. The operator for aggregate functions is changed
+** to TK_AGG_FUNCTION.
+*/
+static int nameResolverStep(void *pArg, Expr *pExpr){
+ NameContext *pNC = (NameContext*)pArg;
+ SrcList *pSrcList;
+ Parse *pParse;
+
+ if( pExpr==0 ) return 1;
+ assert( pNC!=0 );
+ pSrcList = pNC->pSrcList;
+ pParse = pNC->pParse;
+
+ if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1;
+ ExprSetProperty(pExpr, EP_Resolved);
+#ifndef NDEBUG
+ if( pSrcList ){
+ int i;
+ for(i=0; i<pSrcList->nSrc; i++){
+ assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
+ }
+ }
+#endif
+ switch( pExpr->op ){
+ /* Double-quoted strings (ex: "abc") are used as identifiers if
+ ** possible. Otherwise they remain as strings. Single-quoted
+ ** strings (ex: 'abc') are always string literals.
+ */
+ case TK_STRING: {
+ if( pExpr->token.z[0]=='\'' ) break;
+ /* Fall thru into the TK_ID case if this is a double-quoted string */
+ }
+ /* A lone identifier is the name of a column.
+ */
+ case TK_ID: {
+ lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr);
+ return 1;
+ }
+
+ /* A table name and column name: ID.ID
+ ** Or a database, table and column: ID.ID.ID
+ */
+ case TK_DOT: {
+ Token *pColumn;
+ Token *pTable;
+ Token *pDb;
+ Expr *pRight;
+
+ /* if( pSrcList==0 ) break; */
+ pRight = pExpr->pRight;
+ if( pRight->op==TK_ID ){
+ pDb = 0;
+ pTable = &pExpr->pLeft->token;
+ pColumn = &pRight->token;
+ }else{
+ assert( pRight->op==TK_DOT );
+ pDb = &pExpr->pLeft->token;
+ pTable = &pRight->pLeft->token;
+ pColumn = &pRight->pRight->token;
+ }
+ lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);
+ return 1;
+ }
+
+ /* Resolve function names
+ */
+ case TK_CONST_FUNC:
+ case TK_FUNCTION: {
+ ExprList *pList = pExpr->pList; /* The argument list */
+ int n = pList ? pList->nExpr : 0; /* Number of arguments */
+ int no_such_func = 0; /* True if no such function exists */
+ int wrong_num_args = 0; /* True if wrong number of arguments */
+ int is_agg = 0; /* True if is an aggregate function */
+ int i;
+ int nId; /* Number of characters in function name */
+ const char *zId; /* The function name. */
+ FuncDef *pDef; /* Information about the function */
+ int enc = pParse->db->enc; /* The database encoding */
+
+ zId = pExpr->token.z;
+ nId = pExpr->token.n;
+ pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
+ if( pDef==0 ){
+ pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
+ if( pDef==0 ){
+ no_such_func = 1;
+ }else{
+ wrong_num_args = 1;
+ }
+ }else{
+ is_agg = pDef->xFunc==0;
+ }
+ if( is_agg && !pNC->allowAgg ){
+ sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
+ pNC->nErr++;
+ is_agg = 0;
+ }else if( no_such_func ){
+ sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
+ pNC->nErr++;
+ }else if( wrong_num_args ){
+ sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
+ nId, zId);
+ pNC->nErr++;
+ }
+ if( is_agg ){
+ pExpr->op = TK_AGG_FUNCTION;
+ pNC->hasAgg = 1;
+ }
+ if( is_agg ) pNC->allowAgg = 0;
+ for(i=0; pNC->nErr==0 && i<n; i++){
+ walkExprTree(pList->a[i].pExpr, nameResolverStep, pNC);
+ }
+ if( is_agg ) pNC->allowAgg = 1;
+ /* FIX ME: Compute pExpr->affinity based on the expected return
+ ** type of the function
+ */
+ return is_agg;
+ }
+#ifndef SQLITE_OMIT_SUBQUERY
+ case TK_SELECT:
+ case TK_EXISTS:
+#endif
+ case TK_IN: {
+ if( pExpr->pSelect ){
+ int nRef = pNC->nRef;
+ sqlite3SelectResolve(pParse, pExpr->pSelect, pNC);
+ assert( pNC->nRef>=nRef );
+ if( nRef!=pNC->nRef ){
+ ExprSetProperty(pExpr, EP_VarSelect);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** This routine walks an expression tree and resolves references to
+** table columns. Nodes of the form ID.ID or ID resolve into an
+** index to the table in the table list and a column offset. The
+** Expr.opcode for such nodes is changed to TK_COLUMN. The Expr.iTable
+** value is changed to the index of the referenced table in pTabList
+** plus the "base" value. The base value will ultimately become the
+** VDBE cursor number for a cursor that is pointing into the referenced
+** table. The Expr.iColumn value is changed to the index of the column
+** of the referenced table. The Expr.iColumn value for the special
+** ROWID column is -1. Any INTEGER PRIMARY KEY column is tried as an
+** alias for ROWID.
+**
+** Also resolve function names and check the functions for proper
+** usage. Make sure all function names are recognized and all functions
+** have the correct number of arguments. Leave an error message
+** in pParse->zErrMsg if anything is amiss. Return the number of errors.
+**
+** If the expression contains aggregate functions then set the EP_Agg
+** property on the expression.
+*/
+int sqlite3ExprResolveNames(
+ NameContext *pNC, /* Namespace to resolve expressions in. */
+ Expr *pExpr /* The expression to be analyzed. */
+){
+ if( pExpr==0 ) return 0;
+ walkExprTree(pExpr, nameResolverStep, pNC);
+ if( pNC->nErr>0 ){
+ ExprSetProperty(pExpr, EP_Error);
+ }
+ return ExprHasProperty(pExpr, EP_Error);
+}
+
+/*
+** A pointer instance of this structure is used to pass information
+** through walkExprTree into codeSubqueryStep().
+*/
+typedef struct QueryCoder QueryCoder;
+struct QueryCoder {
+ Parse *pParse; /* The parsing context */
+ NameContext *pNC; /* Namespace of first enclosing query */
+};
+
+
+/*
+** Generate code for subqueries and IN operators.
+**
+** IN operators comes in two forms:
+**
+** expr IN (exprlist)
+** and
+** expr IN (SELECT ...)
+**
+** The first form is handled by creating a set holding the list
+** of allowed values. The second form causes the SELECT to generate
+** a temporary table.
+*/
+#ifndef SQLITE_OMIT_SUBQUERY
+void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
+ int label = 0; /* Address after sub-select code */
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return;
+
+ /* If this is not a variable (correlated) select, then execute
+ ** it only once. Unless this is part of a trigger program. In
+ ** that case re-execute every time (this could be optimized).
+ */
+ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
+ int mem = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
+ label = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_If, 0, label);
+ sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, mem, 1);
+ }
+
+ if( pExpr->pSelect ){
+ sqlite3VdbeAddOp(v, OP_AggContextPush, 0, 0);
+ }
+
+ switch( pExpr->op ){
+ case TK_IN: {
+ char affinity;
+ KeyInfo keyInfo;
+ int addr; /* Address of OP_OpenTemp instruction */
+
+ affinity = sqlite3ExprAffinity(pExpr->pLeft);
+
+ /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
+ ** expression it is handled the same way. A temporary table is
+ ** filled with single-field index keys representing the results
+ ** from the SELECT or the <exprlist>.
+ **
+ ** If the 'x' expression is a column value, or the SELECT...
+ ** statement returns a column value, then the affinity of that
+ ** column is used to build the index keys. If both 'x' and the
+ ** SELECT... statement are columns, then numeric affinity is used
+ ** if either column has NUMERIC or INTEGER affinity. If neither
+ ** 'x' nor the SELECT... statement are columns, then numeric affinity
+ ** is used.
+ */
+ pExpr->iTable = pParse->nTab++;
+ addr = sqlite3VdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 0);
+ memset(&keyInfo, 0, sizeof(keyInfo));
+ keyInfo.nField = 1;
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1);
+
+ if( pExpr->pSelect ){
+ /* Case 1: expr IN (SELECT ...)
+ **
+ ** Generate code to write the results of the select into the temporary
+ ** table allocated and opened above.
+ */
+ int iParm = pExpr->iTable + (((int)affinity)<<16);
+ ExprList *pEList;
+ assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
+ sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0);
+ pEList = pExpr->pSelect->pEList;
+ if( pEList && pEList->nExpr>0 ){
+ keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft,
+ pEList->a[0].pExpr);
+ }
+ }else if( pExpr->pList ){
+ /* Case 2: expr IN (exprlist)
+ **
+ ** For each expression, build an index key from the evaluation and
+ ** store it in the temporary table. If <expr> is a column, then use
+ ** that columns affinity when building index keys. If <expr> is not
+ ** a column, use numeric affinity.
+ */
+ int i;
+ if( !affinity ){
+ affinity = SQLITE_AFF_NUMERIC;
+ }
+ keyInfo.aColl[0] = pExpr->pLeft->pColl;
+
+ /* Loop through each expression in <exprlist>. */
+ for(i=0; i<pExpr->pList->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;
+ }
+
+ /* Evaluate the expression and insert it into the temp table */
+ sqlite3ExprCode(pParse, pE2);
+ sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
+ sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0);
+ }
+ }
+ sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
+ break;
+ }
+
+ case TK_EXISTS:
+ case TK_SELECT: {
+ /* This has to be a scalar SELECT. Generate code to put the
+ ** value of this select in a memory cell and record the number
+ ** of the memory cell in iColumn.
+ */
+ int sop;
+ Select *pSel;
+
+ pExpr->iColumn = pParse->nMem++;
+ pSel = pExpr->pSelect;
+ if( pExpr->op==TK_SELECT ){
+ sop = SRT_Mem;
+ }else{
+ static const Token one = { "1", 0, 1 };
+ sop = SRT_Exists;
+ sqlite3ExprListDelete(pSel->pEList);
+ pSel->pEList = sqlite3ExprListAppend(0,
+ sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
+ }
+ sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0);
+ break;
+ }
+ }
+
+ if( pExpr->pSelect ){
+ sqlite3VdbeAddOp(v, OP_AggContextPop, 0, 0);
+ }
+ if( label<0 ){
+ sqlite3VdbeResolveLabel(v, label);
+ }
+ return;
+}
+#endif /* SQLITE_OMIT_SUBQUERY */
+
+/*
+** Generate an instruction that will put the integer describe by
+** text z[0..n-1] on the stack.
+*/
+static void codeInteger(Vdbe *v, const char *z, int n){
+ int i;
+ if( sqlite3GetInt32(z, &i) ){
+ sqlite3VdbeAddOp(v, OP_Integer, i, 0);
+ }else if( sqlite3FitsIn64Bits(z) ){
+ sqlite3VdbeOp3(v, OP_Integer, 0, 0, z, n);
+ }else{
+ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);
+ }
+}
+
+/*
+** Generate code into the current Vdbe to evaluate the given
+** expression and leave the result on the top of stack.
+**
+** This code depends on the fact that certain token values (ex: TK_EQ)
+** are the same as opcode values (ex: OP_Eq) that implement the corresponding
+** operation. Special comments in vdbe.c and the mkopcodeh.awk script in
+** the make process cause these values to align. Assert()s in the code
+** below verify that the numbers are aligned correctly.
+*/
+void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
+ Vdbe *v = pParse->pVdbe;
+ int op;
+ if( v==0 ) return;
+ if( pExpr==0 ){
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ return;
+ }
+ op = pExpr->op;
+ switch( op ){
+ case TK_COLUMN: {
+ if( !pParse->fillAgg && pExpr->iAgg>=0 ){
+ sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg);
+ }else if( pExpr->iColumn>=0 ){
+ sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
+ sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0);
+ }
+ break;
+ }
+ case TK_INTEGER: {
+ codeInteger(v, pExpr->token.z, pExpr->token.n);
+ break;
+ }
+ case TK_FLOAT:
+ case TK_STRING: {
+ assert( TK_FLOAT==OP_Real );
+ assert( TK_STRING==OP_String8 );
+ sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
+ sqlite3VdbeDequoteP3(v, -1);
+ break;
+ }
+ case TK_NULL: {
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ break;
+ }
+#ifndef SQLITE_OMIT_BLOB_LITERAL
+ case TK_BLOB: {
+ assert( TK_BLOB==OP_HexBlob );
+ sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1);
+ sqlite3VdbeDequoteP3(v, -1);
+ break;
+ }
+#endif
+ case TK_VARIABLE: {
+ sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
+ if( pExpr->token.n>1 ){
+ sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
+ }
+ break;
+ }
+ case TK_REGISTER: {
+ sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);
+ break;
+ }
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_NE:
+ case TK_EQ: {
+ assert( TK_LT==OP_Lt );
+ assert( TK_LE==OP_Le );
+ assert( TK_GT==OP_Gt );
+ assert( TK_GE==OP_Ge );
+ assert( TK_EQ==OP_Eq );
+ assert( TK_NE==OP_Ne );
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ sqlite3ExprCode(pParse, pExpr->pRight);
+ codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
+ break;
+ }
+ case TK_AND:
+ case TK_OR:
+ case TK_PLUS:
+ case TK_STAR:
+ case TK_MINUS:
+ case TK_REM:
+ case TK_BITAND:
+ case TK_BITOR:
+ case TK_SLASH:
+ case TK_LSHIFT:
+ case TK_RSHIFT:
+ case TK_CONCAT: {
+ assert( TK_AND==OP_And );
+ assert( TK_OR==OP_Or );
+ assert( TK_PLUS==OP_Add );
+ assert( TK_MINUS==OP_Subtract );
+ assert( TK_REM==OP_Remainder );
+ assert( TK_BITAND==OP_BitAnd );
+ assert( TK_BITOR==OP_BitOr );
+ assert( TK_SLASH==OP_Divide );
+ assert( TK_LSHIFT==OP_ShiftLeft );
+ assert( TK_RSHIFT==OP_ShiftRight );
+ assert( TK_CONCAT==OP_Concat );
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ sqlite3ExprCode(pParse, pExpr->pRight);
+ sqlite3VdbeAddOp(v, op, 0, 0);
+ break;
+ }
+ case TK_UMINUS: {
+ Expr *pLeft = pExpr->pLeft;
+ assert( pLeft );
+ if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
+ Token *p = &pLeft->token;
+ char *z = sqliteMalloc( p->n + 2 );
+ sprintf(z, "-%.*s", p->n, p->z);
+ if( pLeft->op==TK_FLOAT ){
+ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
+ }else{
+ codeInteger(v, z, p->n+1);
+ }
+ sqliteFree(z);
+ break;
+ }
+ /* Fall through into TK_NOT */
+ }
+ case TK_BITNOT:
+ case TK_NOT: {
+ assert( TK_BITNOT==OP_BitNot );
+ assert( TK_NOT==OP_Not );
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ sqlite3VdbeAddOp(v, op, 0, 0);
+ break;
+ }
+ case TK_ISNULL:
+ case TK_NOTNULL: {
+ int dest;
+ assert( TK_ISNULL==OP_IsNull );
+ assert( TK_NOTNULL==OP_NotNull );
+ sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ dest = sqlite3VdbeCurrentAddr(v) + 2;
+ sqlite3VdbeAddOp(v, op, 1, dest);
+ sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
+ break;
+ }
+ case TK_AGG_FUNCTION: {
+ sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
+ break;
+ }
+ case TK_CONST_FUNC:
+ case TK_FUNCTION: {
+ ExprList *pList = pExpr->pList;
+ int nExpr = pList ? pList->nExpr : 0;
+ FuncDef *pDef;
+ int nId;
+ const char *zId;
+ int p2 = 0;
+ int i;
+ u8 enc = pParse->db->enc;
+ CollSeq *pColl = 0;
+ zId = pExpr->token.z;
+ nId = pExpr->token.n;
+ pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
+ assert( pDef!=0 );
+ nExpr = sqlite3ExprCodeExprList(pParse, pList);
+ for(i=0; i<nExpr && i<32; i++){
+ if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
+ p2 |= (1<<i);
+ }
+ if( pDef->needCollSeq && !pColl ){
+ pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
+ }
+ }
+ if( pDef->needCollSeq ){
+ if( !pColl ) pColl = pParse->db->pDfltColl;
+ sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
+ }
+ sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF);
+ break;
+ }
+#ifndef SQLITE_OMIT_SUBQUERY
+ case TK_EXISTS:
+ case TK_SELECT: {
+ sqlite3CodeSubselect(pParse, pExpr);
+ sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
+ VdbeComment((v, "# load subquery result"));
+ break;
+ }
+ case TK_IN: {
+ int addr;
+ char affinity;
+ sqlite3CodeSubselect(pParse, pExpr);
+
+ /* Figure out the affinity to use to create a key from the results
+ ** of the expression. affinityStr stores a static string suitable for
+ ** P3 of OP_MakeRecord.
+ */
+ affinity = comparisonAffinity(pExpr);
+
+ sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
+
+ /* Code the <expr> from "<expr> IN (...)". The temporary table
+ ** pExpr->iTable contains the values that make up the (...) set.
+ */
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ addr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4); /* addr + 0 */
+ sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
+ sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */
+ sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
+ sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); /* addr + 6 */
+
+ break;
+ }
+#endif
+ case TK_BETWEEN: {
+ Expr *pLeft = pExpr->pLeft;
+ struct ExprList_item *pLItem = pExpr->pList->a;
+ Expr *pRight = pLItem->pExpr;
+ sqlite3ExprCode(pParse, pLeft);
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ sqlite3ExprCode(pParse, pRight);
+ codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+ pLItem++;
+ pRight = pLItem->pExpr;
+ sqlite3ExprCode(pParse, pRight);
+ codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
+ sqlite3VdbeAddOp(v, OP_And, 0, 0);
+ break;
+ }
+ case TK_UPLUS:
+ case TK_AS: {
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ break;
+ }
+ case TK_CASE: {
+ int expr_end_label;
+ int jumpInst;
+ int addr;
+ int nExpr;
+ int i;
+ ExprList *pEList;
+ struct ExprList_item *aListelem;
+
+ assert(pExpr->pList);
+ assert((pExpr->pList->nExpr % 2) == 0);
+ assert(pExpr->pList->nExpr > 0);
+ pEList = pExpr->pList;
+ aListelem = pEList->a;
+ nExpr = pEList->nExpr;
+ expr_end_label = sqlite3VdbeMakeLabel(v);
+ if( pExpr->pLeft ){
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ }
+ for(i=0; i<nExpr; i=i+2){
+ sqlite3ExprCode(pParse, aListelem[i].pExpr);
+ if( pExpr->pLeft ){
+ sqlite3VdbeAddOp(v, OP_Dup, 1, 1);
+ jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
+ OP_Ne, 0, 1);
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ }else{
+ jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);
+ }
+ sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);
+ addr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeChangeP2(v, jumpInst, addr);
+ }
+ if( pExpr->pLeft ){
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ }
+ if( pExpr->pRight ){
+ sqlite3ExprCode(pParse, pExpr->pRight);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ }
+ sqlite3VdbeResolveLabel(v, expr_end_label);
+ break;
+ }
+#ifndef SQLITE_OMIT_TRIGGER
+ case TK_RAISE: {
+ if( !pParse->trigStack ){
+ sqlite3ErrorMsg(pParse,
+ "RAISE() may only be used within a trigger-program");
+ return;
+ }
+ if( pExpr->iColumn!=OE_Ignore ){
+ assert( pExpr->iColumn==OE_Rollback ||
+ pExpr->iColumn == OE_Abort ||
+ pExpr->iColumn == OE_Fail );
+ 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);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
+ VdbeComment((v, "# raise(IGNORE)"));
+ }
+ }
+#endif
+ break;
+ }
+}
+
+#ifndef SQLITE_OMIT_TRIGGER
+/*
+** Generate code that evalutes the given expression and leaves the result
+** on the stack. See also sqlite3ExprCode().
+**
+** This routine might also cache the result and modify the pExpr tree
+** so that it will make use of the cached result on subsequent evaluations
+** rather than evaluate the whole expression again. Trivial expressions are
+** not cached. If the expression is cached, its result is stored in a
+** memory location.
+*/
+void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){
+ Vdbe *v = pParse->pVdbe;
+ int iMem;
+ int addr1, addr2;
+ if( v==0 ) return;
+ addr1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3ExprCode(pParse, pExpr);
+ addr2 = sqlite3VdbeCurrentAddr(v);
+ if( addr2>addr1+1 || sqlite3VdbeGetOp(v, addr1)->opcode==OP_Function ){
+ iMem = pExpr->iTable = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
+ pExpr->op = TK_REGISTER;
+ }
+}
+#endif
+
+/*
+** Generate code that pushes the value of every element of the given
+** expression list onto the stack.
+**
+** Return the number of elements pushed onto the stack.
+*/
+int sqlite3ExprCodeExprList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList /* The expression list to be coded */
+){
+ 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; i<n; i++, pItem++){
+ sqlite3ExprCode(pParse, pItem->pExpr);
+ }
+ return n;
+}
+
+/*
+** Generate code for a boolean expression such that a jump is made
+** to the label "dest" if the expression is true but execution
+** continues straight thru if the expression is false.
+**
+** If the expression evaluates to NULL (neither true nor false), then
+** take the jump if the jumpIfNull flag is true.
+**
+** This code depends on the fact that certain token values (ex: TK_EQ)
+** are the same as opcode values (ex: OP_Eq) that implement the corresponding
+** operation. Special comments in vdbe.c and the mkopcodeh.awk script in
+** the make process cause these values to align. Assert()s in the code
+** below verify that the numbers are aligned correctly.
+*/
+void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
+ Vdbe *v = pParse->pVdbe;
+ int op = 0;
+ if( v==0 || pExpr==0 ) return;
+ op = pExpr->op;
+ switch( op ){
+ case TK_AND: {
+ int d2 = sqlite3VdbeMakeLabel(v);
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
+ break;
+ }
+ case TK_OR: {
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ break;
+ }
+ case TK_NOT: {
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ break;
+ }
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_NE:
+ case TK_EQ: {
+ assert( TK_LT==OP_Lt );
+ assert( TK_LE==OP_Le );
+ assert( TK_GT==OP_Gt );
+ assert( TK_GE==OP_Ge );
+ assert( TK_EQ==OP_Eq );
+ assert( TK_NE==OP_Ne );
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ sqlite3ExprCode(pParse, pExpr->pRight);
+ codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
+ break;
+ }
+ case TK_ISNULL:
+ case TK_NOTNULL: {
+ assert( TK_ISNULL==OP_IsNull );
+ assert( TK_NOTNULL==OP_NotNull );
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ sqlite3VdbeAddOp(v, op, 1, dest);
+ break;
+ }
+ case TK_BETWEEN: {
+ /* The expression "x BETWEEN y AND z" is implemented as:
+ **
+ ** 1 IF (x < y) GOTO 3
+ ** 2 IF (x <= z) GOTO <dest>
+ ** 3 ...
+ */
+ int addr;
+ Expr *pLeft = pExpr->pLeft;
+ Expr *pRight = pExpr->pList->a[0].pExpr;
+ sqlite3ExprCode(pParse, pLeft);
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ sqlite3ExprCode(pParse, pRight);
+ addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
+
+ pRight = pExpr->pList->a[1].pExpr;
+ sqlite3ExprCode(pParse, pRight);
+ codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);
+
+ sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+ sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ break;
+ }
+ default: {
+ sqlite3ExprCode(pParse, pExpr);
+ sqlite3VdbeAddOp(v, OP_If, jumpIfNull, dest);
+ break;
+ }
+ }
+}
+
+/*
+** Generate code for a boolean expression such that a jump is made
+** to the label "dest" if the expression is false but execution
+** continues straight thru if the expression is true.
+**
+** If the expression evaluates to NULL (neither true nor false) then
+** jump if jumpIfNull is true or fall through if jumpIfNull is false.
+*/
+void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
+ Vdbe *v = pParse->pVdbe;
+ int op = 0;
+ if( v==0 || pExpr==0 ) return;
+
+ /* The value of pExpr->op and op are related as follows:
+ **
+ ** pExpr->op op
+ ** --------- ----------
+ ** TK_ISNULL OP_NotNull
+ ** TK_NOTNULL OP_IsNull
+ ** TK_NE OP_Eq
+ ** TK_EQ OP_Ne
+ ** TK_GT OP_Le
+ ** TK_LE OP_Gt
+ ** TK_GE OP_Lt
+ ** TK_LT OP_Ge
+ **
+ ** For other values of pExpr->op, op is undefined and unused.
+ ** The value of TK_ and OP_ constants are arranged such that we
+ ** can compute the mapping above using the following expression.
+ ** Assert()s verify that the computation is correct.
+ */
+ op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);
+
+ /* Verify correct alignment of TK_ and OP_ constants
+ */
+ assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
+ assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
+ assert( pExpr->op!=TK_NE || op==OP_Eq );
+ assert( pExpr->op!=TK_EQ || op==OP_Ne );
+ assert( pExpr->op!=TK_LT || op==OP_Ge );
+ assert( pExpr->op!=TK_LE || op==OP_Gt );
+ assert( pExpr->op!=TK_GT || op==OP_Le );
+ assert( pExpr->op!=TK_GE || op==OP_Lt );
+
+ switch( pExpr->op ){
+ case TK_AND: {
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ break;
+ }
+ case TK_OR: {
+ int d2 = sqlite3VdbeMakeLabel(v);
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
+ break;
+ }
+ case TK_NOT: {
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ break;
+ }
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_NE:
+ case TK_EQ: {
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ sqlite3ExprCode(pParse, pExpr->pRight);
+ codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
+ break;
+ }
+ case TK_ISNULL:
+ case TK_NOTNULL: {
+ sqlite3ExprCode(pParse, pExpr->pLeft);
+ sqlite3VdbeAddOp(v, op, 1, dest);
+ break;
+ }
+ case TK_BETWEEN: {
+ /* The expression is "x BETWEEN y AND z". It is implemented as:
+ **
+ ** 1 IF (x >= y) GOTO 3
+ ** 2 GOTO <dest>
+ ** 3 IF (x > z) GOTO <dest>
+ */
+ int addr;
+ Expr *pLeft = pExpr->pLeft;
+ Expr *pRight = pExpr->pList->a[0].pExpr;
+ sqlite3ExprCode(pParse, pLeft);
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ sqlite3ExprCode(pParse, pRight);
+ addr = sqlite3VdbeCurrentAddr(v);
+ codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
+
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, dest);
+ pRight = pExpr->pList->a[1].pExpr;
+ sqlite3ExprCode(pParse, pRight);
+ codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull);
+ break;
+ }
+ default: {
+ sqlite3ExprCode(pParse, pExpr);
+ sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
+ break;
+ }
+ }
+}
+
+/*
+** Do a deep comparison of two expression trees. Return TRUE (non-zero)
+** if they are identical and return FALSE if they differ in any way.
+*/
+int sqlite3ExprCompare(Expr *pA, Expr *pB){
+ int i;
+ if( pA==0 ){
+ return pB==0;
+ }else if( pB==0 ){
+ return 0;
+ }
+ if( pA->op!=pB->op ) return 0;
+ if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0;
+ if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0;
+ if( pA->pList ){
+ if( pB->pList==0 ) return 0;
+ if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
+ for(i=0; i<pA->pList->nExpr; i++){
+ if( !sqlite3ExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
+ return 0;
+ }
+ }
+ }else if( pB->pList ){
+ return 0;
+ }
+ if( pA->pSelect || pB->pSelect ) return 0;
+ if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
+ if( pA->token.z ){
+ if( pB->token.z==0 ) return 0;
+ if( pB->token.n!=pA->token.n ) return 0;
+ if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
+ }
+ return 1;
+}
+
+/*
+** Add a new element to the pParse->aAgg[] array and return its index.
+** The new element is initialized to zero. The calling function is
+** expected to fill it in.
+*/
+static int appendAggInfo(Parse *pParse){
+ if( (pParse->nAgg & 0x7)==0 ){
+ int amt = pParse->nAgg + 8;
+ AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
+ if( aAgg==0 ){
+ return -1;
+ }
+ pParse->aAgg = aAgg;
+ }
+ memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
+ return pParse->nAgg++;
+}
+
+/*
+** This is an xFunc for walkExprTree() used to implement
+** sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates
+** for additional information.
+**
+** This routine analyzes the aggregate function at pExpr.
+*/
+static int analyzeAggregate(void *pArg, Expr *pExpr){
+ int i;
+ AggExpr *aAgg;
+ NameContext *pNC = (NameContext *)pArg;
+ Parse *pParse = pNC->pParse;
+ SrcList *pSrcList = pNC->pSrcList;
+
+ switch( pExpr->op ){
+ case TK_COLUMN: {
+ for(i=0; pSrcList && i<pSrcList->nSrc; i++){
+ if( pExpr->iTable==pSrcList->a[i].iCursor ){
+ aAgg = pParse->aAgg;
+ for(i=0; i<pParse->nAgg; i++){
+ if( aAgg[i].isAgg ) continue;
+ if( aAgg[i].pExpr->iTable==pExpr->iTable
+ && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
+ break;
+ }
+ }
+ if( i>=pParse->nAgg ){
+ i = appendAggInfo(pParse);
+ if( i<0 ) return 1;
+ pParse->aAgg[i].isAgg = 0;
+ pParse->aAgg[i].pExpr = pExpr;
+ }
+ pExpr->iAgg = i;
+ pExpr->iAggCtx = pNC->nDepth;
+ return 1;
+ }
+ }
+ return 1;
+ }
+ case TK_AGG_FUNCTION: {
+ if( pNC->nDepth==0 ){
+ aAgg = pParse->aAgg;
+ for(i=0; i<pParse->nAgg; i++){
+ if( !aAgg[i].isAgg ) continue;
+ if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){
+ break;
+ }
+ }
+ if( i>=pParse->nAgg ){
+ u8 enc = pParse->db->enc;
+ i = appendAggInfo(pParse);
+ if( i<0 ) return 1;
+ pParse->aAgg[i].isAgg = 1;
+ pParse->aAgg[i].pExpr = pExpr;
+ pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db,
+ pExpr->token.z, pExpr->token.n,
+ pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);
+ }
+ pExpr->iAgg = i;
+ return 1;
+ }
+ }
+ }
+ if( pExpr->pSelect ){
+ pNC->nDepth++;
+ walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC);
+ pNC->nDepth--;
+ }
+ return 0;
+}
+
+/*
+** Analyze the given expression looking for aggregate functions and
+** for variables that need to be added to the pParse->aAgg[] array.
+** Make additional entries to the pParse->aAgg[] array as necessary.
+**
+** This routine should only be called after the expression has been
+** analyzed by sqlite3ExprResolveNames().
+**
+** If errors are seen, leave an error message in zErrMsg and return
+** the number of errors.
+*/
+int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
+ int nErr = pNC->pParse->nErr;
+ walkExprTree(pExpr, analyzeAggregate, pNC);
+ return pNC->pParse->nErr - nErr;
+}
diff --git a/src/sqlite/func.c b/src/sqlite/func.c
new file mode 100644
index 0000000..6b05335
--- /dev/null
+++ b/src/sqlite/func.c
@@ -0,0 +1,1043 @@
+/*
+** 2002 February 23
+**
+** 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 the C functions that implement various SQL
+** functions of SQLite.
+**
+** There is only one exported symbol in this file - the function
+** sqliteRegisterBuildinFunctions() found at the bottom of the file.
+** All other code has file scope.
+**
+** $Id: func.c,v 1.1.1.1 2006/02/03 20:35:12 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include <ctype.h>
+#include <math.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "vdbeInt.h"
+#include "os.h"
+
+static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
+ return context->pColl;
+}
+
+/*
+** Implementation of the non-aggregate min() and max() functions
+*/
+static void minmaxFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ int mask; /* 0 for min() or 0xffffffff for max() */
+ int iBest;
+ CollSeq *pColl;
+
+ if( argc==0 ) return;
+ mask = sqlite3_user_data(context)==0 ? 0 : -1;
+ pColl = sqlite3GetFuncCollSeq(context);
+ assert( pColl );
+ assert( mask==-1 || mask==0 );
+ iBest = 0;
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ for(i=1; i<argc; i++){
+ if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
+ if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
+ iBest = i;
+ }
+ }
+ sqlite3_result_value(context, argv[iBest]);
+}
+
+/*
+** Return the type of the argument.
+*/
+static void typeofFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *z = 0;
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_NULL: z = "null"; break;
+ case SQLITE_INTEGER: z = "integer"; break;
+ case SQLITE_TEXT: z = "text"; break;
+ case SQLITE_FLOAT: z = "real"; break;
+ case SQLITE_BLOB: z = "blob"; break;
+ }
+ sqlite3_result_text(context, z, -1, SQLITE_STATIC);
+}
+
+/*
+** Implementation of the length() function
+*/
+static void lengthFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int len;
+
+ assert( argc==1 );
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_BLOB:
+ case SQLITE_INTEGER:
+ case SQLITE_FLOAT: {
+ sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
+ break;
+ }
+ case SQLITE_TEXT: {
+ const char *z = sqlite3_value_text(argv[0]);
+ for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
+ sqlite3_result_int(context, len);
+ break;
+ }
+ default: {
+ sqlite3_result_null(context);
+ break;
+ }
+ }
+}
+
+/*
+** Implementation of the abs() function
+*/
+static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ assert( argc==1 );
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_INTEGER: {
+ i64 iVal = sqlite3_value_int64(argv[0]);
+ if( iVal<0 ) iVal = iVal * -1;
+ sqlite3_result_int64(context, iVal);
+ break;
+ }
+ case SQLITE_NULL: {
+ sqlite3_result_null(context);
+ break;
+ }
+ default: {
+ double rVal = sqlite3_value_double(argv[0]);
+ if( rVal<0 ) rVal = rVal * -1.0;
+ sqlite3_result_double(context, rVal);
+ break;
+ }
+ }
+}
+
+/*
+** Implementation of the substr() function
+*/
+static void substrFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *z;
+ const char *z2;
+ int i;
+ int p1, p2, len;
+
+ assert( argc==3 );
+ z = sqlite3_value_text(argv[0]);
+ if( z==0 ) return;
+ p1 = sqlite3_value_int(argv[1]);
+ p2 = sqlite3_value_int(argv[2]);
+ for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; }
+ if( p1<0 ){
+ p1 += len;
+ if( p1<0 ){
+ p2 += p1;
+ p1 = 0;
+ }
+ }else if( p1>0 ){
+ p1--;
+ }
+ if( p1+p2>len ){
+ p2 = len-p1;
+ }
+ for(i=0; i<p1 && z[i]; i++){
+ if( (z[i]&0xc0)==0x80 ) p1++;
+ }
+ while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p1++; }
+ for(; i<p1+p2 && z[i]; i++){
+ if( (z[i]&0xc0)==0x80 ) p2++;
+ }
+ while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
+ if( p2<0 ) p2 = 0;
+ sqlite3_result_text(context, &z[p1], p2, SQLITE_TRANSIENT);
+}
+
+/*
+** Implementation of the round() function
+*/
+static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ int n = 0;
+ double r;
+ char zBuf[100];
+ assert( argc==1 || argc==2 );
+ if( argc==2 ){
+ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
+ n = sqlite3_value_int(argv[1]);
+ if( n>30 ) n = 30;
+ if( n<0 ) n = 0;
+ }
+ if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
+ r = sqlite3_value_double(argv[0]);
+ sprintf(zBuf,"%.*f",n,r);
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+}
+
+/*
+** Implementation of the upper() and lower() SQL functions.
+*/
+static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ unsigned char *z;
+ int i;
+ if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
+ z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
+ if( z==0 ) return;
+ strcpy(z, sqlite3_value_text(argv[0]));
+ for(i=0; z[i]; i++){
+ z[i] = toupper(z[i]);
+ }
+ sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+ sqliteFree(z);
+}
+static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ unsigned char *z;
+ int i;
+ if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
+ z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
+ if( z==0 ) return;
+ strcpy(z, sqlite3_value_text(argv[0]));
+ for(i=0; z[i]; i++){
+ z[i] = tolower(z[i]);
+ }
+ sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+ sqliteFree(z);
+}
+
+/*
+** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
+** All three do the same thing. They return the first non-NULL
+** argument.
+*/
+static void ifnullFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ for(i=0; i<argc; i++){
+ if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
+ sqlite3_result_value(context, argv[i]);
+ break;
+ }
+ }
+}
+
+/*
+** Implementation of random(). Return a random integer.
+*/
+static void randomFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int r;
+ sqlite3Randomness(sizeof(r), &r);
+ sqlite3_result_int(context, r);
+}
+
+/*
+** Implementation of the last_insert_rowid() SQL function. The return
+** value is the same as the sqlite3_last_insert_rowid() API function.
+*/
+static void last_insert_rowid(
+ sqlite3_context *context,
+ int arg,
+ sqlite3_value **argv
+){
+ sqlite3 *db = sqlite3_user_data(context);
+ sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
+}
+
+/*
+** Implementation of the changes() SQL function. The return value is the
+** same as the sqlite3_changes() API function.
+*/
+static void changes(
+ sqlite3_context *context,
+ int arg,
+ sqlite3_value **argv
+){
+ sqlite3 *db = sqlite3_user_data(context);
+ sqlite3_result_int(context, sqlite3_changes(db));
+}
+
+/*
+** Implementation of the total_changes() SQL function. The return value is
+** the same as the sqlite3_total_changes() API function.
+*/
+static void total_changes(
+ sqlite3_context *context,
+ int arg,
+ sqlite3_value **argv
+){
+ sqlite3 *db = sqlite3_user_data(context);
+ sqlite3_result_int(context, sqlite3_total_changes(db));
+}
+
+/*
+** A structure defining how to do GLOB-style comparisons.
+*/
+struct compareInfo {
+ u8 matchAll;
+ u8 matchOne;
+ u8 matchSet;
+ u8 noCase;
+};
+static const struct compareInfo globInfo = { '*', '?', '[', 0 };
+static const struct compareInfo likeInfo = { '%', '_', 0, 1 };
+
+/*
+** X is a pointer to the first byte of a UTF-8 character. Increment
+** X so that it points to the next character. This only works right
+** if X points to a well-formed UTF-8 string.
+*/
+#define sqliteNextChar(X) while( (0xc0&*++(X))==0x80 ){}
+#define sqliteCharVal(X) sqlite3ReadUtf8(X)
+
+
+/*
+** Compare two UTF-8 strings for equality where the first string can
+** potentially be a "glob" expression. Return true (1) if they
+** are the same and false (0) if they are different.
+**
+** Globbing rules:
+**
+** '*' Matches any sequence of zero or more characters.
+**
+** '?' Matches exactly one character.
+**
+** [...] Matches one character from the enclosed list of
+** characters.
+**
+** [^...] Matches one character not in the enclosed list.
+**
+** With the [...] and [^...] matching, a ']' character can be included
+** in the list by making it the first character after '[' or '^'. A
+** range of characters can be specified using '-'. Example:
+** "[a-z]" matches any single lower-case letter. To match a '-', make
+** it the last character in the list.
+**
+** This routine is usually quick, but can be N**2 in the worst case.
+**
+** Hints: to match '*' or '?', put them in "[]". Like this:
+**
+** abc[*]xyz Matches "abc*xyz" only
+*/
+static int patternCompare(
+ const u8 *zPattern, /* The glob pattern */
+ const u8 *zString, /* The string to compare against the glob */
+ const struct compareInfo *pInfo, /* Information about how to do the compare */
+ const int esc /* The escape character */
+){
+ register int c;
+ int invert;
+ int seen;
+ int c2;
+ u8 matchOne = pInfo->matchOne;
+ u8 matchAll = pInfo->matchAll;
+ u8 matchSet = pInfo->matchSet;
+ u8 noCase = pInfo->noCase;
+ int prevEscape = 0; /* True if the previous character was 'escape' */
+
+ while( (c = *zPattern)!=0 ){
+ if( !prevEscape && c==matchAll ){
+ while( (c=zPattern[1]) == matchAll || c == matchOne ){
+ if( c==matchOne ){
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ }
+ zPattern++;
+ }
+ if( c && esc && sqlite3ReadUtf8(&zPattern[1])==esc ){
+ u8 const *zTemp = &zPattern[1];
+ sqliteNextChar(zTemp);
+ c = *zTemp;
+ }
+ if( c==0 ) return 1;
+ if( c==matchSet ){
+ assert( esc==0 ); /* This is GLOB, not LIKE */
+ while( *zString && patternCompare(&zPattern[1],zString,pInfo,esc)==0 ){
+ sqliteNextChar(zString);
+ }
+ return *zString!=0;
+ }else{
+ while( (c2 = *zString)!=0 ){
+ if( noCase ){
+ c2 = sqlite3UpperToLower[c2];
+ c = sqlite3UpperToLower[c];
+ while( c2 != 0 && c2 != c ){ c2 = sqlite3UpperToLower[*++zString]; }
+ }else{
+ while( c2 != 0 && c2 != c ){ c2 = *++zString; }
+ }
+ if( c2==0 ) return 0;
+ if( patternCompare(&zPattern[1],zString,pInfo,esc) ) return 1;
+ sqliteNextChar(zString);
+ }
+ return 0;
+ }
+ }else if( !prevEscape && c==matchOne ){
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ zPattern++;
+ }else if( c==matchSet ){
+ int prior_c = 0;
+ assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
+ seen = 0;
+ invert = 0;
+ c = sqliteCharVal(zString);
+ if( c==0 ) return 0;
+ c2 = *++zPattern;
+ if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
+ if( c2==']' ){
+ if( c==']' ) seen = 1;
+ c2 = *++zPattern;
+ }
+ while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
+ if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
+ zPattern++;
+ c2 = sqliteCharVal(zPattern);
+ if( c>=prior_c && c<=c2 ) seen = 1;
+ prior_c = 0;
+ }else if( c==c2 ){
+ seen = 1;
+ prior_c = c2;
+ }else{
+ prior_c = c2;
+ }
+ sqliteNextChar(zPattern);
+ }
+ if( c2==0 || (seen ^ invert)==0 ) return 0;
+ sqliteNextChar(zString);
+ zPattern++;
+ }else if( esc && !prevEscape && sqlite3ReadUtf8(zPattern)==esc){
+ prevEscape = 1;
+ sqliteNextChar(zPattern);
+ }else{
+ if( noCase ){
+ if( sqlite3UpperToLower[c] != sqlite3UpperToLower[*zString] ) return 0;
+ }else{
+ if( c != *zString ) return 0;
+ }
+ zPattern++;
+ zString++;
+ prevEscape = 0;
+ }
+ }
+ return *zString==0;
+}
+
+
+/*
+** Implementation of the like() SQL function. This function implements
+** the build-in LIKE operator. The first argument to the function is the
+** pattern and the second argument is the string. So, the SQL statements:
+**
+** A LIKE B
+**
+** 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.
+*/
+static void likeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zA = sqlite3_value_text(argv[0]);
+ const unsigned char *zB = sqlite3_value_text(argv[1]);
+ int escape = 0;
+ if( argc==3 ){
+ /* The escape character string must consist of a single UTF-8 character.
+ ** Otherwise, return an error.
+ */
+ const unsigned char *zEsc = sqlite3_value_text(argv[2]);
+ if( sqlite3utf8CharLen(zEsc, -1)!=1 ){
+ sqlite3_result_error(context,
+ "ESCAPE expression must be a single character", -1);
+ return;
+ }
+ escape = sqlite3ReadUtf8(zEsc);
+ }
+ if( zA && zB ){
+ sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo, 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));
+ }
+}
+
+/*
+** Implementation of the NULLIF(x,y) function. The result is the first
+** argument if the arguments are different. The result is NULL if the
+** arguments are equal to each other.
+*/
+static void nullifFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ CollSeq *pColl = sqlite3GetFuncCollSeq(context);
+ if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
+ sqlite3_result_value(context, argv[0]);
+ }
+}
+
+/*
+** Implementation of the VERSION(*) function. The result is the version
+** of the SQLite library that is running.
+*/
+static void versionFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
+}
+
+
+/*
+** EXPERIMENTAL - This is not an official function. The interface may
+** change. This function may disappear. Do not write code that depends
+** on this function.
+**
+** Implementation of the QUOTE() function. This function takes a single
+** argument. If the argument is numeric, the return value is the same as
+** the argument. If the argument is NULL, the return value is the string
+** "NULL". Otherwise, the argument is enclosed in single quotes with
+** single-quote escapes.
+*/
+static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ if( argc<1 ) return;
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE_NULL: {
+ sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
+ break;
+ }
+ case SQLITE_INTEGER:
+ case SQLITE_FLOAT: {
+ sqlite3_result_value(context, argv[0]);
+ break;
+ }
+ case SQLITE_BLOB: {
+ static const char hexdigits[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+ char *zText = 0;
+ int nBlob = sqlite3_value_bytes(argv[0]);
+ char const *zBlob = sqlite3_value_blob(argv[0]);
+
+ zText = (char *)sqliteMalloc((2*nBlob)+4);
+ if( !zText ){
+ sqlite3_result_error(context, "out of memory", -1);
+ }else{
+ int i;
+ for(i=0; i<nBlob; i++){
+ zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
+ zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
+ }
+ zText[(nBlob*2)+2] = '\'';
+ zText[(nBlob*2)+3] = '\0';
+ zText[0] = 'X';
+ zText[1] = '\'';
+ sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
+ sqliteFree(zText);
+ }
+ break;
+ }
+ case SQLITE_TEXT: {
+ int i,j,n;
+ const char *zArg = sqlite3_value_text(argv[0]);
+ char *z;
+
+ for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
+ z = sqliteMalloc( i+n+3 );
+ if( z==0 ) return;
+ z[0] = '\'';
+ for(i=0, j=1; zArg[i]; i++){
+ z[j++] = zArg[i];
+ if( zArg[i]=='\'' ){
+ z[j++] = '\'';
+ }
+ }
+ z[j++] = '\'';
+ z[j] = 0;
+ sqlite3_result_text(context, z, j, SQLITE_TRANSIENT);
+ sqliteFree(z);
+ }
+ }
+}
+
+#ifdef SQLITE_SOUNDEX
+/*
+** Compute the soundex encoding of a word.
+*/
+static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
+ char zResult[8];
+ const u8 *zIn;
+ int i, j;
+ static const unsigned char iCode[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
+ 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
+ 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
+ };
+ assert( argc==1 );
+ zIn = (u8*)sqlite3_value_text(argv[0]);
+ for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
+ if( zIn[i] ){
+ zResult[0] = toupper(zIn[i]);
+ for(j=1; j<4 && zIn[i]; i++){
+ int code = iCode[zIn[i]&0x7f];
+ if( code>0 ){
+ zResult[j++] = code + '0';
+ }
+ }
+ while( j<4 ){
+ zResult[j++] = '0';
+ }
+ zResult[j] = 0;
+ sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
+ }
+}
+#endif
+
+#ifdef SQLITE_TEST
+/*
+** This function generates a string of random characters. Used for
+** generating test data.
+*/
+static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
+ static const unsigned char zSrc[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ ".-!,:*^+=_|?/<> ";
+ int iMin, iMax, n, r, i;
+ unsigned char zBuf[1000];
+ if( argc>=1 ){
+ iMin = sqlite3_value_int(argv[0]);
+ if( iMin<0 ) iMin = 0;
+ if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
+ }else{
+ iMin = 1;
+ }
+ if( argc>=2 ){
+ iMax = sqlite3_value_int(argv[1]);
+ if( iMax<iMin ) iMax = iMin;
+ if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
+ }else{
+ iMax = 50;
+ }
+ n = iMin;
+ if( iMax>iMin ){
+ sqlite3Randomness(sizeof(r), &r);
+ r &= 0x7fffffff;
+ n += r%(iMax + 1 - iMin);
+ }
+ assert( n<sizeof(zBuf) );
+ sqlite3Randomness(n, zBuf);
+ for(i=0; i<n; i++){
+ zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
+ }
+ zBuf[n] = 0;
+ sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
+}
+#endif /* SQLITE_TEST */
+
+#ifdef SQLITE_TEST
+/*
+** The following two SQL functions are used to test returning a text
+** result with a destructor. Function 'test_destructor' takes one argument
+** and returns the same argument interpreted as TEXT. A destructor is
+** passed with the sqlite3_result_text() call.
+**
+** SQL function 'test_destructor_count' returns the number of outstanding
+** allocations made by 'test_destructor';
+**
+** WARNING: Not threadsafe.
+*/
+static int test_destructor_count_var = 0;
+static void destructor(void *p){
+ char *zVal = (char *)p;
+ assert(zVal);
+ zVal--;
+ sqliteFree(zVal);
+ test_destructor_count_var--;
+}
+static void test_destructor(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **argv
+){
+ char *zVal;
+ int len;
+ sqlite3 *db = sqlite3_user_data(pCtx);
+
+ test_destructor_count_var++;
+ assert( nArg==1 );
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ len = sqlite3ValueBytes(argv[0], db->enc);
+ zVal = sqliteMalloc(len+3);
+ zVal[len] = 0;
+ zVal[len-1] = 0;
+ assert( zVal );
+ zVal++;
+ memcpy(zVal, sqlite3ValueText(argv[0], db->enc), len);
+ if( db->enc==SQLITE_UTF8 ){
+ sqlite3_result_text(pCtx, zVal, -1, destructor);
+#ifndef SQLITE_OMIT_UTF16
+ }else if( db->enc==SQLITE_UTF16LE ){
+ sqlite3_result_text16le(pCtx, zVal, -1, destructor);
+ }else{
+ sqlite3_result_text16be(pCtx, zVal, -1, destructor);
+#endif /* SQLITE_OMIT_UTF16 */
+ }
+}
+static void test_destructor_count(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **argv
+){
+ sqlite3_result_int(pCtx, test_destructor_count_var);
+}
+#endif /* SQLITE_TEST */
+
+#ifdef SQLITE_TEST
+/*
+** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata()
+** interface.
+**
+** The test_auxdata() SQL function attempts to register each of its arguments
+** as auxiliary data. If there are no prior registrations of aux data for
+** that argument (meaning the argument is not a constant or this is its first
+** call) then the result for that argument is 0. If there is a prior
+** registration, the result for that argument is 1. The overall result
+** is the individual argument results separated by spaces.
+*/
+static void free_test_auxdata(void *p) {sqliteFree(p);}
+static void test_auxdata(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **argv
+){
+ int i;
+ char *zRet = sqliteMalloc(nArg*2);
+ if( !zRet ) return;
+ for(i=0; i<nArg; i++){
+ char const *z = sqlite3_value_text(argv[i]);
+ if( z ){
+ char *zAux = sqlite3_get_auxdata(pCtx, i);
+ if( zAux ){
+ zRet[i*2] = '1';
+ if( strcmp(zAux, z) ){
+ sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
+ return;
+ }
+ }else{
+ zRet[i*2] = '0';
+ zAux = sqliteStrDup(z);
+ sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
+ }
+ zRet[i*2+1] = ' ';
+ }
+ }
+ sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
+}
+#endif /* SQLITE_TEST */
+
+#ifdef SQLITE_TEST
+/*
+** A function to test error reporting from user functions. This function
+** returns a copy of it's first argument as an error.
+*/
+static void test_error(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **argv
+){
+ sqlite3_result_error(pCtx, sqlite3_value_text(argv[0]), 0);
+}
+#endif /* SQLITE_TEST */
+
+/*
+** An instance of the following structure holds the context of a
+** sum() or avg() aggregate computation.
+*/
+typedef struct SumCtx SumCtx;
+struct SumCtx {
+ double sum; /* Sum of terms */
+ int cnt; /* Number of elements summed */
+};
+
+/*
+** Routines used to compute the sum or average.
+*/
+static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
+ SumCtx *p;
+ if( argc<1 ) return;
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ if( p && SQLITE_NULL!=sqlite3_value_type(argv[0]) ){
+ p->sum += sqlite3_value_double(argv[0]);
+ p->cnt++;
+ }
+}
+static void sumFinalize(sqlite3_context *context){
+ SumCtx *p;
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ sqlite3_result_double(context, p ? p->sum : 0.0);
+}
+static void avgFinalize(sqlite3_context *context){
+ SumCtx *p;
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ if( p && p->cnt>0 ){
+ sqlite3_result_double(context, p->sum/(double)p->cnt);
+ }
+}
+
+/*
+** An instance of the following structure holds the context of a
+** variance or standard deviation computation.
+*/
+typedef struct StdDevCtx StdDevCtx;
+struct StdDevCtx {
+ double sum; /* Sum of terms */
+ double sum2; /* Sum of the squares of terms */
+ int cnt; /* Number of terms counted */
+};
+
+/*
+** The following structure keeps track of state information for the
+** count() aggregate function.
+*/
+typedef struct CountCtx CountCtx;
+struct CountCtx {
+ int n;
+};
+
+/*
+** Routines to implement the count() aggregate function.
+*/
+static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
+ CountCtx *p;
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
+ p->n++;
+ }
+}
+static void countFinalize(sqlite3_context *context){
+ CountCtx *p;
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ 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.
+*/
+static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){
+ Mem *pArg = (Mem *)argv[0];
+ Mem *pBest;
+
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
+ if( !pBest ) return;
+
+ if( pBest->flags ){
+ int max;
+ int cmp;
+ CollSeq *pColl = sqlite3GetFuncCollSeq(context);
+ /* This step function is used for both the min() and max() aggregates,
+ ** the only difference between the two being that the sense of the
+ ** comparison is inverted. For the max() aggregate, the
+ ** sqlite3_user_data() function returns (void *)-1. For min() it
+ ** returns (void *)db, where db is the sqlite3* database pointer.
+ ** Therefore the next statement sets variable 'max' to 1 for the max()
+ ** aggregate, or 0 for min().
+ */
+ max = ((sqlite3_user_data(context)==(void *)-1)?1:0);
+ cmp = sqlite3MemCompare(pBest, pArg, pColl);
+ if( (max && cmp<0) || (!max && cmp>0) ){
+ sqlite3VdbeMemCopy(pBest, pArg);
+ }
+ }else{
+ sqlite3VdbeMemCopy(pBest, pArg);
+ }
+}
+static void minMaxFinalize(sqlite3_context *context){
+ sqlite3_value *pRes;
+ pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem));
+ if( pRes->flags ){
+ sqlite3_result_value(context, pRes);
+ }
+ sqlite3VdbeMemRelease(pRes);
+}
+
+
+/*
+** This function registered all of the above C functions as SQL
+** functions. This should be the only routine in this file with
+** external linkage.
+*/
+void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
+ static const struct {
+ char *zName;
+ signed char nArg;
+ u8 argType; /* 0: none. 1: db 2: (-1) */
+ u8 eTextRep; /* 1: UTF-16. 0: UTF-8 */
+ u8 needCollSeq;
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
+ } aFuncs[] = {
+ { "min", -1, 0, SQLITE_UTF8, 1, minmaxFunc },
+ { "min", 0, 0, SQLITE_UTF8, 1, 0 },
+ { "max", -1, 2, SQLITE_UTF8, 1, minmaxFunc },
+ { "max", 0, 2, SQLITE_UTF8, 1, 0 },
+ { "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc },
+ { "length", 1, 0, SQLITE_UTF8, 0, lengthFunc },
+ { "substr", 3, 0, SQLITE_UTF8, 0, substrFunc },
+#ifndef SQLITE_OMIT_UTF16
+ { "substr", 3, 0, SQLITE_UTF16LE, 0, sqlite3utf16Substr },
+#endif
+ { "abs", 1, 0, SQLITE_UTF8, 0, absFunc },
+ { "round", 1, 0, SQLITE_UTF8, 0, roundFunc },
+ { "round", 2, 0, SQLITE_UTF8, 0, roundFunc },
+ { "upper", 1, 0, SQLITE_UTF8, 0, upperFunc },
+ { "lower", 1, 0, SQLITE_UTF8, 0, lowerFunc },
+ { "coalesce", -1, 0, SQLITE_UTF8, 0, ifnullFunc },
+ { "coalesce", 0, 0, SQLITE_UTF8, 0, 0 },
+ { "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 },
+ { "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid },
+ { "changes", 0, 1, SQLITE_UTF8, 0, changes },
+ { "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes },
+#ifdef SQLITE_SOUNDEX
+ { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
+#endif
+#ifdef SQLITE_TEST
+ { "randstr", 2, 0, SQLITE_UTF8, 0, randStr },
+ { "test_destructor", 1, 1, SQLITE_UTF8, 0, test_destructor},
+ { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
+ { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata},
+ { "test_error", 1, 0, SQLITE_UTF8, 0, test_error},
+#endif
+ };
+ static const struct {
+ char *zName;
+ signed char nArg;
+ u8 argType;
+ u8 needCollSeq;
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**);
+ void (*xFinalize)(sqlite3_context*);
+ } aAggs[] = {
+ { "min", 1, 0, 1, minmaxStep, minMaxFinalize },
+ { "max", 1, 2, 1, minmaxStep, minMaxFinalize },
+ { "sum", 1, 0, 0, sumStep, sumFinalize },
+ { "avg", 1, 0, 0, sumStep, avgFinalize },
+ { "count", 0, 0, 0, countStep, countFinalize },
+ { "count", 1, 0, 0, countStep, countFinalize },
+ };
+ int i;
+
+ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
+ void *pArg = 0;
+ switch( aFuncs[i].argType ){
+ case 1: pArg = db; break;
+ case 2: pArg = (void *)(-1); break;
+ }
+ sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
+ aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
+ if( aFuncs[i].needCollSeq ){
+ FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName,
+ strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0);
+ if( pFunc && aFuncs[i].needCollSeq ){
+ pFunc->needCollSeq = 1;
+ }
+ }
+ }
+#ifndef SQLITE_OMIT_ALTERTABLE
+ sqlite3AlterFunctions(db);
+#endif
+ for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
+ void *pArg = 0;
+ switch( aAggs[i].argType ){
+ case 1: pArg = db; break;
+ case 2: pArg = (void *)(-1); break;
+ }
+ sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8,
+ pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
+ if( aAggs[i].needCollSeq ){
+ FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
+ strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
+ if( pFunc && aAggs[i].needCollSeq ){
+ pFunc->needCollSeq = 1;
+ }
+ }
+ }
+ sqlite3RegisterDateTimeFunctions(db);
+#ifdef SQLITE_SSE
+ {
+ sqlite3SseFunctions(db);
+ }
+#endif
+}
diff --git a/src/sqlite/hash.c b/src/sqlite/hash.c
new file mode 100644
index 0000000..5d29f57
--- /dev/null
+++ b/src/sqlite/hash.c
@@ -0,0 +1,387 @@
+/*
+** 2001 September 22
+**
+** 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 is the implementation of generic hash-tables
+** used in SQLite.
+**
+** $Id: hash.c,v 1.1.1.1 2006/02/03 20:35:12 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include <assert.h>
+
+/* Turn bulk memory into a hash table object by initializing the
+** fields of the Hash structure.
+**
+** "pNew" is a pointer to the hash table that is to be initialized.
+** keyClass is one of the constants SQLITE_HASH_INT, SQLITE_HASH_POINTER,
+** SQLITE_HASH_BINARY, or SQLITE_HASH_STRING. The value of keyClass
+** determines what kind of key the hash table will use. "copyKey" is
+** true if the hash table should make its own private copy of keys and
+** false if it should just use the supplied pointer. CopyKey only makes
+** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored
+** for other key classes.
+*/
+void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){
+ assert( pNew!=0 );
+ assert( keyClass>=SQLITE_HASH_STRING && keyClass<=SQLITE_HASH_BINARY );
+ pNew->keyClass = keyClass;
+#if 0
+ if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0;
+#endif
+ pNew->copyKey = copyKey;
+ pNew->first = 0;
+ pNew->count = 0;
+ pNew->htsize = 0;
+ pNew->ht = 0;
+}
+
+/* Remove all entries from a hash table. Reclaim all memory.
+** Call this routine to delete a hash table or to reset a hash table
+** to the empty state.
+*/
+void sqlite3HashClear(Hash *pH){
+ HashElem *elem; /* For looping over all elements of the table */
+
+ assert( pH!=0 );
+ elem = pH->first;
+ pH->first = 0;
+ if( pH->ht ) sqliteFree(pH->ht);
+ pH->ht = 0;
+ pH->htsize = 0;
+ while( elem ){
+ HashElem *next_elem = elem->next;
+ if( pH->copyKey && elem->pKey ){
+ sqliteFree(elem->pKey);
+ }
+ sqliteFree(elem);
+ elem = next_elem;
+ }
+ pH->count = 0;
+}
+
+#if 0 /* NOT USED */
+/*
+** Hash and comparison functions when the mode is SQLITE_HASH_INT
+*/
+static int intHash(const void *pKey, int nKey){
+ return nKey ^ (nKey<<8) ^ (nKey>>8);
+}
+static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ return n2 - n1;
+}
+#endif
+
+#if 0 /* NOT USED */
+/*
+** Hash and comparison functions when the mode is SQLITE_HASH_POINTER
+*/
+static int ptrHash(const void *pKey, int nKey){
+ uptr x = Addr(pKey);
+ return x ^ (x<<8) ^ (x>>8);
+}
+static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ if( pKey1==pKey2 ) return 0;
+ if( pKey1<pKey2 ) return -1;
+ return 1;
+}
+#endif
+
+/*
+** Hash and comparison functions when the mode is SQLITE_HASH_STRING
+*/
+static int strHash(const void *pKey, int nKey){
+ const char *z = (const char *)pKey;
+ int h = 0;
+ if( nKey<=0 ) nKey = strlen(z);
+ while( nKey > 0 ){
+ h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
+ nKey--;
+ }
+ return h & 0x7fffffff;
+}
+static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ if( n1!=n2 ) return 1;
+ return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1);
+}
+
+/*
+** Hash and comparison functions when the mode is SQLITE_HASH_BINARY
+*/
+static int binHash(const void *pKey, int nKey){
+ int h = 0;
+ const char *z = (const char *)pKey;
+ while( nKey-- > 0 ){
+ h = (h<<3) ^ h ^ *(z++);
+ }
+ return h & 0x7fffffff;
+}
+static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ if( n1!=n2 ) return 1;
+ return memcmp(pKey1,pKey2,n1);
+}
+
+/*
+** Return a pointer to the appropriate hash function given the key class.
+**
+** The C syntax in this function definition may be unfamilar to some
+** programmers, so we provide the following additional explanation:
+**
+** The name of the function is "hashFunction". The function takes a
+** single parameter "keyClass". The return value of hashFunction()
+** is a pointer to another function. Specifically, the return value
+** of hashFunction() is a pointer to a function that takes two parameters
+** with types "const void*" and "int" and returns an "int".
+*/
+static int (*hashFunction(int keyClass))(const void*,int){
+#if 0 /* HASH_INT and HASH_POINTER are never used */
+ switch( keyClass ){
+ case SQLITE_HASH_INT: return &intHash;
+ case SQLITE_HASH_POINTER: return &ptrHash;
+ case SQLITE_HASH_STRING: return &strHash;
+ case SQLITE_HASH_BINARY: return &binHash;;
+ default: break;
+ }
+ return 0;
+#else
+ if( keyClass==SQLITE_HASH_STRING ){
+ return &strHash;
+ }else{
+ assert( keyClass==SQLITE_HASH_BINARY );
+ return &binHash;
+ }
+#endif
+}
+
+/*
+** Return a pointer to the appropriate hash function given the key class.
+**
+** For help in interpreted the obscure C code in the function definition,
+** see the header comment on the previous function.
+*/
+static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
+#if 0 /* HASH_INT and HASH_POINTER are never used */
+ switch( keyClass ){
+ case SQLITE_HASH_INT: return &intCompare;
+ case SQLITE_HASH_POINTER: return &ptrCompare;
+ case SQLITE_HASH_STRING: return &strCompare;
+ case SQLITE_HASH_BINARY: return &binCompare;
+ default: break;
+ }
+ return 0;
+#else
+ if( keyClass==SQLITE_HASH_STRING ){
+ return &strCompare;
+ }else{
+ assert( keyClass==SQLITE_HASH_BINARY );
+ return &binCompare;
+ }
+#endif
+}
+
+/* Link an element into the hash table
+*/
+static void insertElement(
+ Hash *pH, /* The complete hash table */
+ struct _ht *pEntry, /* The entry into which pNew is inserted */
+ HashElem *pNew /* The element to be inserted */
+){
+ HashElem *pHead; /* First element already in pEntry */
+ pHead = pEntry->chain;
+ if( pHead ){
+ pNew->next = pHead;
+ pNew->prev = pHead->prev;
+ if( pHead->prev ){ pHead->prev->next = pNew; }
+ else { pH->first = pNew; }
+ pHead->prev = pNew;
+ }else{
+ pNew->next = pH->first;
+ if( pH->first ){ pH->first->prev = pNew; }
+ pNew->prev = 0;
+ pH->first = pNew;
+ }
+ pEntry->count++;
+ pEntry->chain = pNew;
+}
+
+
+/* Resize the hash table so that it cantains "new_size" buckets.
+** "new_size" must be a power of 2. The hash table might fail
+** to resize if sqliteMalloc() fails.
+*/
+static void rehash(Hash *pH, int new_size){
+ struct _ht *new_ht; /* The new hash table */
+ HashElem *elem, *next_elem; /* For looping over existing elements */
+ int (*xHash)(const void*,int); /* The hash function */
+
+ assert( (new_size & (new_size-1))==0 );
+ new_ht = (struct _ht *)sqliteMalloc( new_size*sizeof(struct _ht) );
+ if( new_ht==0 ) return;
+ if( pH->ht ) sqliteFree(pH->ht);
+ pH->ht = new_ht;
+ pH->htsize = new_size;
+ xHash = hashFunction(pH->keyClass);
+ for(elem=pH->first, pH->first=0; elem; elem = next_elem){
+ int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
+ next_elem = elem->next;
+ insertElement(pH, &new_ht[h], elem);
+ }
+}
+
+/* This function (for internal use only) locates an element in an
+** hash table that matches the given key. The hash for this key has
+** already been computed and is passed as the 4th parameter.
+*/
+static HashElem *findElementGivenHash(
+ const Hash *pH, /* The pH to be searched */
+ const void *pKey, /* The key we are searching for */
+ int nKey,
+ int h /* The hash for this key. */
+){
+ HashElem *elem; /* Used to loop thru the element list */
+ int count; /* Number of elements left to test */
+ int (*xCompare)(const void*,int,const void*,int); /* comparison function */
+
+ if( pH->ht ){
+ struct _ht *pEntry = &pH->ht[h];
+ elem = pEntry->chain;
+ count = pEntry->count;
+ xCompare = compareFunction(pH->keyClass);
+ while( count-- && elem ){
+ if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){
+ return elem;
+ }
+ elem = elem->next;
+ }
+ }
+ return 0;
+}
+
+/* Remove a single entry from the hash table given a pointer to that
+** element and a hash on the element's key.
+*/
+static void removeElementGivenHash(
+ Hash *pH, /* The pH containing "elem" */
+ HashElem* elem, /* The element to be removed from the pH */
+ int h /* Hash value for the element */
+){
+ struct _ht *pEntry;
+ if( elem->prev ){
+ elem->prev->next = elem->next;
+ }else{
+ pH->first = elem->next;
+ }
+ if( elem->next ){
+ elem->next->prev = elem->prev;
+ }
+ pEntry = &pH->ht[h];
+ if( pEntry->chain==elem ){
+ pEntry->chain = elem->next;
+ }
+ pEntry->count--;
+ if( pEntry->count<=0 ){
+ pEntry->chain = 0;
+ }
+ if( pH->copyKey && elem->pKey ){
+ sqliteFree(elem->pKey);
+ }
+ sqliteFree( elem );
+ pH->count--;
+}
+
+/* Attempt to locate an element of the hash table pH with a key
+** that matches pKey,nKey. Return the data for this element if it is
+** found, or NULL if there is no match.
+*/
+void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
+ int h; /* A hash on key */
+ HashElem *elem; /* The element that matches key */
+ int (*xHash)(const void*,int); /* The hash function */
+
+ if( pH==0 || pH->ht==0 ) return 0;
+ xHash = hashFunction(pH->keyClass);
+ assert( xHash!=0 );
+ h = (*xHash)(pKey,nKey);
+ assert( (pH->htsize & (pH->htsize-1))==0 );
+ elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
+ return elem ? elem->data : 0;
+}
+
+/* Insert an element into the hash table pH. The key is pKey,nKey
+** and the data is "data".
+**
+** If no element exists with a matching key, then a new
+** element is created. A copy of the key is made if the copyKey
+** flag is set. NULL is returned.
+**
+** If another element already exists with the same key, then the
+** new data replaces the old data and the old data is returned.
+** The key is not copied in this instance. If a malloc fails, then
+** the new data is returned and the hash table is unchanged.
+**
+** If the "data" parameter to this function is NULL, then the
+** element corresponding to "key" is removed from the hash table.
+*/
+void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
+ int hraw; /* Raw hash value of the key */
+ int h; /* the hash of the key modulo hash table size */
+ HashElem *elem; /* Used to loop thru the element list */
+ HashElem *new_elem; /* New element added to the pH */
+ int (*xHash)(const void*,int); /* The hash function */
+
+ assert( pH!=0 );
+ xHash = hashFunction(pH->keyClass);
+ assert( xHash!=0 );
+ hraw = (*xHash)(pKey, nKey);
+ assert( (pH->htsize & (pH->htsize-1))==0 );
+ h = hraw & (pH->htsize-1);
+ elem = findElementGivenHash(pH,pKey,nKey,h);
+ if( elem ){
+ void *old_data = elem->data;
+ if( data==0 ){
+ removeElementGivenHash(pH,elem,h);
+ }else{
+ elem->data = data;
+ }
+ return old_data;
+ }
+ if( data==0 ) return 0;
+ new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
+ if( new_elem==0 ) return data;
+ if( pH->copyKey && pKey!=0 ){
+ new_elem->pKey = sqliteMallocRaw( nKey );
+ if( new_elem->pKey==0 ){
+ sqliteFree(new_elem);
+ return data;
+ }
+ memcpy((void*)new_elem->pKey, pKey, nKey);
+ }else{
+ new_elem->pKey = (void*)pKey;
+ }
+ new_elem->nKey = nKey;
+ pH->count++;
+ if( pH->htsize==0 ){
+ rehash(pH,8);
+ if( pH->htsize==0 ){
+ pH->count = 0;
+ sqliteFree(new_elem);
+ return data;
+ }
+ }
+ if( pH->count > pH->htsize ){
+ rehash(pH,pH->htsize*2);
+ }
+ assert( pH->htsize>0 );
+ assert( (pH->htsize & (pH->htsize-1))==0 );
+ h = hraw & (pH->htsize-1);
+ insertElement(pH, &pH->ht[h], new_elem);
+ new_elem->data = data;
+ return 0;
+}
diff --git a/src/sqlite/hash.h b/src/sqlite/hash.h
new file mode 100644
index 0000000..43c6b09
--- /dev/null
+++ b/src/sqlite/hash.h
@@ -0,0 +1,109 @@
+/*
+** 2001 September 22
+**
+** 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 is the header file for the generic hash-table implemenation
+** used in SQLite.
+**
+** $Id: hash.h,v 1.1.1.1 2006/02/03 20:35:12 hoganrobert Exp $
+*/
+#ifndef _SQLITE_HASH_H_
+#define _SQLITE_HASH_H_
+
+/* Forward declarations of structures. */
+typedef struct Hash Hash;
+typedef struct HashElem HashElem;
+
+/* A complete hash table is an instance of the following structure.
+** The internals of this structure are intended to be opaque -- client
+** code should not attempt to access or modify the fields of this structure
+** directly. Change this structure only by using the routines below.
+** However, many of the "procedures" and "functions" for modifying and
+** accessing this structure are really macros, so we can't really make
+** this structure opaque.
+*/
+struct Hash {
+ char keyClass; /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */
+ char copyKey; /* True if copy of key made on insert */
+ int count; /* Number of entries in this table */
+ HashElem *first; /* The first element of the array */
+ int htsize; /* Number of buckets in the hash table */
+ struct _ht { /* the hash table */
+ int count; /* Number of entries with this hash */
+ HashElem *chain; /* Pointer to first entry with this hash */
+ } *ht;
+};
+
+/* Each element in the hash table is an instance of the following
+** structure. All elements are stored on a single doubly-linked list.
+**
+** Again, this structure is intended to be opaque, but it can't really
+** be opaque because it is used by macros.
+*/
+struct HashElem {
+ HashElem *next, *prev; /* Next and previous elements in the table */
+ void *data; /* Data associated with this element */
+ void *pKey; int nKey; /* Key associated with this element */
+};
+
+/*
+** There are 4 different modes of operation for a hash table:
+**
+** SQLITE_HASH_INT nKey is used as the key and pKey is ignored.
+**
+** SQLITE_HASH_POINTER pKey is used as the key and nKey is ignored.
+**
+** SQLITE_HASH_STRING pKey points to a string that is nKey bytes long
+** (including the null-terminator, if any). Case
+** is ignored in comparisons.
+**
+** SQLITE_HASH_BINARY pKey points to binary data nKey bytes long.
+** memcmp() is used to compare keys.
+**
+** A copy of the key is made for SQLITE_HASH_STRING and SQLITE_HASH_BINARY
+** if the copyKey parameter to HashInit is 1.
+*/
+/* #define SQLITE_HASH_INT 1 // NOT USED */
+/* #define SQLITE_HASH_POINTER 2 // NOT USED */
+#define SQLITE_HASH_STRING 3
+#define SQLITE_HASH_BINARY 4
+
+/*
+** Access routines. To delete, insert a NULL pointer.
+*/
+void sqlite3HashInit(Hash*, int keytype, int copyKey);
+void *sqlite3HashInsert(Hash*, const void *pKey, int nKey, void *pData);
+void *sqlite3HashFind(const Hash*, const void *pKey, int nKey);
+void sqlite3HashClear(Hash*);
+
+/*
+** Macros for looping over all elements of a hash table. The idiom is
+** like this:
+**
+** Hash h;
+** HashElem *p;
+** ...
+** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
+** SomeStructure *pData = sqliteHashData(p);
+** // do something with pData
+** }
+*/
+#define sqliteHashFirst(H) ((H)->first)
+#define sqliteHashNext(E) ((E)->next)
+#define sqliteHashData(E) ((E)->data)
+#define sqliteHashKey(E) ((E)->pKey)
+#define sqliteHashKeysize(E) ((E)->nKey)
+
+/*
+** Number of entries in a hash table
+*/
+#define sqliteHashCount(H) ((H)->count)
+
+#endif /* _SQLITE_HASH_H_ */
diff --git a/src/sqlite/insert.c b/src/sqlite/insert.c
new file mode 100644
index 0000000..1c019e8
--- /dev/null
+++ b/src/sqlite/insert.c
@@ -0,0 +1,1111 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** to handle INSERT statements in SQLite.
+**
+** $Id: insert.c,v 1.1.1.1 2006/02/03 20:35:22 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** Set P3 of the most recently inserted opcode to a column affinity
+** string for index pIdx. A column affinity string has one character
+** for each column in the table, according to the affinity of the column:
+**
+** Character Column affinity
+** ------------------------------
+** 'n' NUMERIC
+** 'i' INTEGER
+** 't' TEXT
+** 'o' NONE
+*/
+void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
+ if( !pIdx->zColAff ){
+ /* The first time a column affinity string for a particular index is
+ ** required, it is allocated and populated here. It is then stored as
+ ** a member of the Index structure for subsequent use.
+ **
+ ** The column affinity string will eventually be deleted by
+ ** sqliteDeleteIndex() when the Index structure itself is cleaned
+ ** up.
+ */
+ int n;
+ Table *pTab = pIdx->pTable;
+ pIdx->zColAff = (char *)sqliteMalloc(pIdx->nColumn+1);
+ if( !pIdx->zColAff ){
+ return;
+ }
+ for(n=0; n<pIdx->nColumn; n++){
+ pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
+ }
+ pIdx->zColAff[pIdx->nColumn] = '\0';
+ }
+
+ sqlite3VdbeChangeP3(v, -1, pIdx->zColAff, 0);
+}
+
+/*
+** Set P3 of the most recently inserted opcode to a column affinity
+** string for table pTab. A column affinity string has one character
+** for each column indexed by the index, according to the affinity of the
+** column:
+**
+** Character Column affinity
+** ------------------------------
+** 'n' NUMERIC
+** 'i' INTEGER
+** 't' TEXT
+** 'o' NONE
+*/
+void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
+ /* The first time a column affinity string for a particular table
+ ** is required, it is allocated and populated here. It is then
+ ** stored as a member of the Table structure for subsequent use.
+ **
+ ** The column affinity string will eventually be deleted by
+ ** sqlite3DeleteTable() when the Table structure itself is cleaned up.
+ */
+ if( !pTab->zColAff ){
+ char *zColAff;
+ int i;
+
+ zColAff = (char *)sqliteMalloc(pTab->nCol+1);
+ if( !zColAff ){
+ return;
+ }
+
+ for(i=0; i<pTab->nCol; i++){
+ zColAff[i] = pTab->aCol[i].affinity;
+ }
+ zColAff[pTab->nCol] = '\0';
+
+ pTab->zColAff = zColAff;
+ }
+
+ sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0);
+}
+
+/*
+** Return non-zero if SELECT statement p opens the table with rootpage
+** iTab in database iDb. This is used to see if a statement of the form
+** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary
+** table for the results of the SELECT.
+**
+** No checking is done for sub-selects that are part of expressions.
+*/
+static int selectReadsTable(Select *p, int iDb, int iTab){
+ int i;
+ struct SrcList_item *pItem;
+ if( p->pSrc==0 ) return 0;
+ for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
+ if( pItem->pSelect ){
+ if( selectReadsTable(pItem->pSelect, iDb, iTab) ) return 1;
+ }else{
+ if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** This routine is call to handle SQL of the following forms:
+**
+** insert into TABLE (IDLIST) values(EXPRLIST)
+** insert into TABLE (IDLIST) select
+**
+** The IDLIST following the table name is always optional. If omitted,
+** then a list of all columns for the table is substituted. The IDLIST
+** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
+**
+** The pList parameter holds EXPRLIST in the first form of the INSERT
+** statement above, and pSelect is NULL. For the second form, pList is
+** NULL and pSelect is a pointer to the select statement used to generate
+** data for the insert.
+**
+** The code generated follows one of three templates. For a simple
+** select with data coming from a VALUES clause, the code executes
+** once straight down through. The template looks like this:
+**
+** open write cursor to <table> and its indices
+** puts VALUES clause expressions onto the stack
+** write the resulting record into <table>
+** cleanup
+**
+** If the statement is of the form
+**
+** INSERT INTO <table> SELECT ...
+**
+** And the SELECT clause does not read from <table> at any time, then
+** the generated code follows this template:
+**
+** goto B
+** A: setup for the SELECT
+** loop over the tables in the SELECT
+** gosub C
+** end loop
+** cleanup after the SELECT
+** goto D
+** B: open write cursor to <table> and its indices
+** goto A
+** C: insert the select result into <table>
+** return
+** D: cleanup
+**
+** The third template is used if the insert statement takes its
+** values from a SELECT but the data is being inserted into a table
+** that is also read as part of the SELECT. In the third form,
+** we have to use a intermediate table to store the results of
+** the select. The template is like this:
+**
+** goto B
+** A: setup for the SELECT
+** loop over the tables in the SELECT
+** gosub C
+** end loop
+** cleanup after the SELECT
+** goto D
+** C: insert the select result into the intermediate table
+** return
+** B: open a cursor to an intermediate table
+** goto A
+** D: open write cursor to <table> and its indices
+** loop over the intermediate table
+** transfer values form intermediate table into <table>
+** end the loop
+** cleanup
+*/
+void sqlite3Insert(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* Name of table into which we are inserting */
+ ExprList *pList, /* List of values to be inserted */
+ Select *pSelect, /* A SELECT statement to use as the data source */
+ IdList *pColumn, /* Column names corresponding to IDLIST. */
+ int onError /* How to handle constraint errors */
+){
+ Table *pTab; /* The table to insert into */
+ char *zTab; /* Name of the table into which we are inserting */
+ const char *zDb; /* Name of the database holding this table */
+ int i, j, idx; /* Loop counters */
+ Vdbe *v; /* Generate code into this virtual machine */
+ Index *pIdx; /* For looping over indices of the table */
+ int nColumn; /* Number of columns in the data */
+ int base = 0; /* VDBE Cursor number for pTab */
+ int iCont=0,iBreak=0; /* Beginning and end of the loop over srcTab */
+ sqlite3 *db; /* The main database structure */
+ int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
+ int endOfLoop; /* Label for the end of the insertion loop */
+ int useTempTable = 0; /* Store SELECT results in intermediate table */
+ int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
+ int iSelectLoop = 0; /* Address of code that implements the SELECT */
+ int iCleanup = 0; /* Address of the cleanup code */
+ int iInsertBlock = 0; /* Address of the subroutine used to insert data */
+ int iCntMem = 0; /* Memory cell used for the row counter */
+ int newIdx = -1; /* Cursor for the NEW table */
+ Db *pDb; /* The database containing table being inserted into */
+ int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */
+
+#ifndef SQLITE_OMIT_TRIGGER
+ int isView; /* True if attempting to insert into a view */
+ int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */
+#endif
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ int counterRowid; /* Memory cell holding rowid of autoinc counter */
+#endif
+
+ if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
+ db = pParse->db;
+
+ /* Locate the table into which we will be inserting new information.
+ */
+ assert( pTabList->nSrc==1 );
+ zTab = pTabList->a[0].zName;
+ if( zTab==0 ) goto insert_cleanup;
+ pTab = sqlite3SrcListLookup(pParse, pTabList);
+ if( pTab==0 ){
+ goto insert_cleanup;
+ }
+ assert( pTab->iDb<db->nDb );
+ pDb = &db->aDb[pTab->iDb];
+ zDb = pDb->zName;
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
+ goto insert_cleanup;
+ }
+
+ /* Figure out if we have any triggers and if the table being
+ ** inserted into is a view
+ */
+#ifndef SQLITE_OMIT_TRIGGER
+ triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0);
+ isView = pTab->pSelect!=0;
+#else
+# define triggers_exist 0
+# define isView 0
+#endif
+#ifdef SQLITE_OMIT_VIEW
+# undef isView
+# define isView 0
+#endif
+
+ /* Ensure that:
+ * (a) the table is not read-only,
+ * (b) that if it is a view then ON INSERT triggers exist
+ */
+ if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
+ goto insert_cleanup;
+ }
+ if( pTab==0 ) goto insert_cleanup;
+
+ /* If pTab is really a view, make sure it has been initialized.
+ */
+ if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
+ goto insert_cleanup;
+ }
+
+ /* Ensure all required collation sequences are available. */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
+ goto insert_cleanup;
+ }
+ }
+
+ /* Allocate a VDBE
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto insert_cleanup;
+ if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+ sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, pTab->iDb);
+
+ /* if there are row triggers, allocate a temp table for new.* references. */
+ if( triggers_exist ){
+ newIdx = pParse->nTab++;
+ }
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ /* If this is an AUTOINCREMENT table, look up the sequence number in the
+ ** sqlite_sequence table and store it in memory cell counterMem. Also
+ ** remember the rowid of the sqlite_sequence table entry in memory cell
+ ** counterRowid.
+ */
+ if( pTab->autoInc ){
+ int iCur = pParse->nTab;
+ int base = sqlite3VdbeCurrentAddr(v);
+ counterRowid = pParse->nMem++;
+ counterMem = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
+ sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13);
+ sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
+ sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
+ sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
+ sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, base+13);
+ sqlite3VdbeAddOp(v, OP_Next, iCur, base+4);
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+#endif /* SQLITE_OMIT_AUTOINCREMENT */
+
+ /* Figure out how many columns of data are supplied. If the data
+ ** is coming from a SELECT statement, then this step also generates
+ ** all the code to implement the SELECT statement and invoke a subroutine
+ ** to process each row of the result. (Template 2.) If the SELECT
+ ** statement uses the the table that is being inserted into, then the
+ ** subroutine is also coded here. That subroutine stores the SELECT
+ ** results in a temporary table. (Template 3.)
+ */
+ if( pSelect ){
+ /* Data is coming from a SELECT. Generate code to implement that SELECT
+ */
+ int rc, iInitCode;
+ iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
+ iSelectLoop = sqlite3VdbeCurrentAddr(v);
+ iInsertBlock = sqlite3VdbeMakeLabel(v);
+
+ /* Resolve the expressions in the SELECT statement and execute it. */
+ rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
+ if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
+
+ iCleanup = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
+ assert( pSelect->pEList );
+ nColumn = pSelect->pEList->nExpr;
+
+ /* Set useTempTable to TRUE if the result of the SELECT statement
+ ** should be written into a temporary table. Set to FALSE if each
+ ** row of the SELECT can be written directly into the result table.
+ **
+ ** A temp table must be used if the table being updated is also one
+ ** of the tables being read by the SELECT statement. Also use a
+ ** temp table in the case of row triggers.
+ */
+ if( triggers_exist || selectReadsTable(pSelect, pTab->iDb, pTab->tnum) ){
+ useTempTable = 1;
+ }
+
+ if( useTempTable ){
+ /* Generate the subroutine that SELECT calls to process each row of
+ ** the result. Store the result in a temporary table
+ */
+ srcTab = pParse->nTab++;
+ sqlite3VdbeResolveLabel(v, iInsertBlock);
+ sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ sqlite3TableAffinityStr(v, pTab);
+ sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
+ sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
+ sqlite3VdbeAddOp(v, OP_Return, 0, 0);
+
+ /* The following code runs first because the GOTO at the very top
+ ** of the program jumps to it. Create the temporary table, then jump
+ ** back up and execute the SELECT code above.
+ */
+ sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
+ sqlite3VdbeAddOp(v, OP_OpenTemp, srcTab, 0);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
+ sqlite3VdbeResolveLabel(v, iCleanup);
+ }else{
+ sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
+ }
+ }else{
+ /* This is the case if the data for the INSERT is coming from a VALUES
+ ** clause
+ */
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ assert( pList!=0 );
+ srcTab = -1;
+ useTempTable = 0;
+ assert( pList );
+ nColumn = pList->nExpr;
+ for(i=0; i<nColumn; i++){
+ if( sqlite3ExprResolveNames(&sNC, pList->a[i].pExpr) ){
+ goto insert_cleanup;
+ }
+ }
+ }
+
+ /* Make sure the number of columns in the source data matches the number
+ ** of columns to be inserted into the table.
+ */
+ if( pColumn==0 && nColumn!=pTab->nCol ){
+ sqlite3ErrorMsg(pParse,
+ "table %S has %d columns but %d values were supplied",
+ pTabList, 0, pTab->nCol, nColumn);
+ goto insert_cleanup;
+ }
+ if( pColumn!=0 && nColumn!=pColumn->nId ){
+ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
+ goto insert_cleanup;
+ }
+
+ /* If the INSERT statement included an IDLIST term, then make sure
+ ** all elements of the IDLIST really are columns of the table and
+ ** remember the column indices.
+ **
+ ** If the table has an INTEGER PRIMARY KEY column and that column
+ ** is named in the IDLIST, then record in the keyColumn variable
+ ** the index into IDLIST of the primary key column. keyColumn is
+ ** the index of the primary key as it appears in IDLIST, not as
+ ** is appears in the original table. (The index of the primary
+ ** key in the original table is pTab->iPKey.)
+ */
+ if( pColumn ){
+ for(i=0; i<pColumn->nId; i++){
+ pColumn->a[i].idx = -1;
+ }
+ for(i=0; i<pColumn->nId; i++){
+ for(j=0; j<pTab->nCol; j++){
+ if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
+ pColumn->a[i].idx = j;
+ if( j==pTab->iPKey ){
+ keyColumn = i;
+ }
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( sqlite3IsRowid(pColumn->a[i].zName) ){
+ keyColumn = i;
+ }else{
+ sqlite3ErrorMsg(pParse, "table %S has no column named %s",
+ pTabList, 0, pColumn->a[i].zName);
+ pParse->nErr++;
+ goto insert_cleanup;
+ }
+ }
+ }
+ }
+
+ /* If there is no IDLIST term but the table has an integer primary
+ ** key, the set the keyColumn variable to the primary key column index
+ ** in the original table definition.
+ */
+ if( pColumn==0 ){
+ keyColumn = pTab->iPKey;
+ }
+
+ /* Open the temp table for FOR EACH ROW triggers
+ */
+ if( triggers_exist ){
+ sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
+ }
+
+ /* Initialize the count of rows to be inserted
+ */
+ if( db->flags & SQLITE_CountRows ){
+ iCntMem = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, iCntMem, 1);
+ }
+
+ /* Open tables and indices if there are no row triggers */
+ if( !triggers_exist ){
+ base = pParse->nTab;
+ sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
+ }
+
+ /* If the data source is a temporary table, then we have to create
+ ** a loop because there might be multiple rows of data. If the data
+ ** source is a subroutine call from the SELECT statement, then we need
+ ** to launch the SELECT statement processing.
+ */
+ if( useTempTable ){
+ iBreak = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_Rewind, srcTab, iBreak);
+ iCont = sqlite3VdbeCurrentAddr(v);
+ }else if( pSelect ){
+ sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
+ sqlite3VdbeResolveLabel(v, iInsertBlock);
+ }
+
+ /* Run the BEFORE and INSTEAD OF triggers, if there are any
+ */
+ endOfLoop = sqlite3VdbeMakeLabel(v);
+ if( triggers_exist & TRIGGER_BEFORE ){
+
+ /* build the NEW.* reference row. Note that if there is an INTEGER
+ ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
+ ** translated into a unique ID for the row. But on a BEFORE trigger,
+ ** we do not know what the unique ID will be (because the insert has
+ ** not happened yet) so we substitute a rowid of -1
+ */
+ if( keyColumn<0 ){
+ sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
+ }else if( useTempTable ){
+ sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
+ }else{
+ assert( pSelect==0 ); /* Otherwise useTempTable is true */
+ sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
+ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
+ sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+ }
+
+ /* Create the new column data
+ */
+ for(i=0; i<pTab->nCol; i++){
+ if( pColumn==0 ){
+ j = i;
+ }else{
+ for(j=0; j<pColumn->nId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( pColumn && j>=pColumn->nId ){
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
+ }else if( useTempTable ){
+ sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
+ }else{
+ assert( pSelect==0 ); /* Otherwise useTempTable is true */
+ sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr);
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+
+ /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
+ ** do not attempt any conversions before assembling the record.
+ ** If this is a real table, attempt conversions as required by the
+ ** table column affinities.
+ */
+ if( !isView ){
+ sqlite3TableAffinityStr(v, pTab);
+ }
+ sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
+
+ /* Fire BEFORE or INSTEAD OF triggers */
+ if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab,
+ newIdx, -1, onError, endOfLoop) ){
+ goto insert_cleanup;
+ }
+ }
+
+ /* If any triggers exists, the opening of tables and indices is deferred
+ ** until now.
+ */
+ if( triggers_exist && !isView ){
+ base = pParse->nTab;
+ sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
+ }
+
+ /* Push the record number for the new entry onto the stack. The
+ ** record number is a randomly generate integer created by NewRowid
+ ** except when the table has an INTEGER PRIMARY KEY column, in which
+ ** case the record number is the same as that column.
+ */
+ if( !isView ){
+ if( keyColumn>=0 ){
+ if( useTempTable ){
+ sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
+ }else if( pSelect ){
+ sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
+ }else{
+ sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
+ }
+ /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
+ ** to generate a unique primary key value.
+ */
+ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
+ sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+ }else{
+ sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
+ }
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ if( pTab->autoInc ){
+ sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0);
+ }
+#endif /* SQLITE_OMIT_AUTOINCREMENT */
+
+ /* Push onto the stack, data for all columns of the new entry, beginning
+ ** with the first column.
+ */
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ /* The value of the INTEGER PRIMARY KEY column is always a NULL.
+ ** Whenever this column is read, the record number will be substituted
+ ** in its place. So will fill this column with a NULL to avoid
+ ** taking up data space with information that will never be used. */
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ continue;
+ }
+ if( pColumn==0 ){
+ j = i;
+ }else{
+ for(j=0; j<pColumn->nId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( pColumn && j>=pColumn->nId ){
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
+ }else if( useTempTable ){
+ sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
+ }else if( pSelect ){
+ sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
+ }else{
+ sqlite3ExprCode(pParse, pList->a[j].pExpr);
+ }
+ }
+
+ /* Generate code to check constraints and generate index keys and
+ ** do the insertion.
+ */
+ sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
+ 0, onError, endOfLoop);
+ sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
+ (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1);
+ }
+
+ /* Update the count of rows that are inserted
+ */
+ if( (db->flags & SQLITE_CountRows)!=0 ){
+ sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0);
+ }
+
+ if( triggers_exist ){
+ /* Close all tables opened */
+ if( !isView ){
+ sqlite3VdbeAddOp(v, OP_Close, base, 0);
+ for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
+ sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
+ }
+ }
+
+ /* Code AFTER triggers */
+ if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab,
+ newIdx, -1, onError, endOfLoop) ){
+ goto insert_cleanup;
+ }
+ }
+
+ /* The bottom of the loop, if the data source is a SELECT statement
+ */
+ sqlite3VdbeResolveLabel(v, endOfLoop);
+ if( useTempTable ){
+ sqlite3VdbeAddOp(v, OP_Next, srcTab, iCont);
+ sqlite3VdbeResolveLabel(v, iBreak);
+ sqlite3VdbeAddOp(v, OP_Close, srcTab, 0);
+ }else if( pSelect ){
+ sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
+ sqlite3VdbeAddOp(v, OP_Return, 0, 0);
+ sqlite3VdbeResolveLabel(v, iCleanup);
+ }
+
+ if( !triggers_exist ){
+ /* Close all tables opened */
+ sqlite3VdbeAddOp(v, OP_Close, base, 0);
+ for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
+ sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
+ }
+ }
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ /* Update the sqlite_sequence table by storing the content of the
+ ** counter value in memory counterMem back into the sqlite_sequence
+ ** table.
+ */
+ if( pTab->autoInc ){
+ int iCur = pParse->nTab;
+ int base = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
+ sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
+ sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
+ sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
+ sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+#endif
+
+ /*
+ ** Return the number of rows inserted. If this routine is
+ ** generating code because of a call to sqlite3NestedParse(), do not
+ ** invoke the callback function.
+ */
+ if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
+ sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
+ sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
+ }
+
+insert_cleanup:
+ sqlite3SrcListDelete(pTabList);
+ sqlite3ExprListDelete(pList);
+ sqlite3SelectDelete(pSelect);
+ sqlite3IdListDelete(pColumn);
+}
+
+/*
+** Generate code to do a constraint check prior to an INSERT or an UPDATE.
+**
+** When this routine is called, the stack contains (from bottom to top)
+** the following values:
+**
+** 1. The rowid of the row to be updated before the update. This
+** value is omitted unless we are doing an UPDATE that involves a
+** change to the record number.
+**
+** 2. The rowid of the row after the update.
+**
+** 3. The data in the first column of the entry after the update.
+**
+** i. Data from middle columns...
+**
+** N. The data in the last column of the entry after the update.
+**
+** The old rowid shown as entry (1) above is omitted unless both isUpdate
+** and rowidChng are 1. isUpdate is true for UPDATEs and false for
+** INSERTs and rowidChng is true if the record number is being changed.
+**
+** The code generated by this routine pushes additional entries onto
+** the stack which are the keys for new index entries for the new record.
+** The order of index keys is the same as the order of the indices on
+** the pTable->pIndex list. A key is only created for index i if
+** aIdxUsed!=0 and aIdxUsed[i]!=0.
+**
+** This routine also generates code to check constraints. NOT NULL,
+** CHECK, and UNIQUE constraints are all checked. If a constraint fails,
+** then the appropriate action is performed. There are five possible
+** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
+**
+** Constraint type Action What Happens
+** --------------- ---------- ----------------------------------------
+** any ROLLBACK The current transaction is rolled back and
+** sqlite3_exec() returns immediately with a
+** return code of SQLITE_CONSTRAINT.
+**
+** any ABORT Back out changes from the current command
+** only (do not do a complete rollback) then
+** cause sqlite3_exec() to return immediately
+** with SQLITE_CONSTRAINT.
+**
+** any FAIL Sqlite_exec() returns immediately with a
+** return code of SQLITE_CONSTRAINT. The
+** transaction is not rolled back and any
+** prior changes are retained.
+**
+** any IGNORE The record number and data is popped from
+** the stack and there is an immediate jump
+** to label ignoreDest.
+**
+** NOT NULL REPLACE The NULL value is replace by the default
+** value for that column. If the default value
+** is NULL, the action is the same as ABORT.
+**
+** UNIQUE REPLACE The other row that conflicts with the row
+** being inserted is removed.
+**
+** CHECK REPLACE Illegal. The results in an exception.
+**
+** Which action to take is determined by the overrideError parameter.
+** Or if overrideError==OE_Default, then the pParse->onError parameter
+** is used. Or if pParse->onError==OE_Default then the onError value
+** for the constraint is used.
+**
+** The calling routine must open a read/write cursor for pTab with
+** cursor number "base". All indices of pTab must also have open
+** read/write cursors with cursor number base+i for the i-th cursor.
+** Except, if there is no possibility of a REPLACE action then
+** cursors do not need to be open for indices where aIdxUsed[i]==0.
+**
+** If the isUpdate flag is true, it means that the "base" cursor is
+** initially pointing to an entry that is being updated. The isUpdate
+** flag causes extra code to be generated so that the "base" cursor
+** is still pointing at the same entry after the routine returns.
+** Without the isUpdate flag, the "base" cursor might be moved.
+*/
+void sqlite3GenerateConstraintChecks(
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* the table into which we are inserting */
+ int base, /* Index of a read/write cursor pointing at pTab */
+ char *aIdxUsed, /* Which indices are used. NULL means all are used */
+ int rowidChng, /* True if the record number will change */
+ int isUpdate, /* True for UPDATE, False for INSERT */
+ int overrideError, /* Override onError to this if not OE_Default */
+ int ignoreDest /* Jump to this label on an OE_Ignore resolution */
+){
+ int i;
+ Vdbe *v;
+ int nCol;
+ int onError;
+ int addr;
+ int extra;
+ int iCur;
+ Index *pIdx;
+ int seenReplace = 0;
+ int jumpInst1=0, jumpInst2;
+ int contAddr;
+ int hasTwoRowids = (isUpdate && rowidChng);
+
+ v = sqlite3GetVdbe(pParse);
+ assert( v!=0 );
+ assert( pTab->pSelect==0 ); /* This table is not a VIEW */
+ nCol = pTab->nCol;
+
+ /* Test all NOT NULL constraints.
+ */
+ for(i=0; i<nCol; i++){
+ if( i==pTab->iPKey ){
+ continue;
+ }
+ onError = pTab->aCol[i].notNull;
+ if( onError==OE_None ) continue;
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+ if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
+ onError = OE_Abort;
+ }
+ sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1);
+ addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0);
+ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
+ || onError==OE_Ignore || onError==OE_Replace );
+ switch( onError ){
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ char *zMsg = 0;
+ sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
+ sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
+ " may not be NULL", (char*)0);
+ sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
+ break;
+ }
+ case OE_Ignore: {
+ sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
+ break;
+ }
+ case OE_Replace: {
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
+ sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0);
+ break;
+ }
+ }
+ sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
+ }
+
+ /* Test all CHECK constraints
+ */
+ /**** TBD ****/
+
+ /* If we have an INTEGER PRIMARY KEY, make sure the primary key
+ ** of the new record does not previously exist. Except, if this
+ ** is an UPDATE and the primary key is not changing, that is OK.
+ */
+ if( rowidChng ){
+ onError = pTab->keyConf;
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+
+ if( isUpdate ){
+ sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
+ sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
+ jumpInst1 = sqlite3VdbeAddOp(v, OP_Eq, 0, 0);
+ }
+ sqlite3VdbeAddOp(v, OP_Dup, nCol, 1);
+ jumpInst2 = sqlite3VdbeAddOp(v, OP_NotExists, base, 0);
+ switch( onError ){
+ default: {
+ onError = OE_Abort;
+ /* Fall thru into the next case */
+ }
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
+ "PRIMARY KEY must be unique", P3_STATIC);
+ break;
+ }
+ case OE_Replace: {
+ sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
+ if( isUpdate ){
+ sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
+ sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
+ }
+ seenReplace = 1;
+ break;
+ }
+ case OE_Ignore: {
+ assert( seenReplace==0 );
+ sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
+ break;
+ }
+ }
+ contAddr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
+ if( isUpdate ){
+ sqlite3VdbeChangeP2(v, jumpInst1, contAddr);
+ sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
+ sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
+ }
+ }
+
+ /* Test all UNIQUE constraints by creating entries for each UNIQUE
+ ** index and making sure that duplicate entries do not already exist.
+ ** Add the new records to the indices as we go.
+ */
+ extra = -1;
+ for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
+ if( aIdxUsed && aIdxUsed[iCur]==0 ) continue; /* Skip unused indices */
+ extra++;
+
+ /* Create a key for accessing the index entry */
+ sqlite3VdbeAddOp(v, OP_Dup, nCol+extra, 1);
+ for(i=0; i<pIdx->nColumn; i++){
+ int idx = pIdx->aiColumn[i];
+ if( idx==pTab->iPKey ){
+ sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
+ }
+ }
+ jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
+ sqlite3IndexAffinityStr(v, pIdx);
+
+ /* Find out what action to take in case there is an indexing conflict */
+ onError = pIdx->onError;
+ if( onError==OE_None ) continue; /* pIdx is not a UNIQUE index */
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+ if( seenReplace ){
+ if( onError==OE_Ignore ) onError = OE_Replace;
+ else if( onError==OE_Fail ) onError = OE_Abort;
+ }
+
+
+ /* Check to see if the new index entry will be unique */
+ sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
+ jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
+
+ /* Generate code that executes if the new index entry is not unique */
+ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
+ || onError==OE_Ignore || onError==OE_Replace );
+ switch( onError ){
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ int j, n1, n2;
+ char zErrMsg[200];
+ strcpy(zErrMsg, pIdx->nColumn>1 ? "columns " : "column ");
+ n1 = strlen(zErrMsg);
+ for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){
+ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+ n2 = strlen(zCol);
+ if( j>0 ){
+ strcpy(&zErrMsg[n1], ", ");
+ n1 += 2;
+ }
+ if( n1+n2>sizeof(zErrMsg)-30 ){
+ strcpy(&zErrMsg[n1], "...");
+ n1 += 3;
+ break;
+ }else{
+ strcpy(&zErrMsg[n1], zCol);
+ n1 += n2;
+ }
+ }
+ strcpy(&zErrMsg[n1],
+ pIdx->nColumn>1 ? " are not unique" : " is not unique");
+ sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
+ break;
+ }
+ case OE_Ignore: {
+ assert( seenReplace==0 );
+ sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
+ break;
+ }
+ case OE_Replace: {
+ sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
+ if( isUpdate ){
+ sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
+ sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
+ }
+ seenReplace = 1;
+ break;
+ }
+ }
+ contAddr = sqlite3VdbeCurrentAddr(v);
+ assert( contAddr<(1<<24) );
+#if NULL_DISTINCT_FOR_UNIQUE
+ sqlite3VdbeChangeP2(v, jumpInst1, contAddr | (1<<24));
+#endif
+ sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
+ }
+}
+
+/*
+** This routine generates code to finish the INSERT or UPDATE operation
+** that was started by a prior call to sqlite3GenerateConstraintChecks.
+** The stack must contain keys for all active indices followed by data
+** and the rowid for the new entry. This routine creates the new
+** entries in all indices and in the main table.
+**
+** The arguments to this routine should be the same as the first six
+** arguments to sqlite3GenerateConstraintChecks.
+*/
+void sqlite3CompleteInsertion(
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* the table into which we are inserting */
+ int base, /* Index of a read/write cursor pointing at pTab */
+ char *aIdxUsed, /* Which indices are used. NULL means all are used */
+ int rowidChng, /* True if the record number will change */
+ int isUpdate, /* True for UPDATE, False for INSERT */
+ int newIdx /* Index of NEW table for triggers. -1 if none */
+){
+ int i;
+ Vdbe *v;
+ int nIdx;
+ Index *pIdx;
+ int pik_flags;
+
+ v = sqlite3GetVdbe(pParse);
+ assert( v!=0 );
+ assert( pTab->pSelect==0 ); /* This table is not a VIEW */
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
+ for(i=nIdx-1; i>=0; i--){
+ if( aIdxUsed && aIdxUsed[i]==0 ) continue;
+ sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0);
+ }
+ sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ sqlite3TableAffinityStr(v, pTab);
+#ifndef SQLITE_OMIT_TRIGGER
+ if( newIdx>=0 ){
+ sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
+ }
+#endif
+ if( pParse->nested ){
+ pik_flags = 0;
+ }else{
+ pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
+ }
+ sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
+
+ if( isUpdate && rowidChng ){
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ }
+}
+
+/*
+** Generate code that will open cursors for a table and for all
+** indices of that table. The "base" parameter is the cursor number used
+** for the table. Indices are opened on subsequent cursors.
+*/
+void sqlite3OpenTableAndIndices(
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* Table to be opened */
+ int base, /* Cursor number assigned to the table */
+ int op /* OP_OpenRead or OP_OpenWrite */
+){
+ int i;
+ Index *pIdx;
+ 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_SetNumColumns, base, pTab->nCol);
+ for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
+ (char*)&pIdx->keyInfo, P3_KEYINFO);
+ }
+ if( pParse->nTab<=base+i ){
+ pParse->nTab = base+i;
+ }
+}
diff --git a/src/sqlite/keywordhash.h b/src/sqlite/keywordhash.h
new file mode 100644
index 0000000..2eef13b
--- /dev/null
+++ b/src/sqlite/keywordhash.h
@@ -0,0 +1,96 @@
+/* Hash score: 153 */
+static int keywordCode(const char *z, int n){
+ static const char zText[515] =
+ "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER"
+ "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYAND"
+ "EFERRABLEXCLUSIVEXISTSTATEMENTATTACHAVINGLOBEFOREIGNOREINDEXAUTOINCREMENT"
+ "BEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETECASECOLLATECOLUMN"
+ "COMMITCONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATECURRENT_TIMESTAMP"
+ "RAGMATCHDESCDETACHDISTINCTDROPRIMARYFAILIMITFROMFULLGROUPDATE"
+ "IMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDEREPLACEOUTERESTRICT"
+ "RIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEWHERE";
+ 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,
+ };
+ static const unsigned char aNext[111] = {
+ 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,
+ };
+ static const unsigned char aLen[111] = {
+ 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,
+ };
+ static const unsigned short int aOffset[111] = {
+ 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,
+ };
+ static const unsigned char aCode[111] = {
+ 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,
+ };
+ int h, i;
+ if( n<2 ) return TK_ID;
+ h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^
+ (sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^
+ n) % 127;
+ for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
+ if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
+ return aCode[i];
+ }
+ }
+ return TK_ID;
+}
+int sqlite3KeywordCode(const char *z, int n){
+ return keywordCode(z, n);
+}
diff --git a/src/sqlite/legacy.c b/src/sqlite/legacy.c
new file mode 100644
index 0000000..dcb0463
--- /dev/null
+++ b/src/sqlite/legacy.c
@@ -0,0 +1,138 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Main file for the SQLite library. The routines in this file
+** implement the programmer interface to the library. Routines in
+** other files are for internal use by SQLite and should not be
+** accessed by users of the library.
+**
+** $Id: legacy.c,v 1.1.1.1 2006/02/03 20:35:11 hoganrobert Exp $
+*/
+
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+
+/*
+** Execute SQL code. Return one of the SQLITE_ success/failure
+** codes. Also write an error message into memory obtained from
+** malloc() and make *pzErrMsg point to that message.
+**
+** If the SQL is a query, then for each row in the query result
+** the xCallback() function is called. pArg becomes the first
+** argument to xCallback(). If xCallback=NULL then no callback
+** is invoked, even for queries.
+*/
+int sqlite3_exec(
+ sqlite3 *db, /* The database on which the SQL executes */
+ const char *zSql, /* The SQL to be executed */
+ sqlite3_callback xCallback, /* Invoke this callback routine */
+ void *pArg, /* First argument to xCallback() */
+ char **pzErrMsg /* Write error messages here */
+){
+ int rc = SQLITE_OK;
+ const char *zLeftover;
+ sqlite3_stmt *pStmt = 0;
+ char **azCols = 0;
+
+ int nRetry = 0;
+ int nChange = 0;
+ int nCallback;
+
+ if( zSql==0 ) return SQLITE_OK;
+ while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
+ int nCol;
+ char **azVals = 0;
+
+ pStmt = 0;
+ rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
+ if( rc!=SQLITE_OK ){
+ if( pStmt ) sqlite3_finalize(pStmt);
+ continue;
+ }
+ if( !pStmt ){
+ /* this happens for a comment or white-space */
+ zSql = zLeftover;
+ continue;
+ }
+
+ db->nChange += nChange;
+ nCallback = 0;
+
+ nCol = sqlite3_column_count(pStmt);
+ azCols = sqliteMalloc(2*nCol*sizeof(const char *));
+ if( nCol && !azCols ){
+ rc = SQLITE_NOMEM;
+ goto exec_out;
+ }
+
+ while( 1 ){
+ int i;
+ rc = sqlite3_step(pStmt);
+
+ /* Invoke the callback function if required */
+ if( xCallback && (SQLITE_ROW==rc ||
+ (SQLITE_DONE==rc && !nCallback && db->flags&SQLITE_NullCallback)) ){
+ if( 0==nCallback ){
+ for(i=0; i<nCol; i++){
+ azCols[i] = (char *)sqlite3_column_name(pStmt, i);
+ }
+ nCallback++;
+ }
+ if( rc==SQLITE_ROW ){
+ azVals = &azCols[nCol];
+ for(i=0; i<nCol; i++){
+ azVals[i] = (char *)sqlite3_column_text(pStmt, i);
+ }
+ }
+ if( xCallback(pArg, nCol, azVals, azCols) ){
+ rc = SQLITE_ABORT;
+ goto exec_out;
+ }
+ }
+
+ if( rc!=SQLITE_ROW ){
+ rc = sqlite3_finalize(pStmt);
+ pStmt = 0;
+ if( db->pVdbe==0 ){
+ nChange = db->nChange;
+ }
+ if( rc!=SQLITE_SCHEMA ){
+ nRetry = 0;
+ zSql = zLeftover;
+ while( isspace((unsigned char)zSql[0]) ) zSql++;
+ }
+ break;
+ }
+ }
+
+ sqliteFree(azCols);
+ azCols = 0;
+ }
+
+exec_out:
+ if( pStmt ) sqlite3_finalize(pStmt);
+ if( azCols ) sqliteFree(azCols);
+
+ if( sqlite3_malloc_failed ){
+ rc = SQLITE_NOMEM;
+ }
+ if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
+ *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
+ if( *pzErrMsg ){
+ strcpy(*pzErrMsg, sqlite3_errmsg(db));
+ }
+ }else if( pzErrMsg ){
+ *pzErrMsg = 0;
+ }
+
+ return rc;
+}
diff --git a/src/sqlite/main.c b/src/sqlite/main.c
new file mode 100644
index 0000000..09fdb6a
--- /dev/null
+++ b/src/sqlite/main.c
@@ -0,0 +1,1003 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Main file for the SQLite library. The routines in this file
+** implement the programmer interface to the library. Routines in
+** other files are for internal use by SQLite and should not be
+** accessed by users of the library.
+**
+** $Id: main.c,v 1.1.1.1 2006/02/03 20:35:13 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+
+/*
+** The following constant value is used by the SQLITE_BIGENDIAN and
+** SQLITE_LITTLEENDIAN macros.
+*/
+const int sqlite3one = 1;
+
+#ifndef SQLITE_OMIT_GLOBALRECOVER
+/*
+** Linked list of all open database handles. This is used by the
+** sqlite3_global_recover() function. Entries are added to the list
+** by openDatabase() and removed by sqlite3_close().
+*/
+static sqlite3 *pDbList = 0;
+#endif
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** Return the transient sqlite3_value object used for encoding conversions
+** during SQL compilation.
+*/
+sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
+ if( !db->pValue ){
+ db->pValue = sqlite3ValueNew();
+ }
+ return db->pValue;
+}
+#endif
+
+/*
+** The version of the library
+*/
+const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
+const char sqlite3_version[] = SQLITE_VERSION;
+const char *sqlite3_libversion(void){ return sqlite3_version; }
+int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
+
+/*
+** This is the default collating function named "BINARY" which is always
+** available.
+*/
+static int binCollFunc(
+ void *NotUsed,
+ int nKey1, const void *pKey1,
+ int nKey2, const void *pKey2
+){
+ int rc, n;
+ n = nKey1<nKey2 ? nKey1 : nKey2;
+ rc = memcmp(pKey1, pKey2, n);
+ if( rc==0 ){
+ rc = nKey1 - nKey2;
+ }
+ return rc;
+}
+
+/*
+** Another built-in collating sequence: NOCASE.
+**
+** This collating sequence is intended to be used for "case independant
+** comparison". SQLite's knowledge of upper and lower case equivalents
+** extends only to the 26 characters used in the English language.
+**
+** At the moment there is only a UTF-8 implementation.
+*/
+static int nocaseCollatingFunc(
+ void *NotUsed,
+ int nKey1, const void *pKey1,
+ int nKey2, const void *pKey2
+){
+ int r = sqlite3StrNICmp(
+ (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2);
+ if( 0==r ){
+ r = nKey1-nKey2;
+ }
+ return r;
+}
+
+/*
+** Return the ROWID of the most recent insert
+*/
+sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
+ return db->lastRowid;
+}
+
+/*
+** Return the number of changes in the most recent call to sqlite3_exec().
+*/
+int sqlite3_changes(sqlite3 *db){
+ return db->nChange;
+}
+
+/*
+** Return the number of changes since the database handle was opened.
+*/
+int sqlite3_total_changes(sqlite3 *db){
+ return db->nTotalChange;
+}
+
+/*
+** Close an existing SQLite database
+*/
+int sqlite3_close(sqlite3 *db){
+ HashElem *i;
+ int j;
+
+ if( !db ){
+ return SQLITE_OK;
+ }
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+
+#ifdef SQLITE_SSE
+ sqlite3_finalize(db->pFetch);
+#endif
+
+ /* If there are any outstanding VMs, return SQLITE_BUSY. */
+ if( db->pVdbe ){
+ sqlite3Error(db, SQLITE_BUSY,
+ "Unable to close due to unfinalised statements");
+ return SQLITE_BUSY;
+ }
+ assert( !sqlite3SafetyCheck(db) );
+
+ /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database
+ ** cannot be opened for some reason. So this routine needs to run in
+ ** that case. But maybe there should be an extra magic value for the
+ ** "failed to open" state.
+ */
+ if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
+ /* printf("DID NOT CLOSE\n"); fflush(stdout); */
+ return SQLITE_ERROR;
+ }
+
+ for(j=0; j<db->nDb; j++){
+ struct Db *pDb = &db->aDb[j];
+ if( pDb->pBt ){
+ sqlite3BtreeClose(pDb->pBt);
+ pDb->pBt = 0;
+ }
+ }
+ sqlite3ResetInternalSchema(db, 0);
+ assert( db->nDb<=2 );
+ assert( db->aDb==db->aDbStatic );
+ for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
+ FuncDef *pFunc, *pNext;
+ for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
+ pNext = pFunc->pNext;
+ sqliteFree(pFunc);
+ }
+ }
+
+ for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
+ CollSeq *pColl = (CollSeq *)sqliteHashData(i);
+ sqliteFree(pColl);
+ }
+ sqlite3HashClear(&db->aCollSeq);
+
+ sqlite3HashClear(&db->aFunc);
+ sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
+ if( db->pValue ){
+ sqlite3ValueFree(db->pValue);
+ }
+ if( db->pErr ){
+ sqlite3ValueFree(db->pErr);
+ }
+
+#ifndef SQLITE_OMIT_GLOBALRECOVER
+ {
+ sqlite3 *pPrev;
+ sqlite3OsEnterMutex();
+ pPrev = pDbList;
+ while( pPrev && pPrev->pNext!=db ){
+ pPrev = pPrev->pNext;
+ }
+ if( pPrev ){
+ pPrev->pNext = db->pNext;
+ }else{
+ assert( pDbList==db );
+ pDbList = db->pNext;
+ }
+ sqlite3OsLeaveMutex();
+ }
+#endif
+
+ db->magic = SQLITE_MAGIC_ERROR;
+ sqliteFree(db);
+ return SQLITE_OK;
+}
+
+/*
+** Rollback all database files.
+*/
+void sqlite3RollbackAll(sqlite3 *db){
+ int i;
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt ){
+ sqlite3BtreeRollback(db->aDb[i].pBt);
+ db->aDb[i].inTrans = 0;
+ }
+ }
+ sqlite3ResetInternalSchema(db, 0);
+}
+
+/*
+** Return a static string that describes the kind of error specified in the
+** argument.
+*/
+const char *sqlite3ErrStr(int rc){
+ const char *z;
+ switch( rc ){
+ case SQLITE_ROW:
+ 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;
+ case SQLITE_LOCKED: z = "database table is locked"; break;
+ case SQLITE_NOMEM: z = "out of memory"; break;
+ case SQLITE_READONLY: z = "attempt to write a readonly database"; break;
+ 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_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;
+ case SQLITE_NOLFS: z = "kernel lacks large file support"; break;
+ case SQLITE_AUTH: z = "authorization denied"; break;
+ case SQLITE_FORMAT: z = "auxiliary database format error"; break;
+ case SQLITE_RANGE: z = "bind or column index out of range"; break;
+ case SQLITE_NOTADB: z = "file is encrypted or is not a database";break;
+ default: z = "unknown error"; break;
+ }
+ return z;
+}
+
+/*
+** This routine implements a busy callback that sleeps and tries
+** again until a timeout value is reached. The timeout value is
+** an integer number of milliseconds passed in as the first
+** argument.
+*/
+static int sqliteDefaultBusyCallback(
+ void *ptr, /* Database connection */
+ int count /* Number of times table has been busy */
+){
+#if SQLITE_MIN_SLEEP_MS==1
+ static const u8 delays[] =
+ { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
+ static const u8 totals[] =
+ { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
+# define NDELAY (sizeof(delays)/sizeof(delays[0]))
+ int timeout = ((sqlite3 *)ptr)->busyTimeout;
+ int delay, prior;
+
+ assert( count>=0 );
+ if( count < NDELAY ){
+ delay = delays[count];
+ prior = totals[count];
+ }else{
+ delay = delays[NDELAY-1];
+ prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
+ }
+ if( prior + delay > timeout ){
+ delay = timeout - prior;
+ if( delay<=0 ) return 0;
+ }
+ sqlite3OsSleep(delay);
+ return 1;
+#else
+ int timeout = ((sqlite3 *)ptr)->busyTimeout;
+ if( (count+1)*1000 > timeout ){
+ return 0;
+ }
+ sqlite3OsSleep(1000);
+ return 1;
+#endif
+}
+
+/*
+** This routine sets the busy callback for an Sqlite database to the
+** given callback function with the given argument.
+*/
+int sqlite3_busy_handler(
+ sqlite3 *db,
+ int (*xBusy)(void*,int),
+ void *pArg
+){
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ db->busyHandler.xFunc = xBusy;
+ db->busyHandler.pArg = pArg;
+ return SQLITE_OK;
+}
+
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+/*
+** This routine sets the progress callback for an Sqlite database to the
+** given callback function with the given argument. The progress callback will
+** be invoked every nOps opcodes.
+*/
+void sqlite3_progress_handler(
+ sqlite3 *db,
+ int nOps,
+ int (*xProgress)(void*),
+ void *pArg
+){
+ if( !sqlite3SafetyCheck(db) ){
+ if( nOps>0 ){
+ db->xProgress = xProgress;
+ db->nProgressOps = nOps;
+ db->pProgressArg = pArg;
+ }else{
+ db->xProgress = 0;
+ db->nProgressOps = 0;
+ db->pProgressArg = 0;
+ }
+ }
+}
+#endif
+
+
+/*
+** This routine installs a default busy handler that waits for the
+** specified number of milliseconds before returning 0.
+*/
+int sqlite3_busy_timeout(sqlite3 *db, int ms){
+ if( ms>0 ){
+ db->busyTimeout = ms;
+ sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
+ }else{
+ sqlite3_busy_handler(db, 0, 0);
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Cause any pending operation to stop at its earliest opportunity.
+*/
+void sqlite3_interrupt(sqlite3 *db){
+ if( !sqlite3SafetyCheck(db) ){
+ db->flags |= SQLITE_Interrupt;
+ }
+}
+
+/*
+** Windows systems should call this routine to free memory that
+** is returned in the in the errmsg parameter of sqlite3_open() when
+** SQLite is a DLL. For some reason, it does not work to call free()
+** directly.
+**
+** Note that we need to call free() not sqliteFree() here.
+*/
+void sqlite3_free(char *p){ free(p); }
+
+/*
+** Create new user functions.
+*/
+int sqlite3_create_function(
+ sqlite3 *db,
+ const char *zFunctionName,
+ int nArg,
+ int enc,
+ void *pUserData,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+ void (*xFinal)(sqlite3_context*)
+){
+ FuncDef *p;
+ int nName;
+
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ if( zFunctionName==0 ||
+ (xFunc && (xFinal || xStep)) ||
+ (!xFunc && (xFinal && !xStep)) ||
+ (!xFunc && (!xFinal && xStep)) ||
+ (nArg<-1 || nArg>127) ||
+ (255<(nName = strlen(zFunctionName))) ){
+ return SQLITE_ERROR;
+ }
+
+#ifndef SQLITE_OMIT_UTF16
+ /* If SQLITE_UTF16 is specified as the encoding type, transform this
+ ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
+ ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
+ **
+ ** If SQLITE_ANY is specified, add three versions of the function
+ ** to the hash table.
+ */
+ if( enc==SQLITE_UTF16 ){
+ enc = SQLITE_UTF16NATIVE;
+ }else if( enc==SQLITE_ANY ){
+ int rc;
+ rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF8,
+ pUserData, xFunc, xStep, xFinal);
+ if( rc!=SQLITE_OK ) return rc;
+ rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF16LE,
+ pUserData, xFunc, xStep, xFinal);
+ if( rc!=SQLITE_OK ) return rc;
+ enc = SQLITE_UTF16BE;
+ }
+#else
+ enc = SQLITE_UTF8;
+#endif
+
+ /* Check if an existing function is being overridden or deleted. If so,
+ ** and there are active VMs, then return SQLITE_BUSY. If a function
+ ** is being overridden/deleted but there are no active VMs, allow the
+ ** operation to continue but invalidate all precompiled statements.
+ */
+ p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0);
+ if( p && p->iPrefEnc==enc && p->nArg==nArg ){
+ if( db->activeVdbeCnt ){
+ sqlite3Error(db, SQLITE_BUSY,
+ "Unable to delete/modify user-function due to active statements");
+ return SQLITE_BUSY;
+ }else{
+ sqlite3ExpirePreparedStatements(db);
+ }
+ }
+
+ p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
+ if( p==0 ) return SQLITE_NOMEM;
+ p->xFunc = xFunc;
+ p->xStep = xStep;
+ p->xFinalize = xFinal;
+ p->pUserData = pUserData;
+ return SQLITE_OK;
+}
+#ifndef SQLITE_OMIT_UTF16
+int sqlite3_create_function16(
+ sqlite3 *db,
+ const void *zFunctionName,
+ int nArg,
+ int eTextRep,
+ void *pUserData,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*)
+){
+ int rc;
+ char const *zFunc8;
+ sqlite3_value *pTmp;
+
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ pTmp = sqlite3GetTransientValue(db);
+ sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);
+ zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
+
+ if( !zFunc8 ){
+ return SQLITE_NOMEM;
+ }
+ rc = sqlite3_create_function(db, zFunc8, nArg, eTextRep,
+ pUserData, xFunc, xStep, xFinal);
+ return rc;
+}
+#endif
+
+/*
+** Register a trace function. The pArg from the previously registered trace
+** is returned.
+**
+** A NULL trace function means that no tracing is executes. A non-NULL
+** trace is a pointer to a function that is invoked at the start of each
+** sqlite3_exec().
+*/
+void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
+ void *pOld = db->pTraceArg;
+ db->xTrace = xTrace;
+ db->pTraceArg = pArg;
+ return pOld;
+}
+
+/*** EXPERIMENTAL ***
+**
+** Register a function to be invoked when a transaction comments.
+** If either function returns non-zero, then the commit becomes a
+** rollback.
+*/
+void *sqlite3_commit_hook(
+ sqlite3 *db, /* Attach the hook to this database */
+ int (*xCallback)(void*), /* Function to invoke on each commit */
+ void *pArg /* Argument to the function */
+){
+ void *pOld = db->pCommitArg;
+ db->xCommitCallback = xCallback;
+ db->pCommitArg = pArg;
+ return pOld;
+}
+
+
+/*
+** This routine is called to create a connection to a database BTree
+** driver. If zFilename is the name of a file, then that file is
+** 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.
+**
+** 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,
+** depending on the values of the TEMP_STORE compile-time macro and the
+** db->temp_store variable, according to the following chart:
+**
+** TEMP_STORE db->temp_store Location of temporary database
+** ---------- -------------- ------------------------------
+** 0 any file
+** 1 1 file
+** 1 2 memory
+** 1 0 file
+** 2 1 file
+** 2 2 memory
+** 2 0 memory
+** 3 any memory
+*/
+int sqlite3BtreeFactory(
+ const sqlite3 *db, /* Main database when opening aux otherwise 0 */
+ const char *zFilename, /* Name of the file containing the BTree database */
+ int omitJournal, /* if TRUE then do not journal this file */
+ int nCache, /* How many pages in the page cache */
+ Btree **ppBtree /* Pointer to new Btree object written here */
+){
+ int btree_flags = 0;
+ int rc;
+
+ assert( ppBtree != 0);
+ if( omitJournal ){
+ btree_flags |= BTREE_OMIT_JOURNAL;
+ }
+ if( db->flags & SQLITE_NoReadlock ){
+ btree_flags |= BTREE_NO_READLOCK;
+ }
+ if( zFilename==0 ){
+#if TEMP_STORE==0
+ /* Do nothing */
+#endif
+#ifndef SQLITE_OMIT_MEMORYDB
+#if TEMP_STORE==1
+ if( db->temp_store==2 ) zFilename = ":memory:";
+#endif
+#if TEMP_STORE==2
+ if( db->temp_store!=1 ) zFilename = ":memory:";
+#endif
+#if TEMP_STORE==3
+ zFilename = ":memory:";
+#endif
+#endif /* SQLITE_OMIT_MEMORYDB */
+ }
+
+ rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags);
+ if( rc==SQLITE_OK ){
+ sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
+ sqlite3BtreeSetCacheSize(*ppBtree, nCache);
+ }
+ return rc;
+}
+
+/*
+** Return UTF-8 encoded English language explanation of the most recent
+** error.
+*/
+const char *sqlite3_errmsg(sqlite3 *db){
+ const char *z;
+ if( sqlite3_malloc_failed ){
+ return sqlite3ErrStr(SQLITE_NOMEM);
+ }
+ if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
+ return sqlite3ErrStr(SQLITE_MISUSE);
+ }
+ z = sqlite3_value_text(db->pErr);
+ if( z==0 ){
+ z = sqlite3ErrStr(db->errCode);
+ }
+ return z;
+}
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** Return UTF-16 encoded English language explanation of the most recent
+** error.
+*/
+const void *sqlite3_errmsg16(sqlite3 *db){
+ /* Because all the characters in the string are in the unicode
+ ** range 0x00-0xFF, if we pad the big-endian string with a
+ ** zero byte, we can obtain the little-endian string with
+ ** &big_endian[1].
+ */
+ static const char outOfMemBe[] = {
+ 0, 'o', 0, 'u', 0, 't', 0, ' ',
+ 0, 'o', 0, 'f', 0, ' ',
+ 0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0
+ };
+ static const char misuseBe [] = {
+ 0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ',
+ 0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ',
+ 0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ',
+ 0, 'o', 0, 'u', 0, 't', 0, ' ',
+ 0, 'o', 0, 'f', 0, ' ',
+ 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
+ };
+
+ const void *z;
+ if( sqlite3_malloc_failed ){
+ return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
+ }
+ if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
+ return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
+ }
+ z = sqlite3_value_text16(db->pErr);
+ if( z==0 ){
+ sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
+ SQLITE_UTF8, SQLITE_STATIC);
+ z = sqlite3_value_text16(db->pErr);
+ }
+ return z;
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+/*
+** Return the most recent error code generated by an SQLite routine.
+*/
+int sqlite3_errcode(sqlite3 *db){
+ if( sqlite3_malloc_failed ){
+ return SQLITE_NOMEM;
+ }
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ return db->errCode;
+}
+
+/*
+** This routine does the work of opening a database on behalf of
+** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"
+** is UTF-8 encoded.
+*/
+static int openDatabase(
+ const char *zFilename, /* Database filename UTF-8 encoded */
+ sqlite3 **ppDb /* OUT: Returned database handle */
+){
+ sqlite3 *db;
+ int rc, i;
+
+ /* Allocate the sqlite data structure */
+ db = sqliteMalloc( sizeof(sqlite3) );
+ if( db==0 ) goto opendb_out;
+ db->priorNewRowid = 0;
+ db->magic = SQLITE_MAGIC_BUSY;
+ db->nDb = 2;
+ db->aDb = db->aDbStatic;
+ db->enc = SQLITE_UTF8;
+ db->autoCommit = 1;
+ db->flags |= SQLITE_ShortColNames;
+ sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
+ sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
+ for(i=0; i<db->nDb; i++){
+ sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
+ sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
+ sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
+ sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
+ }
+
+ /* Add the default collation sequence BINARY. BINARY works for both UTF-8
+ ** and UTF-16, so add a version for each to avoid any unnecessary
+ ** conversions. The only error that can occur here is a malloc() failure.
+ */
+ if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
+ sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
+ !(db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0)) ){
+ rc = db->errCode;
+ assert( rc!=SQLITE_OK );
+ db->magic = SQLITE_MAGIC_CLOSED;
+ goto opendb_out;
+ }
+
+ /* Also add a UTF-8 case-insensitive collation sequence. */
+ sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
+
+ /* Open the backend database driver */
+ rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
+ if( rc!=SQLITE_OK ){
+ sqlite3Error(db, rc, 0);
+ db->magic = SQLITE_MAGIC_CLOSED;
+ goto opendb_out;
+ }
+
+ /* The default safety_level for the main database is 'full'; for the temp
+ ** database it is 'NONE'. This matches the pager layer defaults.
+ */
+ db->aDb[0].zName = "main";
+ db->aDb[0].safety_level = 3;
+#ifndef SQLITE_OMIT_TEMPDB
+ db->aDb[1].zName = "temp";
+ db->aDb[1].safety_level = 1;
+#endif
+
+
+ /* Register all built-in functions, but do not attempt to read the
+ ** database schema yet. This is delayed until the first time the database
+ ** is accessed.
+ */
+ sqlite3RegisterBuiltinFunctions(db);
+ sqlite3Error(db, SQLITE_OK, 0);
+ db->magic = SQLITE_MAGIC_OPEN;
+
+opendb_out:
+ if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){
+ sqlite3Error(db, SQLITE_NOMEM, 0);
+ }
+ *ppDb = db;
+#ifndef SQLITE_OMIT_GLOBALRECOVER
+ if( db ){
+ sqlite3OsEnterMutex();
+ db->pNext = pDbList;
+ pDbList = db;
+ sqlite3OsLeaveMutex();
+ }
+#endif
+ return sqlite3_errcode(db);
+}
+
+/*
+** Open a new database handle.
+*/
+int sqlite3_open(
+ const char *zFilename,
+ sqlite3 **ppDb
+){
+ return openDatabase(zFilename, ppDb);
+}
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** Open a new database handle.
+*/
+int sqlite3_open16(
+ const void *zFilename,
+ sqlite3 **ppDb
+){
+ char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */
+ int rc = SQLITE_NOMEM;
+ sqlite3_value *pVal;
+
+ assert( ppDb );
+ *ppDb = 0;
+ pVal = sqlite3ValueNew();
+ sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
+ zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
+ if( zFilename8 ){
+ rc = openDatabase(zFilename8, ppDb);
+ if( rc==SQLITE_OK && *ppDb ){
+ sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
+ }
+ }
+ if( pVal ){
+ sqlite3ValueFree(pVal);
+ }
+
+ return rc;
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+/*
+** The following routine destroys a virtual machine that is created by
+** the sqlite3_compile() routine. The integer returned is an SQLITE_
+** success/failure code that describes the result of executing the virtual
+** machine.
+**
+** This routine sets the error code and string returned by
+** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
+*/
+int sqlite3_finalize(sqlite3_stmt *pStmt){
+ int rc;
+ if( pStmt==0 ){
+ rc = SQLITE_OK;
+ }else{
+ rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
+ }
+ return rc;
+}
+
+/*
+** Terminate the current execution of an SQL statement and reset it
+** back to its starting state so that it can be reused. A success code from
+** the prior execution is returned.
+**
+** This routine sets the error code and string returned by
+** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
+*/
+int sqlite3_reset(sqlite3_stmt *pStmt){
+ int rc;
+ if( pStmt==0 ){
+ rc = SQLITE_OK;
+ }else{
+ rc = sqlite3VdbeReset((Vdbe*)pStmt);
+ sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0, 0);
+ }
+ return rc;
+}
+
+/*
+** Register a new collation sequence with the database handle db.
+*/
+int sqlite3_create_collation(
+ sqlite3* db,
+ const char *zName,
+ int enc,
+ void* pCtx,
+ int(*xCompare)(void*,int,const void*,int,const void*)
+){
+ CollSeq *pColl;
+ int rc = SQLITE_OK;
+
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+
+ /* If SQLITE_UTF16 is specified as the encoding type, transform this
+ ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
+ ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
+ */
+ if( enc==SQLITE_UTF16 ){
+ enc = SQLITE_UTF16NATIVE;
+ }
+
+ if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16LE && enc!=SQLITE_UTF16BE ){
+ sqlite3Error(db, SQLITE_ERROR,
+ "Param 3 to sqlite3_create_collation() must be one of "
+ "SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
+ );
+ return SQLITE_ERROR;
+ }
+
+ /* Check if this call is removing or replacing an existing collation
+ ** sequence. If so, and there are active VMs, return busy. If there
+ ** are no active VMs, invalidate any pre-compiled statements.
+ */
+ pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0);
+ if( pColl && pColl->xCmp ){
+ if( db->activeVdbeCnt ){
+ sqlite3Error(db, SQLITE_BUSY,
+ "Unable to delete/modify collation sequence due to active statements");
+ return SQLITE_BUSY;
+ }
+ sqlite3ExpirePreparedStatements(db);
+ }
+
+ pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
+ if( 0==pColl ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pColl->xCmp = xCompare;
+ pColl->pUser = pCtx;
+ pColl->enc = enc;
+ }
+ sqlite3Error(db, rc, 0);
+ return rc;
+}
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** Register a new collation sequence with the database handle db.
+*/
+int sqlite3_create_collation16(
+ sqlite3* db,
+ const char *zName,
+ int enc,
+ void* pCtx,
+ int(*xCompare)(void*,int,const void*,int,const void*)
+){
+ char const *zName8;
+ sqlite3_value *pTmp;
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ pTmp = sqlite3GetTransientValue(db);
+ sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF16NATIVE, SQLITE_STATIC);
+ zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
+ return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+/*
+** Register a collation sequence factory callback with the database handle
+** db. Replace any previously installed collation sequence factory.
+*/
+int sqlite3_collation_needed(
+ sqlite3 *db,
+ void *pCollNeededArg,
+ void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
+){
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ db->xCollNeeded = xCollNeeded;
+ db->xCollNeeded16 = 0;
+ db->pCollNeededArg = pCollNeededArg;
+ return SQLITE_OK;
+}
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** Register a collation sequence factory callback with the database handle
+** db. Replace any previously installed collation sequence factory.
+*/
+int sqlite3_collation_needed16(
+ sqlite3 *db,
+ void *pCollNeededArg,
+ void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
+){
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ db->xCollNeeded = 0;
+ db->xCollNeeded16 = xCollNeeded16;
+ db->pCollNeededArg = pCollNeededArg;
+ return SQLITE_OK;
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+#ifndef SQLITE_OMIT_GLOBALRECOVER
+/*
+** This function is called to recover from a malloc failure that occured
+** within SQLite.
+**
+** This function is *not* threadsafe. Calling this from within a threaded
+** application when threads other than the caller have used SQLite is
+** dangerous and will almost certainly result in malfunctions.
+*/
+int sqlite3_global_recover(){
+ int rc = SQLITE_OK;
+
+ if( sqlite3_malloc_failed ){
+ sqlite3 *db;
+ int i;
+ sqlite3_malloc_failed = 0;
+ for(db=pDbList; db; db=db->pNext ){
+ sqlite3ExpirePreparedStatements(db);
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt && (rc=sqlite3BtreeReset(pBt)) ){
+ goto recover_out;
+ }
+ }
+ db->autoCommit = 1;
+ }
+ }
+
+recover_out:
+ if( rc!=SQLITE_OK ){
+ sqlite3_malloc_failed = 1;
+ }
+ return rc;
+}
+#endif
+
+/*
+** Test to see whether or not the database connection is in autocommit
+** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
+** by default. Autocommit is disabled by a BEGIN statement and reenabled
+** by the next COMMIT or ROLLBACK.
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+int sqlite3_get_autocommit(sqlite3 *db){
+ return db->autoCommit;
+}
diff --git a/src/sqlite/opcodes.c b/src/sqlite/opcodes.c
new file mode 100644
index 0000000..08cf6a1
--- /dev/null
+++ b/src/sqlite/opcodes.c
@@ -0,0 +1,135 @@
+/* Automatically generated. Do not edit */
+/* See the mkopcodec.awk script for details. */
+#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+const char *const sqlite3OpcodeNames[] = { "?",
+ /* 1 */ "MemLoad",
+ /* 2 */ "Column",
+ /* 3 */ "SetCookie",
+ /* 4 */ "IfMemPos",
+ /* 5 */ "MoveGt",
+ /* 6 */ "AggFocus",
+ /* 7 */ "RowKey",
+ /* 8 */ "AggNext",
+ /* 9 */ "OpenWrite",
+ /* 10 */ "If",
+ /* 11 */ "Pop",
+ /* 12 */ "AggContextPush",
+ /* 13 */ "CollSeq",
+ /* 14 */ "OpenRead",
+ /* 15 */ "Expire",
+ /* 16 */ "SortReset",
+ /* 17 */ "AutoCommit",
+ /* 18 */ "Sort",
+ /* 19 */ "ListRewind",
+ /* 20 */ "IntegrityCk",
+ /* 21 */ "SortInsert",
+ /* 22 */ "Function",
+ /* 23 */ "Noop",
+ /* 24 */ "Return",
+ /* 25 */ "NewRowid",
+ /* 26 */ "Variable",
+ /* 27 */ "String",
+ /* 28 */ "ParseSchema",
+ /* 29 */ "AggFunc",
+ /* 30 */ "Close",
+ /* 31 */ "ListWrite",
+ /* 32 */ "CreateIndex",
+ /* 33 */ "IsUnique",
+ /* 34 */ "IdxIsNull",
+ /* 35 */ "NotFound",
+ /* 36 */ "MustBeInt",
+ /* 37 */ "Halt",
+ /* 38 */ "Rowid",
+ /* 39 */ "IdxLT",
+ /* 40 */ "AddImm",
+ /* 41 */ "Statement",
+ /* 42 */ "RowData",
+ /* 43 */ "MemMax",
+ /* 44 */ "Push",
+ /* 45 */ "NotExists",
+ /* 46 */ "OpenTemp",
+ /* 47 */ "MemIncr",
+ /* 48 */ "Gosub",
+ /* 49 */ "AggSet",
+ /* 50 */ "Integer",
+ /* 51 */ "SortNext",
+ /* 52 */ "Prev",
+ /* 53 */ "CreateTable",
+ /* 54 */ "Last",
+ /* 55 */ "IdxRowid",
+ /* 56 */ "ResetCount",
+ /* 57 */ "Callback",
+ /* 58 */ "ContextPush",
+ /* 59 */ "DropTrigger",
+ /* 60 */ "DropIndex",
+ /* 61 */ "IdxGE",
+ /* 62 */ "Or",
+ /* 63 */ "And",
+ /* 64 */ "Not",
+ /* 65 */ "IdxDelete",
+ /* 66 */ "Vacuum",
+ /* 67 */ "MoveLe",
+ /* 68 */ "IsNull",
+ /* 69 */ "NotNull",
+ /* 70 */ "Ne",
+ /* 71 */ "Eq",
+ /* 72 */ "Gt",
+ /* 73 */ "Le",
+ /* 74 */ "Lt",
+ /* 75 */ "Ge",
+ /* 76 */ "IfNot",
+ /* 77 */ "BitAnd",
+ /* 78 */ "BitOr",
+ /* 79 */ "ShiftLeft",
+ /* 80 */ "ShiftRight",
+ /* 81 */ "Add",
+ /* 82 */ "Subtract",
+ /* 83 */ "Multiply",
+ /* 84 */ "Divide",
+ /* 85 */ "Remainder",
+ /* 86 */ "Concat",
+ /* 87 */ "Negative",
+ /* 88 */ "DropTable",
+ /* 89 */ "BitNot",
+ /* 90 */ "String8",
+ /* 91 */ "MakeRecord",
+ /* 92 */ "Delete",
+ /* 93 */ "AggContextPop",
+ /* 94 */ "ListRead",
+ /* 95 */ "ListReset",
+ /* 96 */ "Dup",
+ /* 97 */ "Goto",
+ /* 98 */ "Clear",
+ /* 99 */ "IdxGT",
+ /* 100 */ "MoveLt",
+ /* 101 */ "VerifyCookie",
+ /* 102 */ "Pull",
+ /* 103 */ "SetNumColumns",
+ /* 104 */ "AbsValue",
+ /* 105 */ "Transaction",
+ /* 106 */ "AggGet",
+ /* 107 */ "ContextPop",
+ /* 108 */ "Next",
+ /* 109 */ "AggInit",
+ /* 110 */ "IdxInsert",
+ /* 111 */ "Distinct",
+ /* 112 */ "AggReset",
+ /* 113 */ "Insert",
+ /* 114 */ "Destroy",
+ /* 115 */ "ReadCookie",
+ /* 116 */ "ForceInt",
+ /* 117 */ "OpenPseudo",
+ /* 118 */ "Null",
+ /* 119 */ "Blob",
+ /* 120 */ "MemStore",
+ /* 121 */ "Rewind",
+ /* 122 */ "MoveGe",
+ /* 123 */ "Found",
+ /* 124 */ "NullRow",
+ /* 125 */ "NotUsed_125",
+ /* 126 */ "NotUsed_126",
+ /* 127 */ "NotUsed_127",
+ /* 128 */ "Real",
+ /* 129 */ "HexBlob",
+};
+#endif
diff --git a/src/sqlite/opcodes.h b/src/sqlite/opcodes.h
new file mode 100644
index 0000000..9757cd8
--- /dev/null
+++ b/src/sqlite/opcodes.h
@@ -0,0 +1,144 @@
+/* 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_Column 2
+#define OP_SetCookie 3
+#define OP_IfMemPos 4
+#define OP_Real 128 /* same as TK_FLOAT */
+#define OP_MoveGt 5
+#define OP_Ge 75 /* 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_OpenWrite 9
+#define OP_NotNull 69 /* 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_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_Noop 23
+#define OP_Return 24
+#define OP_Remainder 85 /* same as TK_REM */
+#define OP_NewRowid 25
+#define OP_Multiply 83 /* 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_MustBeInt 36
+#define OP_Halt 37
+#define OP_Rowid 38
+#define OP_IdxLT 39
+#define OP_AddImm 40
+#define OP_Statement 41
+#define OP_RowData 42
+#define OP_MemMax 43
+#define OP_Push 44
+#define OP_Or 62 /* 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_SortNext 51
+#define OP_Prev 52
+#define OP_Concat 86 /* same as TK_CONCAT */
+#define OP_BitAnd 77 /* same as TK_BITAND */
+#define OP_CreateTable 53
+#define OP_Last 54
+#define OP_IsNull 68 /* 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 NOPUSH_MASK_0 65400
+#define NOPUSH_MASK_1 61871
+#define NOPUSH_MASK_2 64446
+#define NOPUSH_MASK_3 65363
+#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_9 0
diff --git a/src/sqlite/os.h b/src/sqlite/os.h
new file mode 100644
index 0000000..4854964
--- /dev/null
+++ b/src/sqlite/os.h
@@ -0,0 +1,202 @@
+/*
+** 2001 September 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 header file (together with is companion C source-code file
+** "os.c") attempt to abstract the underlying operating system so that
+** the SQLite library will work on both POSIX and windows systems.
+*/
+#ifndef _SQLITE_OS_H_
+#define _SQLITE_OS_H_
+
+/*
+** Figure out if we are dealing with Unix, Windows or MacOS.
+**
+** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix.
+** The MacOS build is designed to use CodeWarrior (tested with v8)
+*/
+#if !defined(OS_UNIX) && !defined(OS_TEST) && !defined(OS_OTHER)
+# define OS_OTHER 0
+# ifndef OS_WIN
+# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
+# define OS_WIN 1
+# define OS_UNIX 0
+# else
+# define OS_WIN 0
+# define OS_UNIX 1
+# endif
+# else
+# define OS_UNIX 0
+# endif
+#else
+# ifndef OS_WIN
+# define OS_WIN 0
+# endif
+#endif
+
+/*
+** Invoke the appropriate operating-system specific header file.
+*/
+#if OS_TEST
+# include "os_test.h"
+#endif
+#if OS_UNIX
+# include "os_unix.h"
+#endif
+#if OS_WIN
+# include "os_win.h"
+#endif
+
+/* os_other.c and os_other.h are not delivered with SQLite. These files
+** are place-holders that can be filled in by third-party developers to
+** implement backends to their on proprietary operating systems.
+*/
+#if OS_OTHER
+# include "os_other.h"
+#endif
+
+/* If the SET_FULLSYNC macro is not defined above, then make it
+** a no-op
+*/
+#ifndef SET_FULLSYNC
+# define SET_FULLSYNC(x,y)
+#endif
+
+/*
+** Temporary files are named starting with this prefix followed by 16 random
+** alphanumeric characters, and no file extension. They are stored in the
+** OS's standard temporary file directory, and are deleted prior to exit.
+** If sqlite is being embedded in another program, you may wish to change the
+** prefix to reflect your program's name, so that if your program exits
+** prematurely, old temporary files can be easily identified. This can be done
+** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
+*/
+#ifndef TEMP_FILE_PREFIX
+# define TEMP_FILE_PREFIX "sqlite_"
+#endif
+
+/*
+** The following values may be passed as the second argument to
+** sqlite3OsLock(). The various locks exhibit the following semantics:
+**
+** SHARED: Any number of processes may hold a SHARED lock simultaneously.
+** RESERVED: A single process may hold a RESERVED lock on a file at
+** any time. Other processes may hold and obtain new SHARED locks.
+** PENDING: A single process may hold a PENDING lock on a file at
+** any one time. Existing SHARED locks may persist, but no new
+** SHARED locks may be obtained by other processes.
+** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks.
+**
+** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a
+** process that requests an EXCLUSIVE lock may actually obtain a PENDING
+** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to
+** sqlite3OsLock().
+*/
+#define NO_LOCK 0
+#define SHARED_LOCK 1
+#define RESERVED_LOCK 2
+#define PENDING_LOCK 3
+#define EXCLUSIVE_LOCK 4
+
+/*
+** File Locking Notes: (Mostly about windows but also some info for Unix)
+**
+** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
+** those functions are not available. So we use only LockFile() and
+** UnlockFile().
+**
+** LockFile() prevents not just writing but also reading by other processes.
+** A SHARED_LOCK is obtained by locking a single randomly-chosen
+** byte out of a specific range of bytes. The lock byte is obtained at
+** random so two separate readers can probably access the file at the
+** same time, unless they are unlucky and choose the same lock byte.
+** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range.
+** There can only be one writer. A RESERVED_LOCK is obtained by locking
+** a single byte of the file that is designated as the reserved lock byte.
+** A PENDING_LOCK is obtained by locking a designated byte different from
+** the RESERVED_LOCK byte.
+**
+** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
+** which means we can use reader/writer locks. When reader/writer locks
+** are used, the lock is placed on the same range of bytes that is used
+** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
+** will support two or more Win95 readers or two or more WinNT readers.
+** But a single Win95 reader will lock out all WinNT readers and a single
+** WinNT reader will lock out all other Win95 readers.
+**
+** The following #defines specify the range of bytes used for locking.
+** SHARED_SIZE is the number of bytes available in the pool from which
+** a random byte is selected for a shared lock. The pool of bytes for
+** shared locks begins at SHARED_FIRST.
+**
+** These #defines are available in os.h so that Unix can use the same
+** byte ranges for locking. This leaves open the possiblity of having
+** clients on win95, winNT, and unix all talking to the same shared file
+** and all locking correctly. To do so would require that samba (or whatever
+** tool is being used for file sharing) implements locks correctly between
+** windows and unix. I'm guessing that isn't likely to happen, but by
+** using the same locking range we are at least open to the possibility.
+**
+** Locking in windows is manditory. For this reason, we cannot store
+** actual data in the bytes used for locking. The pager never allocates
+** the pages involved in locking therefore. SHARED_SIZE is selected so
+** that all locks will fit on a single page even at the minimum page size.
+** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE
+** is set high so that we don't have to allocate an unused page except
+** for very large databases. But one should test the page skipping logic
+** by setting PENDING_BYTE low and running the entire regression suite.
+**
+** Changing the value of PENDING_BYTE results in a subtly incompatible
+** file format. Depending on how it is changed, you might not notice
+** the incompatibility right away, even running a full regression test.
+** The default location of PENDING_BYTE is the first byte past the
+** 1GB boundary.
+**
+*/
+#define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */
+/* #define PENDING_BYTE 0x5400 // Page 22 - for testing */
+#define RESERVED_BYTE (PENDING_BYTE+1)
+#define SHARED_FIRST (PENDING_BYTE+2)
+#define SHARED_SIZE 510
+
+
+int sqlite3OsDelete(const char*);
+int sqlite3OsFileExists(const char*);
+int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
+int sqlite3OsOpenExclusive(const char*, OsFile*, int);
+int sqlite3OsOpenReadOnly(const char*, OsFile*);
+int sqlite3OsOpenDirectory(const char*, OsFile*);
+int sqlite3OsSyncDirectory(const char*);
+int sqlite3OsTempFileName(char*);
+int sqlite3OsIsDirWritable(char*);
+int sqlite3OsClose(OsFile*);
+int sqlite3OsRead(OsFile*, void*, int amt);
+int sqlite3OsWrite(OsFile*, const void*, int amt);
+int sqlite3OsSeek(OsFile*, i64 offset);
+int sqlite3OsSync(OsFile*);
+int sqlite3OsTruncate(OsFile*, i64 size);
+int sqlite3OsFileSize(OsFile*, i64 *pSize);
+char *sqlite3OsFullPathname(const char*);
+int sqlite3OsLock(OsFile*, int);
+int sqlite3OsUnlock(OsFile*, int);
+int sqlite3OsCheckReservedLock(OsFile *id);
+
+
+/* The interface for file I/O is above. Other miscellaneous functions
+** are below */
+
+int sqlite3OsRandomSeed(char*);
+int sqlite3OsSleep(int ms);
+int sqlite3OsCurrentTime(double*);
+void sqlite3OsEnterMutex(void);
+void sqlite3OsLeaveMutex(void);
+
+#endif /* _SQLITE_OS_H_ */
diff --git a/src/sqlite/os_common.h b/src/sqlite/os_common.h
new file mode 100644
index 0000000..94311b9
--- /dev/null
+++ b/src/sqlite/os_common.h
@@ -0,0 +1,107 @@
+/*
+** 2004 May 22
+**
+** 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 macros and a little bit of code that is common to
+** all of the platform-specific files (os_*.c) and is #included into those
+** files.
+**
+** This file should be #included by the os_*.c files only. It is not a
+** general purpose header file.
+*/
+
+/*
+** At least two bugs have slipped in because we changed the MEMORY_DEBUG
+** macro to SQLITE_DEBUG and some older makefiles have not yet made the
+** switch. The following code should catch this problem at compile-time.
+*/
+#ifdef MEMORY_DEBUG
+# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
+#endif
+
+
+int sqlite3_os_trace = 0;
+#ifdef SQLITE_DEBUG
+static int last_page = 0;
+#define SEEK(X) last_page=(X)
+#define TRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
+#define TRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
+#define TRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
+#define TRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
+#define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
+#define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
+#define TRACE7(X,Y,Z,A,B,C,D) \
+ if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
+#else
+#define SEEK(X)
+#define TRACE1(X)
+#define TRACE2(X,Y)
+#define TRACE3(X,Y,Z)
+#define TRACE4(X,Y,Z,A)
+#define TRACE5(X,Y,Z,A,B)
+#define TRACE6(X,Y,Z,A,B,C)
+#define TRACE7(X,Y,Z,A,B,C,D)
+#endif
+
+/*
+** Macros for performance tracing. Normally turned off. Only works
+** on i486 hardware.
+*/
+#ifdef SQLITE_PERFORMANCE_TRACE
+__inline__ unsigned long long int hwtime(void){
+ unsigned long long int x;
+ __asm__("rdtsc\n\t"
+ "mov %%edx, %%ecx\n\t"
+ :"=A" (x));
+ return x;
+}
+static unsigned long long int g_start;
+static unsigned int elapse;
+#define TIMER_START g_start=hwtime()
+#define TIMER_END elapse=hwtime()-g_start
+#define TIMER_ELAPSED elapse
+#else
+#define TIMER_START
+#define TIMER_END
+#define TIMER_ELAPSED 0
+#endif
+
+/*
+** If we compile with the SQLITE_TEST macro set, then the following block
+** of code will give us the ability to simulate a disk I/O error. This
+** is used for testing the I/O recovery logic.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_io_error_pending = 0;
+int sqlite3_diskfull_pending = 0;
+#define SimulateIOError(A) \
+ if( sqlite3_io_error_pending ) \
+ if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
+static void local_ioerr(){
+ sqlite3_io_error_pending = 0; /* Really just a place to set a breakpoint */
+}
+#define SimulateDiskfullError \
+ if( sqlite3_diskfull_pending ) \
+ if( sqlite3_diskfull_pending-- == 1 ){ local_ioerr(); return SQLITE_FULL; }
+#else
+#define SimulateIOError(A)
+#define SimulateDiskfullError
+#endif
+
+/*
+** When testing, keep a count of the number of open files.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_open_file_count = 0;
+#define OpenCounter(X) sqlite3_open_file_count+=(X)
+#else
+#define OpenCounter(X)
+#endif
diff --git a/src/sqlite/os_unix.c b/src/sqlite/os_unix.c
new file mode 100644
index 0000000..9c361a1
--- /dev/null
+++ b/src/sqlite/os_unix.c
@@ -0,0 +1,1345 @@
+/*
+** 2004 May 22
+**
+** 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 that is specific to Unix systems.
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#if OS_UNIX /* This file is used on unix only */
+
+
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+
+/*
+** Do not include any of the File I/O interface procedures if the
+** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
+** will be in-memory only)
+*/
+#ifndef SQLITE_OMIT_DISKIO
+
+
+/*
+** Define various macros that are missing from some systems.
+*/
+#ifndef O_LARGEFILE
+# define O_LARGEFILE 0
+#endif
+#ifdef SQLITE_DISABLE_LFS
+# undef O_LARGEFILE
+# define O_LARGEFILE 0
+#endif
+#ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+/*
+** The DJGPP compiler environment looks mostly like Unix, but it
+** lacks the fcntl() system call. So redefine fcntl() to be something
+** that always succeeds. This means that locking does not occur under
+** DJGPP. But its DOS - what did you expect?
+*/
+#ifdef __DJGPP__
+# define fcntl(A,B,C) 0
+#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.
+*/
+#if defined(THREADSAFE) && THREADSAFE
+# include <pthread.h>
+# define SQLITE_UNIX_THREADS 1
+#endif
+
+
+/*
+** Include code that is common to all os_*.c files
+*/
+#include "os_common.h"
+
+#if defined(THREADSAFE) && THREADSAFE && defined(__linux__)
+#define getpid pthread_self
+#endif
+
+/*
+** Here is the dirt on POSIX advisory locks: ANSI STD 1003.1 (1996)
+** section 6.5.2.2 lines 483 through 490 specify that when a process
+** sets or clears a lock, that operation overrides any prior locks set
+** by the same process. It does not explicitly say so, but this implies
+** that it overrides locks set by the same process using a different
+** file descriptor. Consider this test case:
+**
+** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
+** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
+**
+** Suppose ./file1 and ./file2 are really the same file (because
+** one is a hard or symbolic link to the other) then if you set
+** an exclusive lock on fd1, then try to get an exclusive lock
+** on fd2, it works. I would have expected the second lock to
+** fail since there was already a lock on the file due to fd1.
+** But not so. Since both locks came from the same process, the
+** second overrides the first, even though they were on different
+** file descriptors opened on different file names.
+**
+** Bummer. If you ask me, this is broken. Badly broken. It means
+** that we cannot use POSIX locks to synchronize file access among
+** competing threads of the same process. POSIX locks will work fine
+** to synchronize access for threads in separate processes, but not
+** threads within the same process.
+**
+** To work around the problem, SQLite has to manage file locks internally
+** on its own. Whenever a new database is opened, we have to find the
+** specific inode of the database file (the inode is determined by the
+** st_dev and st_ino fields of the stat structure that fstat() fills in)
+** and check for locks already existing on that inode. When locks are
+** created or removed, we have to look at our own internal record of the
+** locks to see if another thread has previously set a lock on that same
+** inode.
+**
+** The OsFile structure for POSIX is no longer just an integer file
+** descriptor. It is now a structure that holds the integer file
+** descriptor and a pointer to a structure that describes the internal
+** locks on the corresponding inode. There is one locking structure
+** per inode, so if the same inode is opened twice, both OsFile structures
+** point to the same locking structure. The locking structure keeps
+** a reference count (so we will know when to delete it) and a "cnt"
+** field that tells us its internal lock status. cnt==0 means the
+** file is unlocked. cnt==-1 means the file has an exclusive lock.
+** cnt>0 means there are cnt shared locks on the file.
+**
+** Any attempt to lock or unlock a file first checks the locking
+** structure. The fcntl() system call is only invoked to set a
+** POSIX lock if the internal lock structure transitions between
+** a locked and an unlocked state.
+**
+** 2004-Jan-11:
+** More recent discoveries about POSIX advisory locks. (The more
+** I discover, the more I realize the a POSIX advisory locks are
+** an abomination.)
+**
+** If you close a file descriptor that points to a file that has locks,
+** all locks on that file that are owned by the current process are
+** released. To work around this problem, each OsFile structure contains
+** a pointer to an openCnt structure. There is one openCnt structure
+** per open inode, which means that multiple OsFiles can point to a single
+** openCnt. When an attempt is made to close an OsFile, if there are
+** other OsFiles open on the same inode that are holding locks, the call
+** to close() the file descriptor is deferred until all of the locks clear.
+** The openCnt structure keeps a list of file descriptors that need to
+** be closed and that list is walked (and cleared) when the last lock
+** clears.
+**
+** First, under Linux threads, because each thread has a separate
+** process ID, lock operations in one thread do not override locks
+** to the same file in other threads. Linux threads behave like
+** separate processes in this respect. But, if you close a file
+** descriptor in linux threads, all locks are cleared, even locks
+** on other threads and even though the other threads have different
+** process IDs. Linux threads is inconsistent in this respect.
+** (I'm beginning to think that linux threads is an abomination too.)
+** The consequence of this all is that the hash table for the lockInfo
+** structure has to include the process id as part of its key because
+** locks in different threads are treated as distinct. But the
+** openCnt structure should not include the process id in its
+** key because close() clears lock on all threads, not just the current
+** thread. Were it not for this goofiness in linux threads, we could
+** combine the lockInfo and openCnt structures into a single structure.
+**
+** 2004-Jun-28:
+** On some versions of linux, threads can override each others locks.
+** On others not. Sometimes you can change the behavior on the same
+** system by setting the LD_ASSUME_KERNEL environment variable. The
+** POSIX standard is silent as to which behavior is correct, as far
+** as I can tell, so other versions of unix might show the same
+** inconsistency. There is no little doubt in my mind that posix
+** advisory locks and linux threads are profoundly broken.
+**
+** To work around the inconsistencies, we have to test at runtime
+** whether or not threads can override each others locks. This test
+** is run once, the first time any lock is attempted. A static
+** variable is set to record the results of this test for future
+** use.
+*/
+
+/*
+** An instance of the following structure serves as the key used
+** to locate a particular lockInfo structure given its inode.
+**
+** If threads cannot override each others locks, then we set the
+** lockKey.tid field to the thread ID. If threads can override
+** each others locks then tid is always set to zero. tid is also
+** set to zero if we compile without threading support.
+*/
+struct lockKey {
+ dev_t dev; /* Device number */
+ ino_t ino; /* Inode number */
+#ifdef SQLITE_UNIX_THREADS
+ pthread_t tid; /* Thread ID or zero if threads cannot override each other */
+#endif
+};
+
+/*
+** An instance of the following structure is allocated for each open
+** inode on each thread with a different process ID. (Threads have
+** different process IDs on linux, but not on most other unixes.)
+**
+** A single inode can have multiple file descriptors, so each OsFile
+** structure contains a pointer to an instance of this object and this
+** object keeps a count of the number of OsFiles pointing to it.
+*/
+struct lockInfo {
+ struct lockKey key; /* The lookup key */
+ int cnt; /* Number of SHARED locks held */
+ int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
+ int nRef; /* Number of pointers to this structure */
+};
+
+/*
+** An instance of the following structure serves as the key used
+** to locate a particular openCnt structure given its inode. This
+** is the same as the lockKey except that the thread ID is omitted.
+*/
+struct openKey {
+ dev_t dev; /* Device number */
+ ino_t ino; /* Inode number */
+};
+
+/*
+** An instance of the following structure is allocated for each open
+** inode. This structure keeps track of the number of locks on that
+** inode. If a close is attempted against an inode that is holding
+** locks, the close is deferred until all locks clear by adding the
+** file descriptor to be closed to the pending list.
+*/
+struct openCnt {
+ struct openKey key; /* The lookup key */
+ int nRef; /* Number of pointers to this structure */
+ int nLock; /* Number of outstanding locks */
+ int nPending; /* Number of pending close() operations */
+ int *aPending; /* Malloced space holding fd's awaiting a close() */
+};
+
+/*
+** These hash table maps inodes and process IDs into lockInfo and openCnt
+** structures. Access to these hash tables must be protected by a mutex.
+*/
+static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
+static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
+
+
+#ifdef SQLITE_UNIX_THREADS
+/*
+** This variable records whether or not threads can override each others
+** locks.
+**
+** 0: No. Threads cannot override each others locks.
+** 1: Yes. Threads can override each others locks.
+** -1: We don't know yet.
+*/
+static int threadsOverrideEachOthersLocks = -1;
+
+/*
+** This structure holds information passed into individual test
+** threads by the testThreadLockingBehavior() routine.
+*/
+struct threadTestData {
+ int fd; /* File to be locked */
+ struct flock lock; /* The locking operation */
+ int result; /* Result of the locking operation */
+};
+
+/*
+** The testThreadLockingBehavior() routine launches two separate
+** threads on this routine. This routine attempts to lock a file
+** descriptor then returns. The success or failure of that attempt
+** allows the testThreadLockingBehavior() procedure to determine
+** whether or not threads can override each others locks.
+*/
+static void *threadLockingTest(void *pArg){
+ struct threadTestData *pData = (struct threadTestData*)pArg;
+ pData->result = fcntl(pData->fd, F_SETLK, &pData->lock);
+ return pArg;
+}
+
+/*
+** This procedure attempts to determine whether or not threads
+** can override each others locks then sets the
+** threadsOverrideEachOthersLocks variable appropriately.
+*/
+static void testThreadLockingBehavior(fd_orig){
+ int fd;
+ struct threadTestData d[2];
+ pthread_t t[2];
+
+ fd = dup(fd_orig);
+ if( fd<0 ) return;
+ memset(d, 0, sizeof(d));
+ d[0].fd = fd;
+ d[0].lock.l_type = F_RDLCK;
+ d[0].lock.l_len = 1;
+ d[0].lock.l_start = 0;
+ d[0].lock.l_whence = SEEK_SET;
+ d[1] = d[0];
+ d[1].lock.l_type = F_WRLCK;
+ pthread_create(&t[0], 0, threadLockingTest, &d[0]);
+ pthread_create(&t[1], 0, threadLockingTest, &d[1]);
+ pthread_join(t[0], 0);
+ pthread_join(t[1], 0);
+ close(fd);
+ threadsOverrideEachOthersLocks = d[0].result==0 && d[1].result==0;
+}
+#endif /* SQLITE_UNIX_THREADS */
+
+/*
+** Release a lockInfo structure previously allocated by findLockInfo().
+*/
+static void releaseLockInfo(struct lockInfo *pLock){
+ pLock->nRef--;
+ if( pLock->nRef==0 ){
+ sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
+ sqliteFree(pLock);
+ }
+}
+
+/*
+** Release a openCnt structure previously allocated by findLockInfo().
+*/
+static void releaseOpenCnt(struct openCnt *pOpen){
+ pOpen->nRef--;
+ if( pOpen->nRef==0 ){
+ sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
+ sqliteFree(pOpen->aPending);
+ sqliteFree(pOpen);
+ }
+}
+
+/*
+** Given a file descriptor, locate lockInfo and openCnt structures that
+** describes that file descriptor. Create a new ones if necessary. The
+** return values might be unset if an error occurs.
+**
+** Return the number of errors.
+*/
+static int findLockInfo(
+ int fd, /* The file descriptor used in the key */
+ struct lockInfo **ppLock, /* Return the lockInfo structure here */
+ struct openCnt **ppOpen /* Return the openCnt structure here */
+){
+ int rc;
+ struct lockKey key1;
+ struct openKey key2;
+ struct stat statbuf;
+ struct lockInfo *pLock;
+ struct openCnt *pOpen;
+ rc = fstat(fd, &statbuf);
+ if( rc!=0 ) return 1;
+ memset(&key1, 0, sizeof(key1));
+ key1.dev = statbuf.st_dev;
+ key1.ino = statbuf.st_ino;
+#ifdef SQLITE_UNIX_THREADS
+ if( threadsOverrideEachOthersLocks<0 ){
+ testThreadLockingBehavior(fd);
+ }
+ key1.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
+#endif
+ memset(&key2, 0, sizeof(key2));
+ key2.dev = statbuf.st_dev;
+ key2.ino = statbuf.st_ino;
+ pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
+ if( pLock==0 ){
+ struct lockInfo *pOld;
+ pLock = sqliteMallocRaw( sizeof(*pLock) );
+ if( pLock==0 ) return 1;
+ pLock->key = key1;
+ pLock->nRef = 1;
+ pLock->cnt = 0;
+ pLock->locktype = 0;
+ pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
+ if( pOld!=0 ){
+ assert( pOld==pLock );
+ sqliteFree(pLock);
+ return 1;
+ }
+ }else{
+ pLock->nRef++;
+ }
+ *ppLock = pLock;
+ pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
+ if( pOpen==0 ){
+ struct openCnt *pOld;
+ pOpen = sqliteMallocRaw( sizeof(*pOpen) );
+ if( pOpen==0 ){
+ releaseLockInfo(pLock);
+ return 1;
+ }
+ pOpen->key = key2;
+ pOpen->nRef = 1;
+ pOpen->nLock = 0;
+ pOpen->nPending = 0;
+ pOpen->aPending = 0;
+ pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
+ if( pOld!=0 ){
+ assert( pOld==pOpen );
+ sqliteFree(pOpen);
+ releaseLockInfo(pLock);
+ return 1;
+ }
+ }else{
+ pOpen->nRef++;
+ }
+ *ppOpen = pOpen;
+ return 0;
+}
+
+/*
+** Delete the named file
+*/
+int sqlite3OsDelete(const char *zFilename){
+ unlink(zFilename);
+ return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the named file exists.
+*/
+int sqlite3OsFileExists(const char *zFilename){
+ return access(zFilename, 0)==0;
+}
+
+/*
+** Attempt to open a file for both reading and writing. If that
+** fails, try opening it read-only. If the file does not exist,
+** try to create it.
+**
+** On success, a handle for the open file is written to *id
+** and *pReadonly is set to 0 if the file was opened for reading and
+** writing or 1 if the file was opened read-only. The function returns
+** SQLITE_OK.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id and *pReadonly unchanged.
+*/
+int sqlite3OsOpenReadWrite(
+ const char *zFilename,
+ OsFile *id,
+ int *pReadonly
+){
+ int rc;
+ assert( !id->isOpen );
+ id->dirfd = -1;
+ id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
+ SQLITE_DEFAULT_FILE_PERMISSIONS);
+ if( id->h<0 ){
+#ifdef EISDIR
+ if( errno==EISDIR ){
+ return SQLITE_CANTOPEN;
+ }
+#endif
+ id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+ if( id->h<0 ){
+ return SQLITE_CANTOPEN;
+ }
+ *pReadonly = 1;
+ }else{
+ *pReadonly = 0;
+ }
+ sqlite3OsEnterMutex();
+ rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
+ sqlite3OsLeaveMutex();
+ if( rc ){
+ close(id->h);
+ return SQLITE_NOMEM;
+ }
+ id->locktype = 0;
+ id->isOpen = 1;
+ TRACE3("OPEN %-3d %s\n", id->h, zFilename);
+ OpenCounter(+1);
+ return SQLITE_OK;
+}
+
+
+/*
+** Attempt to open a new file for exclusive access by this process.
+** The file will be opened for both reading and writing. To avoid
+** a potential security problem, we do not allow the file to have
+** previously existed. Nor do we allow the file to be a symbolic
+** link.
+**
+** If delFlag is true, then make arrangements to automatically delete
+** the file when it is closed.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
+ int rc;
+ assert( !id->isOpen );
+ if( access(zFilename, 0)==0 ){
+ return SQLITE_CANTOPEN;
+ }
+ id->dirfd = -1;
+ id->h = open(zFilename,
+ O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600);
+ if( id->h<0 ){
+ return SQLITE_CANTOPEN;
+ }
+ sqlite3OsEnterMutex();
+ rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
+ sqlite3OsLeaveMutex();
+ if( rc ){
+ close(id->h);
+ unlink(zFilename);
+ return SQLITE_NOMEM;
+ }
+ id->locktype = 0;
+ id->isOpen = 1;
+ if( delFlag ){
+ unlink(zFilename);
+ }
+ TRACE3("OPEN-EX %-3d %s\n", id->h, zFilename);
+ OpenCounter(+1);
+ return SQLITE_OK;
+}
+
+/*
+** Attempt to open a new file for read-only access.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
+ int rc;
+ assert( !id->isOpen );
+ id->dirfd = -1;
+ id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+ if( id->h<0 ){
+ return SQLITE_CANTOPEN;
+ }
+ sqlite3OsEnterMutex();
+ rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
+ sqlite3OsLeaveMutex();
+ if( rc ){
+ close(id->h);
+ return SQLITE_NOMEM;
+ }
+ id->locktype = 0;
+ id->isOpen = 1;
+ TRACE3("OPEN-RO %-3d %s\n", id->h, zFilename);
+ OpenCounter(+1);
+ return SQLITE_OK;
+}
+
+/*
+** Attempt to open a file descriptor for the directory that contains a
+** file. This file descriptor can be used to fsync() the directory
+** in order to make sure the creation of a new file is actually written
+** to disk.
+**
+** This routine is only meaningful for Unix. It is a no-op under
+** windows since windows does not support hard links.
+**
+** On success, a handle for a previously open file is at *id is
+** updated with the new directory file descriptor and SQLITE_OK is
+** returned.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id unchanged.
+*/
+int sqlite3OsOpenDirectory(
+ const char *zDirname,
+ OsFile *id
+){
+ if( !id->isOpen ){
+ /* Do not open the directory if the corresponding file is not already
+ ** open. */
+ return SQLITE_CANTOPEN;
+ }
+ assert( id->dirfd<0 );
+ id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0);
+ if( id->dirfd<0 ){
+ return SQLITE_CANTOPEN;
+ }
+ TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
+ return SQLITE_OK;
+}
+
+/*
+** If the following global variable points to a string which is the
+** name of a directory, then that directory will be used to store
+** temporary files.
+*/
+char *sqlite3_temp_directory = 0;
+
+/*
+** Create a temporary file name in zBuf. zBuf must be big enough to
+** hold at least SQLITE_TEMPNAME_SIZE characters.
+*/
+int sqlite3OsTempFileName(char *zBuf){
+ static const char *azDirs[] = {
+ 0,
+ "/var/tmp",
+ "/usr/tmp",
+ "/tmp",
+ ".",
+ };
+ static const unsigned char zChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789";
+ int i, j;
+ struct stat buf;
+ const char *zDir = ".";
+ azDirs[0] = sqlite3_temp_directory;
+ for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
+ if( azDirs[i]==0 ) continue;
+ if( stat(azDirs[i], &buf) ) continue;
+ if( !S_ISDIR(buf.st_mode) ) continue;
+ if( access(azDirs[i], 07) ) continue;
+ zDir = azDirs[i];
+ break;
+ }
+ do{
+ sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
+ j = strlen(zBuf);
+ sqlite3Randomness(15, &zBuf[j]);
+ for(i=0; i<15; i++, j++){
+ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+ }
+ zBuf[j] = 0;
+ }while( access(zBuf,0)==0 );
+ return SQLITE_OK;
+}
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** Check that a given pathname is a directory and is writable
+**
+*/
+int sqlite3OsIsDirWritable(char *zBuf){
+ struct stat buf;
+ if( zBuf==0 ) return 0;
+ if( zBuf[0]==0 ) return 0;
+ if( stat(zBuf, &buf) ) return 0;
+ if( !S_ISDIR(buf.st_mode) ) return 0;
+ if( access(zBuf, 07) ) return 0;
+ return 1;
+}
+#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
+
+/*
+** Read data from a file into a buffer. Return SQLITE_OK if all
+** bytes were read successfully and SQLITE_IOERR if anything goes
+** wrong.
+*/
+int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
+ int got;
+ assert( id->isOpen );
+ SimulateIOError(SQLITE_IOERR);
+ TIMER_START;
+ got = read(id->h, pBuf, amt);
+ TIMER_END;
+ TRACE5("READ %-3d %5d %7d %d\n", id->h, got, last_page, TIMER_ELAPSED);
+ SEEK(0);
+ /* if( got<0 ) got = 0; */
+ if( got==amt ){
+ return SQLITE_OK;
+ }else{
+ return SQLITE_IOERR;
+ }
+}
+
+/*
+** Write data from a buffer into a file. Return SQLITE_OK on success
+** or some other error code on failure.
+*/
+int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
+ int wrote = 0;
+ assert( id->isOpen );
+ assert( amt>0 );
+ SimulateIOError(SQLITE_IOERR);
+ SimulateDiskfullError;
+ TIMER_START;
+ while( amt>0 && (wrote = write(id->h, pBuf, amt))>0 ){
+ amt -= wrote;
+ pBuf = &((char*)pBuf)[wrote];
+ }
+ TIMER_END;
+ TRACE5("WRITE %-3d %5d %7d %d\n", id->h, wrote, last_page, TIMER_ELAPSED);
+ SEEK(0);
+ if( amt>0 ){
+ return SQLITE_FULL;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Move the read/write pointer in a file.
+*/
+int sqlite3OsSeek(OsFile *id, i64 offset){
+ assert( id->isOpen );
+ SEEK(offset/1024 + 1);
+ lseek(id->h, offset, SEEK_SET);
+ return SQLITE_OK;
+}
+
+#ifdef SQLITE_TEST
+/*
+** Count the number of fullsyncs and normal syncs. This is used to test
+** that syncs and fullsyncs are occuring at the right times.
+*/
+int sqlite3_sync_count = 0;
+int sqlite3_fullsync_count = 0;
+#endif
+
+
+/*
+** The fsync() system call does not work as advertised on many
+** unix systems. The following procedure is an attempt to make
+** it work better.
+**
+** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful
+** for testing when we want to run through the test suite quickly.
+** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
+** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
+** or power failure will likely corrupt the database file.
+*/
+static int full_fsync(int fd, int fullSync){
+ int rc;
+
+ /* Record the number of times that we do a normal fsync() and
+ ** FULLSYNC. This is used during testing to verify that this procedure
+ ** gets called with the correct arguments.
+ */
+#ifdef SQLITE_TEST
+ if( fullSync ) sqlite3_fullsync_count++;
+ sqlite3_sync_count++;
+#endif
+
+ /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
+ ** no-op
+ */
+#ifdef SQLITE_NO_SYNC
+ rc = SQLITE_OK;
+#else
+
+#ifdef F_FULLFSYNC
+ if( fullSync ){
+ rc = fcntl(fd, F_FULLFSYNC, 0);
+ }else{
+ rc = 1;
+ }
+ /* If the FULLSYNC failed, try to do a normal fsync() */
+ if( rc ) rc = fsync(fd);
+
+#else
+ rc = fsync(fd);
+#endif /* defined(F_FULLFSYNC) */
+#endif /* defined(SQLITE_NO_SYNC) */
+
+ return rc;
+}
+
+/*
+** Make sure all writes to a particular file are committed to disk.
+**
+** Under Unix, also make sure that the directory entry for the file
+** has been created by fsync-ing the directory that contains the file.
+** If we do not do this and we encounter a power failure, the directory
+** entry for the journal might not exist after we reboot. The next
+** SQLite to access the file will not know that the journal exists (because
+** the directory entry for the journal was never created) and the transaction
+** will not roll back - possibly leading to database corruption.
+*/
+int sqlite3OsSync(OsFile *id){
+ assert( id->isOpen );
+ SimulateIOError(SQLITE_IOERR);
+ TRACE2("SYNC %-3d\n", id->h);
+ if( full_fsync(id->h, id->fullSync) ){
+ return SQLITE_IOERR;
+ }
+ if( id->dirfd>=0 ){
+ TRACE2("DIRSYNC %-3d\n", id->dirfd);
+ full_fsync(id->dirfd, id->fullSync);
+ close(id->dirfd); /* Only need to sync once, so close the directory */
+ id->dirfd = -1; /* when we are done. */
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Sync the directory zDirname. This is a no-op on operating systems other
+** than UNIX.
+**
+** This is used to make sure the master journal file has truely been deleted
+** before making changes to individual journals on a multi-database commit.
+** The F_FULLFSYNC option is not needed here.
+*/
+int sqlite3OsSyncDirectory(const char *zDirname){
+ int fd;
+ int r;
+ SimulateIOError(SQLITE_IOERR);
+ fd = open(zDirname, O_RDONLY|O_BINARY, 0);
+ TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
+ if( fd<0 ){
+ return SQLITE_CANTOPEN;
+ }
+ r = fsync(fd);
+ close(fd);
+ return ((r==0)?SQLITE_OK:SQLITE_IOERR);
+}
+
+/*
+** Truncate an open file to a specified size
+*/
+int sqlite3OsTruncate(OsFile *id, i64 nByte){
+ assert( id->isOpen );
+ SimulateIOError(SQLITE_IOERR);
+ return ftruncate(id->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
+}
+
+/*
+** Determine the current size of a file in bytes
+*/
+int sqlite3OsFileSize(OsFile *id, i64 *pSize){
+ struct stat buf;
+ assert( id->isOpen );
+ SimulateIOError(SQLITE_IOERR);
+ if( fstat(id->h, &buf)!=0 ){
+ return SQLITE_IOERR;
+ }
+ *pSize = buf.st_size;
+ return SQLITE_OK;
+}
+
+/*
+** This routine checks if there is a RESERVED lock held on the specified
+** file by this or any other process. If such a lock is held, return
+** non-zero. If the file is unlocked or holds only SHARED locks, then
+** return zero.
+*/
+int sqlite3OsCheckReservedLock(OsFile *id){
+ int r = 0;
+
+ assert( id->isOpen );
+ sqlite3OsEnterMutex(); /* Needed because id->pLock is shared across threads */
+
+ /* Check if a thread in this process holds such a lock */
+ if( id->pLock->locktype>SHARED_LOCK ){
+ r = 1;
+ }
+
+ /* Otherwise see if some other process holds it.
+ */
+ if( !r ){
+ struct flock lock;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = RESERVED_BYTE;
+ lock.l_len = 1;
+ lock.l_type = F_WRLCK;
+ fcntl(id->h, F_GETLK, &lock);
+ if( lock.l_type!=F_UNLCK ){
+ r = 1;
+ }
+ }
+
+ sqlite3OsLeaveMutex();
+ TRACE3("TEST WR-LOCK %d %d\n", id->h, r);
+
+ return r;
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** Helper function for printing out trace information from debugging
+** binaries. This returns the string represetation of the supplied
+** integer lock-type.
+*/
+static const char * locktypeName(int locktype){
+ switch( locktype ){
+ case NO_LOCK: return "NONE";
+ case SHARED_LOCK: return "SHARED";
+ case RESERVED_LOCK: return "RESERVED";
+ case PENDING_LOCK: return "PENDING";
+ case EXCLUSIVE_LOCK: return "EXCLUSIVE";
+ }
+ return "ERROR";
+}
+#endif
+
+/*
+** Lock the file with the lock specified by parameter locktype - one
+** of the following:
+**
+** (1) SHARED_LOCK
+** (2) RESERVED_LOCK
+** (3) PENDING_LOCK
+** (4) EXCLUSIVE_LOCK
+**
+** Sometimes when requesting one lock state, additional lock states
+** are inserted in between. The locking might fail on one of the later
+** transitions leaving the lock state different from what it started but
+** still short of its goal. The following chart shows the allowed
+** transitions and the inserted intermediate states:
+**
+** UNLOCKED -> SHARED
+** SHARED -> RESERVED
+** SHARED -> (PENDING) -> EXCLUSIVE
+** RESERVED -> (PENDING) -> EXCLUSIVE
+** PENDING -> EXCLUSIVE
+**
+** This routine will only increase a lock. Use the sqlite3OsUnlock()
+** routine to lower a locking level.
+*/
+int sqlite3OsLock(OsFile *id, int locktype){
+ /* The following describes the implementation of the various locks and
+ ** lock transitions in terms of the POSIX advisory shared and exclusive
+ ** lock primitives (called read-locks and write-locks below, to avoid
+ ** confusion with SQLite lock names). The algorithms are complicated
+ ** slightly in order to be compatible with windows systems simultaneously
+ ** accessing the same database file, in case that is ever required.
+ **
+ ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
+ ** byte', each single bytes at well known offsets, and the 'shared byte
+ ** range', a range of 510 bytes at a well known offset.
+ **
+ ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
+ ** byte'. If this is successful, a random byte from the 'shared byte
+ ** range' is read-locked and the lock on the 'pending byte' released.
+ **
+ ** A process may only obtain a RESERVED lock after it has a SHARED lock.
+ ** A RESERVED lock is implemented by grabbing a write-lock on the
+ ** 'reserved byte'.
+ **
+ ** A process may only obtain a PENDING lock after it has obtained a
+ ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock
+ ** on the 'pending byte'. This ensures that no new SHARED locks can be
+ ** obtained, but existing SHARED locks are allowed to persist. A process
+ ** does not have to obtain a RESERVED lock on the way to a PENDING lock.
+ ** This property is used by the algorithm for rolling back a journal file
+ ** after a crash.
+ **
+ ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is
+ ** implemented by obtaining a write-lock on the entire 'shared byte
+ ** range'. Since all other locks require a read-lock on one of the bytes
+ ** within this range, this ensures that no other locks are held on the
+ ** database.
+ **
+ ** The reason a single byte cannot be used instead of the 'shared byte
+ ** range' is that some versions of windows do not support read-locks. By
+ ** locking a random byte from a range, concurrent SHARED locks may exist
+ ** even if the locking primitive used is always a write-lock.
+ */
+ int rc = SQLITE_OK;
+ struct lockInfo *pLock = id->pLock;
+ struct flock lock;
+ int s;
+
+ assert( id->isOpen );
+ 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 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
+ ** sqlite3OsEnterMutex() hasn't been called yet.
+ */
+ if( id->locktype>=locktype ){
+ TRACE3("LOCK %d %s ok (already held)\n", id->h, locktypeName(locktype));
+ return SQLITE_OK;
+ }
+
+ /* Make sure the locking sequence is correct
+ */
+ assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+ assert( locktype!=PENDING_LOCK );
+ assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
+
+ /* This mutex is needed because id->pLock is shared across threads
+ */
+ sqlite3OsEnterMutex();
+
+ /* If some thread using this PID has a lock via a different OsFile*
+ ** handle that precludes the requested lock, return BUSY.
+ */
+ if( (id->locktype!=pLock->locktype &&
+ (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
+ ){
+ rc = SQLITE_BUSY;
+ goto end_lock;
+ }
+
+ /* If a SHARED lock is requested, and some thread using this PID already
+ ** has a SHARED or RESERVED lock, then increment reference counts and
+ ** return SQLITE_OK.
+ */
+ if( locktype==SHARED_LOCK &&
+ (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
+ assert( locktype==SHARED_LOCK );
+ assert( id->locktype==0 );
+ assert( pLock->cnt>0 );
+ id->locktype = SHARED_LOCK;
+ pLock->cnt++;
+ id->pOpen->nLock++;
+ goto end_lock;
+ }
+
+ lock.l_len = 1L;
+ lock.l_whence = SEEK_SET;
+
+ /* A PENDING lock is needed before acquiring a SHARED lock and before
+ ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
+ ** be released.
+ */
+ if( locktype==SHARED_LOCK
+ || (locktype==EXCLUSIVE_LOCK && id->locktype<PENDING_LOCK)
+ ){
+ lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
+ lock.l_start = PENDING_BYTE;
+ s = fcntl(id->h, F_SETLK, &lock);
+ if( s ){
+ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
+ goto end_lock;
+ }
+ }
+
+
+ /* If control gets to this point, then actually go ahead and make
+ ** operating system calls for the specified lock.
+ */
+ if( locktype==SHARED_LOCK ){
+ assert( pLock->cnt==0 );
+ assert( pLock->locktype==0 );
+
+ /* Now get the read-lock */
+ lock.l_start = SHARED_FIRST;
+ lock.l_len = SHARED_SIZE;
+ s = fcntl(id->h, F_SETLK, &lock);
+
+ /* Drop the temporary PENDING lock */
+ lock.l_start = PENDING_BYTE;
+ lock.l_len = 1L;
+ lock.l_type = F_UNLCK;
+ fcntl(id->h, F_SETLK, &lock);
+ if( s ){
+ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
+ }else{
+ id->locktype = SHARED_LOCK;
+ id->pOpen->nLock++;
+ pLock->cnt = 1;
+ }
+ }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
+ /* We are trying for an exclusive lock but another thread in this
+ ** same process is still holding a shared lock. */
+ rc = SQLITE_BUSY;
+ }else{
+ /* The request was for a RESERVED or EXCLUSIVE lock. It is
+ ** assumed that there is a SHARED or greater lock on the file
+ ** already.
+ */
+ assert( 0!=id->locktype );
+ lock.l_type = F_WRLCK;
+ switch( locktype ){
+ case RESERVED_LOCK:
+ lock.l_start = RESERVED_BYTE;
+ break;
+ case EXCLUSIVE_LOCK:
+ lock.l_start = SHARED_FIRST;
+ lock.l_len = SHARED_SIZE;
+ break;
+ default:
+ assert(0);
+ }
+ s = fcntl(id->h, F_SETLK, &lock);
+ if( s ){
+ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ id->locktype = locktype;
+ pLock->locktype = locktype;
+ }else if( locktype==EXCLUSIVE_LOCK ){
+ id->locktype = PENDING_LOCK;
+ pLock->locktype = PENDING_LOCK;
+ }
+
+end_lock:
+ sqlite3OsLeaveMutex();
+ TRACE4("LOCK %d %s %s\n", id->h, locktypeName(locktype),
+ rc==SQLITE_OK ? "ok" : "failed");
+ return rc;
+}
+
+/*
+** Lower the locking level on file descriptor id to locktype. locktype
+** must be either NO_LOCK or SHARED_LOCK.
+**
+** If the locking level of the file descriptor is already at or below
+** the requested locking level, this routine is a no-op.
+**
+** It is not possible for this routine to fail if the second argument
+** is NO_LOCK. If the second argument is SHARED_LOCK, this routine
+** might return SQLITE_IOERR instead of SQLITE_OK.
+*/
+int sqlite3OsUnlock(OsFile *id, int locktype){
+ struct lockInfo *pLock;
+ struct flock lock;
+ int rc = SQLITE_OK;
+
+ 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());
+
+ assert( locktype<=SHARED_LOCK );
+ if( id->locktype<=locktype ){
+ return SQLITE_OK;
+ }
+ sqlite3OsEnterMutex();
+ pLock = id->pLock;
+ assert( pLock->cnt!=0 );
+ if( id->locktype>SHARED_LOCK ){
+ assert( pLock->locktype==id->locktype );
+ if( locktype==SHARED_LOCK ){
+ lock.l_type = F_RDLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = SHARED_FIRST;
+ lock.l_len = SHARED_SIZE;
+ if( fcntl(id->h, F_SETLK, &lock)!=0 ){
+ /* This should never happen */
+ rc = SQLITE_IOERR;
+ }
+ }
+ lock.l_type = F_UNLCK;
+ 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( locktype==NO_LOCK ){
+ struct openCnt *pOpen;
+
+ /* Decrement the shared lock counter. Release the lock using an
+ ** OS call only when all threads in this same process have released
+ ** the lock.
+ */
+ pLock->cnt--;
+ if( pLock->cnt==0 ){
+ 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;
+ }
+
+ /* Decrement the count of locks against this same file. When the
+ ** count reaches zero, close any other file descriptors whose close
+ ** was deferred because of outstanding locks.
+ */
+ pOpen = id->pOpen;
+ pOpen->nLock--;
+ assert( pOpen->nLock>=0 );
+ if( pOpen->nLock==0 && pOpen->nPending>0 ){
+ int i;
+ for(i=0; i<pOpen->nPending; i++){
+ close(pOpen->aPending[i]);
+ }
+ sqliteFree(pOpen->aPending);
+ pOpen->nPending = 0;
+ pOpen->aPending = 0;
+ }
+ }
+ sqlite3OsLeaveMutex();
+ id->locktype = locktype;
+ return rc;
+}
+
+/*
+** Close a file.
+*/
+int sqlite3OsClose(OsFile *id){
+ if( !id->isOpen ) return SQLITE_OK;
+ sqlite3OsUnlock(id, NO_LOCK);
+ if( id->dirfd>=0 ) close(id->dirfd);
+ id->dirfd = -1;
+ sqlite3OsEnterMutex();
+ if( id->pOpen->nLock ){
+ /* If there are outstanding locks, do not actually close the file just
+ ** yet because that would clear those locks. Instead, add the file
+ ** descriptor to pOpen->aPending. It will be automatically closed when
+ ** the last lock is cleared.
+ */
+ int *aNew;
+ struct openCnt *pOpen = id->pOpen;
+ pOpen->nPending++;
+ aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*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;
+ }
+ }else{
+ /* There are no outstanding locks so we can close the file immediately */
+ close(id->h);
+ }
+ releaseLockInfo(id->pLock);
+ releaseOpenCnt(id->pOpen);
+ sqlite3OsLeaveMutex();
+ id->isOpen = 0;
+ TRACE2("CLOSE %-3d\n", id->h);
+ OpenCounter(-1);
+ return SQLITE_OK;
+}
+
+/*
+** Turn a relative pathname into a full pathname. Return a pointer
+** to the full pathname stored in space obtained from sqliteMalloc().
+** The calling function is responsible for freeing this space once it
+** is no longer needed.
+*/
+char *sqlite3OsFullPathname(const char *zRelative){
+ char *zFull = 0;
+ if( zRelative[0]=='/' ){
+ sqlite3SetString(&zFull, zRelative, (char*)0);
+ }else{
+ char zBuf[5000];
+ zBuf[0] = 0;
+ sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
+ (char*)0);
+ }
+ return zFull;
+}
+
+
+#endif /* SQLITE_OMIT_DISKIO */
+/***************************************************************************
+** Everything above deals with file I/O. Everything that follows deals
+** with other miscellanous aspects of the operating system interface
+****************************************************************************/
+
+
+/*
+** Get information to seed the random number generator. The seed
+** is written into the buffer zBuf[256]. The calling function must
+** supply a sufficiently large buffer.
+*/
+int sqlite3OsRandomSeed(char *zBuf){
+ /* We have to initialize zBuf to prevent valgrind from reporting
+ ** errors. The reports issued by valgrind are incorrect - we would
+ ** prefer that the randomness be increased by making use of the
+ ** uninitialized space in zBuf - but valgrind errors tend to worry
+ ** some users. Rather than argue, it seems easier just to initialize
+ ** the whole array and silence valgrind, even if that means less randomness
+ ** in the random seed.
+ **
+ ** When testing, initializing zBuf[] to zero is all we do. That means
+ ** that we always use the same random number sequence.* This makes the
+ ** tests repeatable.
+ */
+ memset(zBuf, 0, 256);
+#if !defined(SQLITE_TEST)
+ {
+ int pid, fd;
+ fd = open("/dev/urandom", O_RDONLY);
+ if( fd<0 ){
+ time((time_t*)zBuf);
+ pid = getpid();
+ memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
+ }else{
+ read(fd, zBuf, 256);
+ close(fd);
+ }
+ }
+#endif
+ return SQLITE_OK;
+}
+
+/*
+** Sleep for a little while. Return the amount of time slept.
+*/
+int sqlite3OsSleep(int ms){
+#if defined(HAVE_USLEEP) && HAVE_USLEEP
+ usleep(ms*1000);
+ return ms;
+#else
+ sleep((ms+999)/1000);
+ return 1000*((ms+999)/1000);
+#endif
+}
+
+/*
+** Static variables used for thread synchronization
+*/
+static int inMutex = 0;
+#ifdef SQLITE_UNIX_THREADS
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+/*
+** The following pair of routine implement mutual exclusion for
+** multi-threaded processes. Only a single thread is allowed to
+** executed code that is surrounded by EnterMutex() and LeaveMutex().
+**
+** SQLite uses only a single Mutex. There is not much critical
+** code and what little there is executes quickly and without blocking.
+*/
+void sqlite3OsEnterMutex(){
+#ifdef SQLITE_UNIX_THREADS
+ pthread_mutex_lock(&mutex);
+#endif
+ assert( !inMutex );
+ inMutex = 1;
+}
+void sqlite3OsLeaveMutex(){
+ assert( inMutex );
+ inMutex = 0;
+#ifdef SQLITE_UNIX_THREADS
+ pthread_mutex_unlock(&mutex);
+#endif
+}
+
+/*
+** The following variable, if set to a non-zero value, becomes the result
+** returned from sqlite3OsCurrentTime(). This is used for testing.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_current_time = 0;
+#endif
+
+/*
+** Find the current time (in Universal Coordinated Time). Write the
+** current time and date as a Julian Day number into *prNow and
+** return 0. Return 1 if the time and date cannot be found.
+*/
+int sqlite3OsCurrentTime(double *prNow){
+ time_t t;
+ time(&t);
+ *prNow = t/86400.0 + 2440587.5;
+#ifdef SQLITE_TEST
+ if( sqlite3_current_time ){
+ *prNow = sqlite3_current_time/86400.0 + 2440587.5;
+ }
+#endif
+ return 0;
+}
+
+#endif /* OS_UNIX */
diff --git a/src/sqlite/os_unix.h b/src/sqlite/os_unix.h
new file mode 100644
index 0000000..4ea0aee
--- /dev/null
+++ b/src/sqlite/os_unix.h
@@ -0,0 +1,102 @@
+/*
+** 2004 May 22
+**
+** 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 header file defined OS-specific features for Unix.
+*/
+#ifndef _SQLITE_OS_UNIX_H_
+#define _SQLITE_OS_UNIX_H_
+
+/*
+** Helpful hint: To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
+** to the compiler command line.
+*/
+
+/*
+** These #defines should enable >2GB file support on Posix if the
+** underlying operating system supports it. If the OS lacks
+** large file support, or if the OS is windows, these should be no-ops.
+**
+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
+** on the compiler command line. This is necessary if you are compiling
+** on a recent machine (ex: RedHat 7.2) but you want your code to work
+** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
+** without this option, LFS is enable. But LFS does not exist in the kernel
+** in RedHat 6.0, so the code won't work. Hence, for maximum binary
+** portability you should omit LFS.
+**
+** Similar is true for MacOS. LFS is only supported on MacOS 9 and later.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE 1
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+/*
+** standard include files.
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/*
+** The OsFile structure is a operating-system independing representation
+** of an open file handle. It is defined differently for each architecture.
+**
+** This is the definition for Unix.
+**
+** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK,
+** PENDING_LOCK or EXCLUSIVE_LOCK.
+*/
+typedef struct OsFile OsFile;
+struct OsFile {
+ struct Pager *pPager; /* The pager that owns this OsFile. Might be 0 */
+ struct openCnt *pOpen; /* Info about all open fd's on this inode */
+ struct lockInfo *pLock; /* Info about locks on this inode */
+ int h; /* The file descriptor */
+ unsigned char locktype; /* The type of lock held on this fd */
+ unsigned char isOpen; /* True if needs to be closed */
+ unsigned char fullSync; /* Use F_FULLSYNC if available */
+ int dirfd; /* File descriptor for the directory */
+};
+
+/*
+** A macro to set the OsFile.fullSync flag, if it exists.
+*/
+#define SET_FULLSYNC(x,y) ((x).fullSync = (y))
+
+/*
+** Maximum number of characters in a temporary file name
+*/
+#define SQLITE_TEMPNAME_SIZE 200
+
+/*
+** Minimum interval supported by sqlite3OsSleep().
+*/
+#if defined(HAVE_USLEEP) && HAVE_USLEEP
+# define SQLITE_MIN_SLEEP_MS 1
+#else
+# define SQLITE_MIN_SLEEP_MS 1000
+#endif
+
+/*
+** Default permissions when creating a new file
+*/
+#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
+# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
+#endif
+
+
+#endif /* _SQLITE_OS_UNIX_H_ */
diff --git a/src/sqlite/os_win.c b/src/sqlite/os_win.c
new file mode 100644
index 0000000..ea2ca26
--- /dev/null
+++ b/src/sqlite/os_win.c
@@ -0,0 +1,767 @@
+/*
+** 2004 May 22
+**
+** 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 that is specific to windows.
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#if OS_WIN /* This file is used for windows only */
+
+#include <winbase.h>
+
+#ifdef __CYGWIN__
+# include <sys/cygwin.h>
+#endif
+
+/*
+** Macros used to determine whether or not to use threads.
+*/
+#if defined(THREADSAFE) && THREADSAFE
+# define SQLITE_W32_THREADS 1
+#endif
+
+/*
+** Include code that is common to all os_*.c files
+*/
+#include "os_common.h"
+
+/*
+** Do not include any of the File I/O interface procedures if the
+** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
+** will be in-memory only)
+*/
+#ifndef SQLITE_OMIT_DISKIO
+
+/*
+** Delete the named file
+*/
+int sqlite3OsDelete(const char *zFilename){
+ DeleteFileA(zFilename);
+ TRACE2("DELETE \"%s\"\n", zFilename);
+ return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the named file exists.
+*/
+int sqlite3OsFileExists(const char *zFilename){
+ return GetFileAttributesA(zFilename) != 0xffffffff;
+}
+
+/*
+** Attempt to open a file for both reading and writing. If that
+** fails, try opening it read-only. If the file does not exist,
+** try to create it.
+**
+** On success, a handle for the open file is written to *id
+** and *pReadonly is set to 0 if the file was opened for reading and
+** writing or 1 if the file was opened read-only. The function returns
+** SQLITE_OK.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id and *pReadonly unchanged.
+*/
+int sqlite3OsOpenReadWrite(
+ const char *zFilename,
+ OsFile *id,
+ int *pReadonly
+){
+ HANDLE h;
+ assert( !id->isOpen );
+ h = CreateFileA(zFilename,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ h = CreateFileA(zFilename,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ return SQLITE_CANTOPEN;
+ }
+ *pReadonly = 1;
+ }else{
+ *pReadonly = 0;
+ }
+ id->h = h;
+ id->locktype = NO_LOCK;
+ id->sharedLockByte = 0;
+ id->isOpen = 1;
+ OpenCounter(+1);
+ TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
+ return SQLITE_OK;
+}
+
+
+/*
+** Attempt to open a new file for exclusive access by this process.
+** The file will be opened for both reading and writing. To avoid
+** a potential security problem, we do not allow the file to have
+** previously existed. Nor do we allow the file to be a symbolic
+** link.
+**
+** If delFlag is true, then make arrangements to automatically delete
+** the file when it is closed.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
+ HANDLE h;
+ int fileflags;
+ assert( !id->isOpen );
+ if( delFlag ){
+ fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
+ | FILE_FLAG_DELETE_ON_CLOSE;
+ }else{
+ fileflags = FILE_FLAG_RANDOM_ACCESS;
+ }
+ h = CreateFileA(zFilename,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ fileflags,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ return SQLITE_CANTOPEN;
+ }
+ id->h = h;
+ id->locktype = NO_LOCK;
+ id->sharedLockByte = 0;
+ id->isOpen = 1;
+ OpenCounter(+1);
+ TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
+ return SQLITE_OK;
+}
+
+/*
+** Attempt to open a new file for read-only access.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
+ HANDLE h;
+ assert( !id->isOpen );
+ h = CreateFileA(zFilename,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ return SQLITE_CANTOPEN;
+ }
+ id->h = h;
+ id->locktype = NO_LOCK;
+ id->sharedLockByte = 0;
+ id->isOpen = 1;
+ OpenCounter(+1);
+ TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
+ return SQLITE_OK;
+}
+
+/*
+** Attempt to open a file descriptor for the directory that contains a
+** file. This file descriptor can be used to fsync() the directory
+** in order to make sure the creation of a new file is actually written
+** to disk.
+**
+** This routine is only meaningful for Unix. It is a no-op under
+** windows since windows does not support hard links.
+**
+** On success, a handle for a previously open file is at *id is
+** updated with the new directory file descriptor and SQLITE_OK is
+** returned.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id unchanged.
+*/
+int sqlite3OsOpenDirectory(
+ const char *zDirname,
+ OsFile *id
+){
+ return SQLITE_OK;
+}
+
+/*
+** If the following global variable points to a string which is the
+** name of a directory, then that directory will be used to store
+** temporary files.
+*/
+char *sqlite3_temp_directory = 0;
+
+/*
+** Create a temporary file name in zBuf. zBuf must be big enough to
+** hold at least SQLITE_TEMPNAME_SIZE characters.
+*/
+int sqlite3OsTempFileName(char *zBuf){
+ static char zChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789";
+ int i, j;
+ char zTempPath[SQLITE_TEMPNAME_SIZE];
+ if( sqlite3_temp_directory ){
+ strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
+ zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
+ }else{
+ GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
+ }
+ for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
+ zTempPath[i] = 0;
+ for(;;){
+ sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
+ j = strlen(zBuf);
+ sqlite3Randomness(15, &zBuf[j]);
+ for(i=0; i<15; i++, j++){
+ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+ }
+ zBuf[j] = 0;
+ if( !sqlite3OsFileExists(zBuf) ) break;
+ }
+ TRACE2("TEMP FILENAME: %s\n", zBuf);
+ return SQLITE_OK;
+}
+
+/*
+** Close a file.
+*/
+int sqlite3OsClose(OsFile *id){
+ if( id->isOpen ){
+ TRACE2("CLOSE %d\n", id->h);
+ CloseHandle(id->h);
+ OpenCounter(-1);
+ id->isOpen = 0;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Read data from a file into a buffer. Return SQLITE_OK if all
+** bytes were read successfully and SQLITE_IOERR if anything goes
+** wrong.
+*/
+int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
+ DWORD got;
+ assert( id->isOpen );
+ SimulateIOError(SQLITE_IOERR);
+ TRACE3("READ %d lock=%d\n", id->h, id->locktype);
+ if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
+ got = 0;
+ }
+ if( got==(DWORD)amt ){
+ return SQLITE_OK;
+ }else{
+ return SQLITE_IOERR;
+ }
+}
+
+/*
+** Write data from a buffer into a file. Return SQLITE_OK on success
+** or some other error code on failure.
+*/
+int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
+ int rc = 0;
+ DWORD wrote;
+ assert( id->isOpen );
+ SimulateIOError(SQLITE_IOERR);
+ SimulateDiskfullError;
+ TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);
+ assert( amt>0 );
+ while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
+ amt -= wrote;
+ pBuf = &((char*)pBuf)[wrote];
+ }
+ if( !rc || amt>(int)wrote ){
+ return SQLITE_FULL;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Move the read/write pointer in a file.
+*/
+int sqlite3OsSeek(OsFile *id, i64 offset){
+ LONG upperBits = offset>>32;
+ LONG lowerBits = offset & 0xffffffff;
+ DWORD rc;
+ assert( id->isOpen );
+ SEEK(offset/1024 + 1);
+ rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
+ TRACE3("SEEK %d %lld\n", id->h, offset);
+ return SQLITE_OK;
+}
+
+/*
+** Make sure all writes to a particular file are committed to disk.
+*/
+int sqlite3OsSync(OsFile *id){
+ assert( id->isOpen );
+ TRACE3("SYNC %d lock=%d\n", id->h, id->locktype);
+ if( FlushFileBuffers(id->h) ){
+ return SQLITE_OK;
+ }else{
+ return SQLITE_IOERR;
+ }
+}
+
+/*
+** Sync the directory zDirname. This is a no-op on operating systems other
+** than UNIX.
+*/
+int sqlite3OsSyncDirectory(const char *zDirname){
+ SimulateIOError(SQLITE_IOERR);
+ return SQLITE_OK;
+}
+
+/*
+** Truncate an open file to a specified size
+*/
+int sqlite3OsTruncate(OsFile *id, i64 nByte){
+ LONG upperBits = nByte>>32;
+ assert( id->isOpen );
+ TRACE3("TRUNCATE %d %lld\n", id->h, nByte);
+ SimulateIOError(SQLITE_IOERR);
+ SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
+ SetEndOfFile(id->h);
+ return SQLITE_OK;
+}
+
+/*
+** Determine the current size of a file in bytes
+*/
+int sqlite3OsFileSize(OsFile *id, i64 *pSize){
+ DWORD upperBits, lowerBits;
+ assert( id->isOpen );
+ SimulateIOError(SQLITE_IOERR);
+ lowerBits = GetFileSize(id->h, &upperBits);
+ *pSize = (((i64)upperBits)<<32) + lowerBits;
+ return SQLITE_OK;
+}
+
+/*
+** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
+** Return false (zero) for Win95, Win98, or WinME.
+**
+** Here is an interesting observation: Win95, Win98, and WinME lack
+** the LockFileEx() API. But we can still statically link against that
+** API as long as we don't call it win running Win95/98/ME. A call to
+** this routine is used to determine if the host is Win95/98/ME or
+** WinNT/2K/XP so that we will know whether or not we can safely call
+** the LockFileEx() API.
+*/
+static int isNT(void){
+ static int osType = 0; /* 0=unknown 1=win95 2=winNT */
+ if( osType==0 ){
+ OSVERSIONINFO sInfo;
+ sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+ GetVersionEx(&sInfo);
+ osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
+ }
+ return osType==2;
+}
+
+/*
+** Acquire a reader lock.
+** Different API routines are called depending on whether or not this
+** is Win95 or WinNT.
+*/
+static int getReadLock(OsFile *id){
+ int res;
+ if( isNT() ){
+ OVERLAPPED ovlp;
+ ovlp.Offset = SHARED_FIRST;
+ ovlp.OffsetHigh = 0;
+ ovlp.hEvent = 0;
+ res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
+ }else{
+ int lk;
+ sqlite3Randomness(sizeof(lk), &lk);
+ id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
+ res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
+ }
+ return res;
+}
+
+/*
+** Undo a readlock
+*/
+static int unlockReadLock(OsFile *id){
+ int res;
+ if( isNT() ){
+ res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+ }else{
+ res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
+ }
+ return res;
+}
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** Check that a given pathname is a directory and is writable
+**
+*/
+int sqlite3OsIsDirWritable(char *zBuf){
+ int fileAttr;
+ if(! zBuf ) return 0;
+ if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0;
+ fileAttr = GetFileAttributesA(zBuf);
+ if( fileAttr == 0xffffffff ) return 0;
+ if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
+ return 0;
+ }
+ return 1;
+}
+#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
+
+/*
+** Lock the file with the lock specified by parameter locktype - one
+** of the following:
+**
+** (1) SHARED_LOCK
+** (2) RESERVED_LOCK
+** (3) PENDING_LOCK
+** (4) EXCLUSIVE_LOCK
+**
+** Sometimes when requesting one lock state, additional lock states
+** are inserted in between. The locking might fail on one of the later
+** transitions leaving the lock state different from what it started but
+** still short of its goal. The following chart shows the allowed
+** transitions and the inserted intermediate states:
+**
+** UNLOCKED -> SHARED
+** SHARED -> RESERVED
+** SHARED -> (PENDING) -> EXCLUSIVE
+** RESERVED -> (PENDING) -> EXCLUSIVE
+** PENDING -> EXCLUSIVE
+**
+** This routine will only increase a lock. The sqlite3OsUnlock() routine
+** erases all locks at once and returns us immediately to locking level 0.
+** It is not possible to lower the locking level one step at a time. You
+** must go straight to locking level 0.
+*/
+int sqlite3OsLock(OsFile *id, int locktype){
+ int rc = SQLITE_OK; /* Return code from subroutines */
+ int res = 1; /* Result of a windows lock call */
+ int newLocktype; /* Set id->locktype to this value before exiting */
+ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
+
+ assert( id->isOpen );
+ TRACE5("LOCK %d %d was %d(%d)\n",
+ id->h, locktype, id->locktype, id->sharedLockByte);
+
+ /* 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
+ ** sqlite3OsEnterMutex() hasn't been called yet.
+ */
+ if( id->locktype>=locktype ){
+ return SQLITE_OK;
+ }
+
+ /* Make sure the locking sequence is correct
+ */
+ assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+ assert( locktype!=PENDING_LOCK );
+ assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
+
+ /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
+ ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
+ ** the PENDING_LOCK byte is temporary.
+ */
+ newLocktype = id->locktype;
+ if( id->locktype==NO_LOCK
+ || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK)
+ ){
+ int cnt = 3;
+ while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){
+ /* Try 3 times to get the pending lock. The pending lock might be
+ ** held by another reader process who will release it momentarily.
+ */
+ TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
+ Sleep(1);
+ }
+ gotPendingLock = res;
+ }
+
+ /* Acquire a shared lock
+ */
+ if( locktype==SHARED_LOCK && res ){
+ assert( id->locktype==NO_LOCK );
+ res = getReadLock(id);
+ if( res ){
+ newLocktype = SHARED_LOCK;
+ }
+ }
+
+ /* Acquire a RESERVED lock
+ */
+ if( locktype==RESERVED_LOCK && res ){
+ assert( id->locktype==SHARED_LOCK );
+ res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+ if( res ){
+ newLocktype = RESERVED_LOCK;
+ }
+ }
+
+ /* Acquire a PENDING lock
+ */
+ if( locktype==EXCLUSIVE_LOCK && res ){
+ newLocktype = PENDING_LOCK;
+ gotPendingLock = 0;
+ }
+
+ /* Acquire an EXCLUSIVE lock
+ */
+ if( locktype==EXCLUSIVE_LOCK && res ){
+ assert( id->locktype>=SHARED_LOCK );
+ res = unlockReadLock(id);
+ TRACE2("unreadlock = %d\n", res);
+ res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+ if( res ){
+ newLocktype = EXCLUSIVE_LOCK;
+ }else{
+ TRACE2("error-code = %d\n", GetLastError());
+ }
+ }
+
+ /* If we are holding a PENDING lock that ought to be released, then
+ ** release it now.
+ */
+ if( gotPendingLock && locktype==SHARED_LOCK ){
+ UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
+ }
+
+ /* Update the state of the lock has held in the file descriptor then
+ ** return the appropriate result code.
+ */
+ if( res ){
+ rc = SQLITE_OK;
+ }else{
+ TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h,
+ locktype, newLocktype);
+ rc = SQLITE_BUSY;
+ }
+ id->locktype = newLocktype;
+ return rc;
+}
+
+/*
+** This routine checks if there is a RESERVED lock held on the specified
+** file by this or any other process. If such a lock is held, return
+** non-zero, otherwise zero.
+*/
+int sqlite3OsCheckReservedLock(OsFile *id){
+ int rc;
+ assert( id->isOpen );
+ if( id->locktype>=RESERVED_LOCK ){
+ rc = 1;
+ TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc);
+ }else{
+ rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+ if( rc ){
+ UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+ }
+ rc = !rc;
+ TRACE3("TEST WR-LOCK %d %d (remote)\n", id->h, rc);
+ }
+ return rc;
+}
+
+/*
+** Lower the locking level on file descriptor id to locktype. locktype
+** must be either NO_LOCK or SHARED_LOCK.
+**
+** If the locking level of the file descriptor is already at or below
+** the requested locking level, this routine is a no-op.
+**
+** It is not possible for this routine to fail if the second argument
+** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
+** might return SQLITE_IOERR;
+*/
+int sqlite3OsUnlock(OsFile *id, int locktype){
+ int type;
+ int rc = SQLITE_OK;
+ assert( id->isOpen );
+ assert( locktype<=SHARED_LOCK );
+ TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype,
+ id->locktype, id->sharedLockByte);
+ type = id->locktype;
+ if( type>=EXCLUSIVE_LOCK ){
+ UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+ if( locktype==SHARED_LOCK && !getReadLock(id) ){
+ /* This should never happen. We should always be able to
+ ** reacquire the read lock */
+ rc = SQLITE_IOERR;
+ }
+ }
+ if( type>=RESERVED_LOCK ){
+ UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
+ }
+ if( locktype==NO_LOCK && type>=SHARED_LOCK ){
+ unlockReadLock(id);
+ }
+ if( type>=PENDING_LOCK ){
+ UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
+ }
+ id->locktype = locktype;
+ return rc;
+}
+
+/*
+** Turn a relative pathname into a full pathname. Return a pointer
+** to the full pathname stored in space obtained from sqliteMalloc().
+** The calling function is responsible for freeing this space once it
+** is no longer needed.
+*/
+char *sqlite3OsFullPathname(const char *zRelative){
+ char *zNotUsed;
+ char *zFull;
+ int nByte;
+#ifdef __CYGWIN__
+ nByte = strlen(zRelative) + MAX_PATH + 1001;
+ zFull = sqliteMalloc( nByte );
+ if( zFull==0 ) return 0;
+ if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
+#else
+ nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
+ zFull = sqliteMalloc( nByte );
+ if( zFull==0 ) return 0;
+ GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
+#endif
+ return zFull;
+}
+
+#endif /* SQLITE_OMIT_DISKIO */
+/***************************************************************************
+** Everything above deals with file I/O. Everything that follows deals
+** with other miscellanous aspects of the operating system interface
+****************************************************************************/
+
+/*
+** Get information to seed the random number generator. The seed
+** is written into the buffer zBuf[256]. The calling function must
+** supply a sufficiently large buffer.
+*/
+int sqlite3OsRandomSeed(char *zBuf){
+ /* We have to initialize zBuf to prevent valgrind from reporting
+ ** errors. The reports issued by valgrind are incorrect - we would
+ ** prefer that the randomness be increased by making use of the
+ ** uninitialized space in zBuf - but valgrind errors tend to worry
+ ** some users. Rather than argue, it seems easier just to initialize
+ ** the whole array and silence valgrind, even if that means less randomness
+ ** in the random seed.
+ **
+ ** When testing, initializing zBuf[] to zero is all we do. That means
+ ** that we always use the same random number sequence.* This makes the
+ ** tests repeatable.
+ */
+ memset(zBuf, 0, 256);
+ GetSystemTime((LPSYSTEMTIME)zBuf);
+ return SQLITE_OK;
+}
+
+/*
+** Sleep for a little while. Return the amount of time slept.
+*/
+int sqlite3OsSleep(int ms){
+ Sleep(ms);
+ return ms;
+}
+
+/*
+** Static variables used for thread synchronization
+*/
+static int inMutex = 0;
+#ifdef SQLITE_W32_THREADS
+ static CRITICAL_SECTION cs;
+#endif
+
+/*
+** The following pair of routine implement mutual exclusion for
+** multi-threaded processes. Only a single thread is allowed to
+** executed code that is surrounded by EnterMutex() and LeaveMutex().
+**
+** SQLite uses only a single Mutex. There is not much critical
+** code and what little there is executes quickly and without blocking.
+*/
+void sqlite3OsEnterMutex(){
+#ifdef SQLITE_W32_THREADS
+ static int isInit = 0;
+ while( !isInit ){
+ static long lock = 0;
+ if( InterlockedIncrement(&lock)==1 ){
+ InitializeCriticalSection(&cs);
+ isInit = 1;
+ }else{
+ Sleep(1);
+ }
+ }
+ EnterCriticalSection(&cs);
+#endif
+ assert( !inMutex );
+ inMutex = 1;
+}
+void sqlite3OsLeaveMutex(){
+ assert( inMutex );
+ inMutex = 0;
+#ifdef SQLITE_W32_THREADS
+ LeaveCriticalSection(&cs);
+#endif
+}
+
+/*
+** The following variable, if set to a non-zero value, becomes the result
+** returned from sqlite3OsCurrentTime(). This is used for testing.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_current_time = 0;
+#endif
+
+/*
+** Find the current time (in Universal Coordinated Time). Write the
+** current time and date as a Julian Day number into *prNow and
+** return 0. Return 1 if the time and date cannot be found.
+*/
+int sqlite3OsCurrentTime(double *prNow){
+ FILETIME ft;
+ /* FILETIME structure is a 64-bit value representing the number of
+ 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
+ */
+ double now;
+ GetSystemTimeAsFileTime( &ft );
+ now = ((double)ft.dwHighDateTime) * 4294967296.0;
+ *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
+#ifdef SQLITE_TEST
+ if( sqlite3_current_time ){
+ *prNow = sqlite3_current_time/86400.0 + 2440587.5;
+ }
+#endif
+ return 0;
+}
+
+#endif /* OS_WIN */
diff --git a/src/sqlite/os_win.h b/src/sqlite/os_win.h
new file mode 100644
index 0000000..baf937b
--- /dev/null
+++ b/src/sqlite/os_win.h
@@ -0,0 +1,40 @@
+/*
+** 2004 May 22
+**
+** 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 header file defines OS-specific features for Win32
+*/
+#ifndef _SQLITE_OS_WIN_H_
+#define _SQLITE_OS_WIN_H_
+
+#include <windows.h>
+#include <winbase.h>
+
+/*
+** The OsFile structure is a operating-system independing representation
+** of an open file handle. It is defined differently for each architecture.
+**
+** This is the definition for Win32.
+*/
+typedef struct OsFile OsFile;
+struct OsFile {
+ HANDLE h; /* Handle for accessing the file */
+ unsigned char locktype; /* Type of lock currently held on this file */
+ unsigned char isOpen; /* True if needs to be closed */
+ short sharedLockByte; /* Randomly chosen byte used as a shared lock */
+};
+
+
+#define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
+#define SQLITE_MIN_SLEEP_MS 1
+
+
+#endif /* _SQLITE_OS_WIN_H_ */
diff --git a/src/sqlite/pager.c b/src/sqlite/pager.c
new file mode 100644
index 0000000..ef22fd4
--- /dev/null
+++ b/src/sqlite/pager.c
@@ -0,0 +1,3604 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This is the implementation of the page cache subsystem or "pager".
+**
+** The pager is used to access a database disk file. It implements
+** atomic commit and rollback through the use of a journal file that
+** is separate from the database file. The pager also implements file
+** locking to prevent two processes from writing the same database
+** file simultaneously, or one process from reading the database while
+** another is writing.
+**
+** @(#) $Id: pager.c,v 1.1.1.1 2006/02/03 20:35:17 hoganrobert Exp $
+*/
+#ifndef SQLITE_OMIT_DISKIO
+#include "sqliteInt.h"
+#include "os.h"
+#include "pager.h"
+#include <assert.h>
+#include <string.h>
+
+/*
+** Macros for troubleshooting. Normally turned off
+*/
+#if 0
+#define TRACE1(X) sqlite3DebugPrintf(X)
+#define TRACE2(X,Y) sqlite3DebugPrintf(X,Y)
+#define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z)
+#define TRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W)
+#define TRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V)
+#else
+#define TRACE1(X)
+#define TRACE2(X,Y)
+#define TRACE3(X,Y,Z)
+#define TRACE4(X,Y,Z,W)
+#define TRACE5(X,Y,Z,W,V)
+#endif
+
+/*
+** The following two macros are used within the TRACEX() macros above
+** to print out file-descriptors. They are required so that tracing
+** can be turned on when using both the regular os_unix.c and os_test.c
+** backends.
+**
+** PAGERID() takes a pointer to a Pager struct as it's argument. The
+** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
+** struct as it's argument.
+*/
+#ifdef OS_TEST
+#define PAGERID(p) (p->fd->fd.h)
+#define FILEHANDLEID(fd) (fd->fd.h)
+#else
+#define PAGERID(p) (p->fd.h)
+#define FILEHANDLEID(fd) (fd.h)
+#endif
+
+/*
+** The page cache as a whole is always in one of the following
+** states:
+**
+** PAGER_UNLOCK The page cache is not currently reading or
+** writing the database file. There is no
+** data held in memory. This is the initial
+** state.
+**
+** PAGER_SHARED The page cache is reading the database.
+** Writing is not permitted. There can be
+** multiple readers accessing the same database
+** file at the same time.
+**
+** PAGER_RESERVED This process has reserved the database for writing
+** but has not yet made any changes. Only one process
+** at a time can reserve the database. The original
+** database file has not been modified so other
+** processes may still be reading the on-disk
+** database file.
+**
+** PAGER_EXCLUSIVE The page cache is writing the database.
+** Access is exclusive. No other processes or
+** threads can be reading or writing while one
+** process is writing.
+**
+** PAGER_SYNCED The pager moves to this state from PAGER_EXCLUSIVE
+** after all dirty pages have been written to the
+** database file and the file has been synced to
+** disk. All that remains to do is to remove the
+** journal file and the transaction will be
+** committed.
+**
+** The page cache comes up in PAGER_UNLOCK. The first time a
+** sqlite3pager_get() occurs, the state transitions to PAGER_SHARED.
+** After all pages have been released using sqlite_page_unref(),
+** the state transitions back to PAGER_UNLOCK. The first time
+** that sqlite3pager_write() is called, the state transitions to
+** PAGER_RESERVED. (Note that sqlite_page_write() can only be
+** called on an outstanding page which means that the pager must
+** be in PAGER_SHARED before it transitions to PAGER_RESERVED.)
+** The transition to PAGER_EXCLUSIVE occurs when before any changes
+** are made to the database file. After an sqlite3pager_rollback()
+** or sqlite_pager_commit(), the state goes back to PAGER_SHARED.
+*/
+#define PAGER_UNLOCK 0
+#define PAGER_SHARED 1 /* same as SHARED_LOCK */
+#define PAGER_RESERVED 2 /* same as RESERVED_LOCK */
+#define PAGER_EXCLUSIVE 4 /* same as EXCLUSIVE_LOCK */
+#define PAGER_SYNCED 5
+
+/*
+** If the SQLITE_BUSY_RESERVED_LOCK macro is set to true at compile-time,
+** then failed attempts to get a reserved lock will invoke the busy callback.
+** This is off by default. To see why, consider the following scenario:
+**
+** Suppose thread A already has a shared lock and wants a reserved lock.
+** Thread B already has a reserved lock and wants an exclusive lock. If
+** both threads are using their busy callbacks, it might be a long time
+** be for one of the threads give up and allows the other to proceed.
+** But if the thread trying to get the reserved lock gives up quickly
+** (if it never invokes its busy callback) then the contention will be
+** resolved quickly.
+*/
+#ifndef SQLITE_BUSY_RESERVED_LOCK
+# define SQLITE_BUSY_RESERVED_LOCK 0
+#endif
+
+/*
+** This macro rounds values up so that if the value is an address it
+** is guaranteed to be an address that is aligned to an 8-byte boundary.
+*/
+#define FORCE_ALIGNMENT(X) (((X)+7)&~7)
+
+/*
+** Each in-memory image of a page begins with the following header.
+** This header is only visible to this pager module. The client
+** code that calls pager sees only the data that follows the header.
+**
+** Client code should call sqlite3pager_write() on a page prior to making
+** any modifications to that page. The first time sqlite3pager_write()
+** is called, the original page contents are written into the rollback
+** journal and PgHdr.inJournal and PgHdr.needSync are set. Later, once
+** the journal page has made it onto the disk surface, PgHdr.needSync
+** is cleared. The modified page cannot be written back into the original
+** database file until the journal pages has been synced to disk and the
+** PgHdr.needSync has been cleared.
+**
+** The PgHdr.dirty flag is set when sqlite3pager_write() is called and
+** is cleared again when the page content is written back to the original
+** database file.
+*/
+typedef struct PgHdr PgHdr;
+struct PgHdr {
+ Pager *pPager; /* The pager to which this page belongs */
+ Pgno pgno; /* The page number for this page */
+ PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
+ PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */
+ PgHdr *pNextAll; /* A list of all pages */
+ PgHdr *pNextStmt, *pPrevStmt; /* List of pages in the statement journal */
+ u8 inJournal; /* TRUE if has been written to journal */
+ u8 inStmt; /* TRUE if in the statement subjournal */
+ u8 dirty; /* TRUE if we need to write back changes */
+ u8 needSync; /* Sync journal before writing this page */
+ u8 alwaysRollback; /* Disable dont_rollback() for this page */
+ short int nRef; /* Number of users of this page */
+ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */
+#ifdef SQLITE_CHECK_PAGES
+ u32 pageHash;
+#endif
+ /* pPager->pageSize bytes of page data follow this header */
+ /* Pager.nExtra bytes of local data follow the page data */
+};
+
+/*
+** For an in-memory only database, some extra information is recorded about
+** each page so that changes can be rolled back. (Journal files are not
+** used for in-memory databases.) The following information is added to
+** the end of every EXTRA block for in-memory databases.
+**
+** This information could have been added directly to the PgHdr structure.
+** But then it would take up an extra 8 bytes of storage on every PgHdr
+** even for disk-based databases. Splitting it out saves 8 bytes. This
+** is only a savings of 0.8% but those percentages add up.
+*/
+typedef struct PgHistory PgHistory;
+struct PgHistory {
+ u8 *pOrig; /* Original page text. Restore to this on a full rollback */
+ u8 *pStmt; /* Text as it was at the beginning of the current statement */
+};
+
+/*
+** A macro used for invoking the codec if there is one
+*/
+#ifdef SQLITE_HAS_CODEC
+# define CODEC(P,D,N,X) if( P->xCodec ){ P->xCodec(P->pCodecArg,D,N,X); }
+#else
+# define CODEC(P,D,N,X)
+#endif
+
+/*
+** Convert a pointer to a PgHdr into a pointer to its data
+** and back again.
+*/
+#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
+#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
+#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize])
+#define PGHDR_TO_HIST(P,PGR) \
+ ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra])
+
+/*
+** How big to make the hash table used for locating in-memory pages
+** by page number. This macro looks a little silly, but is evaluated
+** at compile-time, not run-time (at least for gcc this is true).
+*/
+#define N_PG_HASH (\
+ (MAX_PAGES>1024)?2048: \
+ (MAX_PAGES>512)?1024: \
+ (MAX_PAGES>256)?512: \
+ (MAX_PAGES>128)?256: \
+ (MAX_PAGES>64)?128:64 \
+)
+
+/*
+** Hash a page number
+*/
+#define pager_hash(PN) ((PN)&(N_PG_HASH-1))
+
+/*
+** A open page cache is an instance of the following structure.
+*/
+struct Pager {
+ u8 journalOpen; /* True if journal file descriptors is valid */
+ u8 journalStarted; /* True if header of journal is synced */
+ u8 useJournal; /* Use a rollback journal on this file */
+ u8 noReadlock; /* Do not bother to obtain readlocks */
+ u8 stmtOpen; /* True if the statement subjournal is open */
+ u8 stmtInUse; /* True we are in a statement subtransaction */
+ u8 stmtAutoopen; /* Open stmt journal when main journal is opened*/
+ u8 noSync; /* Do not sync the journal if true */
+ u8 fullSync; /* Do extra syncs of the journal for robustness */
+ u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
+ u8 errMask; /* One of several kinds of errors */
+ u8 tempFile; /* zFilename is a temporary file */
+ u8 readOnly; /* True for a read-only database */
+ u8 needSync; /* True if an fsync() is needed on the journal */
+ u8 dirtyCache; /* True if cached pages have changed */
+ u8 alwaysRollback; /* Disable dont_rollback() for all pages */
+ u8 memDb; /* True to inhibit all file I/O */
+ u8 setMaster; /* True if a m-j name has been written to jrnl */
+ int dbSize; /* Number of pages in the file */
+ int origDbSize; /* dbSize before the current change */
+ int stmtSize; /* Size of database (in pages) at stmt_begin() */
+ int nRec; /* Number of pages written to the journal */
+ u32 cksumInit; /* Quasi-random value added to every checksum */
+ int stmtNRec; /* Number of records in stmt subjournal */
+ int nExtra; /* Add this many bytes to each in-memory page */
+ int pageSize; /* Number of bytes in a page */
+ int nPage; /* Total number of in-memory pages */
+ int nMaxPage; /* High water mark of nPage */
+ int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
+ int mxPage; /* Maximum number of pages to hold in cache */
+ u8 *aInJournal; /* One bit for each page in the database file */
+ u8 *aInStmt; /* One bit for each page in the database */
+ char *zFilename; /* Name of the database file */
+ char *zJournal; /* Name of the journal file */
+ char *zDirectory; /* Directory hold database and journal files */
+ OsFile fd, jfd; /* File descriptors for database and journal */
+ OsFile stfd; /* File descriptor for the statement subjournal*/
+ BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */
+ PgHdr *pFirst, *pLast; /* List of free pages */
+ PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */
+ PgHdr *pAll; /* List of all pages */
+ PgHdr *pStmt; /* List of pages in the statement subjournal */
+ i64 journalOff; /* Current byte offset in the journal file */
+ i64 journalHdr; /* Byte offset to previous journal header */
+ i64 stmtHdrOff; /* First journal header written this statement */
+ i64 stmtCksum; /* cksumInit when statement was started */
+ i64 stmtJSize; /* Size of journal at stmt_begin() */
+ int sectorSize; /* Assumed sector size during rollback */
+#ifdef SQLITE_TEST
+ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
+ int nRead,nWrite; /* Database pages read/written */
+#endif
+ void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
+ void (*xReiniter)(void*,int); /* Call this routine when reloading pages */
+ void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
+ void *pCodecArg; /* First argument to xCodec() */
+ PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */
+};
+
+/*
+** If SQLITE_TEST is defined then increment the variable given in
+** the argument
+*/
+#ifdef SQLITE_TEST
+# define TEST_INCR(x) x++
+#else
+# define TEST_INCR(x)
+#endif
+
+/*
+** These are bits that can be set in Pager.errMask.
+*/
+#define PAGER_ERR_FULL 0x01 /* a write() failed */
+#define PAGER_ERR_MEM 0x02 /* malloc() failed */
+#define PAGER_ERR_LOCK 0x04 /* error in the locking protocol */
+#define PAGER_ERR_CORRUPT 0x08 /* database or journal corruption */
+#define PAGER_ERR_DISK 0x10 /* general disk I/O error - bad hard drive? */
+
+/*
+** Journal files begin with the following magic string. The data
+** was obtained from /dev/random. It is used only as a sanity check.
+**
+** Since version 2.8.0, the journal format contains additional sanity
+** checking information. If the power fails while the journal is begin
+** written, semi-random garbage data might appear in the journal
+** file after power is restored. If an attempt is then made
+** to roll the journal back, the database could be corrupted. The additional
+** sanity checking data is an attempt to discover the garbage in the
+** journal and ignore it.
+**
+** The sanity checking information for the new journal format consists
+** of a 32-bit checksum on each page of data. The checksum covers both
+** the page number and the pPager->pageSize bytes of data for the page.
+** This cksum is initialized to a 32-bit random value that appears in the
+** journal file right after the header. The random initializer is important,
+** because garbage data that appears at the end of a journal is likely
+** data that was once in other files that have now been deleted. If the
+** garbage data came from an obsolete journal file, the checksums might
+** be correct. But by initializing the checksum to random value which
+** is different for every journal, we minimize that risk.
+*/
+static const unsigned char aJournalMagic[] = {
+ 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
+};
+
+/*
+** The size of the header and of each page in the journal is determined
+** by the following macros.
+*/
+#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8)
+
+/*
+** The journal header size for this pager. In the future, this could be
+** set to some value read from the disk controller. The important
+** characteristic is that it is the same size as a disk sector.
+*/
+#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
+
+/*
+** The macro MEMDB is true if we are dealing with an in-memory database.
+** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
+** the value of MEMDB will be a constant and the compiler will optimize
+** out code that would never execute.
+*/
+#ifdef SQLITE_OMIT_MEMORYDB
+# define MEMDB 0
+#else
+# define MEMDB pPager->memDb
+#endif
+
+/*
+** The default size of a disk sector
+*/
+#define PAGER_SECTOR_SIZE 512
+
+/*
+** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
+** reserved for working around a windows/posix incompatibility). It is
+** used in the journal to signify that the remainder of the journal file
+** is devoted to storing a master journal name - there are no more pages to
+** roll back. See comments for function writeMasterJournal() for details.
+*/
+/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */
+#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)
+
+/*
+** The maximum legal page number is (2^31 - 1).
+*/
+#define PAGER_MAX_PGNO 2147483647
+
+/*
+** Enable reference count tracking (for debugging) here:
+*/
+#ifdef SQLITE_DEBUG
+ int pager3_refinfo_enable = 0;
+ static void pager_refinfo(PgHdr *p){
+ static int cnt = 0;
+ if( !pager3_refinfo_enable ) return;
+ sqlite3DebugPrintf(
+ "REFCNT: %4d addr=%p nRef=%d\n",
+ p->pgno, PGHDR_TO_DATA(p), p->nRef
+ );
+ cnt++; /* Something to set a breakpoint on */
+ }
+# define REFINFO(X) pager_refinfo(X)
+#else
+# define REFINFO(X)
+#endif
+
+/*
+** Read a 32-bit integer from the given file descriptor. Store the integer
+** that is read in *pRes. Return SQLITE_OK if everything worked, or an
+** error code is something goes wrong.
+**
+** All values are stored on disk as big-endian.
+*/
+static int read32bits(OsFile *fd, u32 *pRes){
+ u32 res;
+ int rc;
+ rc = sqlite3OsRead(fd, &res, sizeof(res));
+ if( rc==SQLITE_OK ){
+ unsigned char ac[4];
+ memcpy(ac, &res, 4);
+ res = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
+ }
+ *pRes = res;
+ return rc;
+}
+
+/*
+** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK
+** on success or an error code is something goes wrong.
+*/
+static int write32bits(OsFile *fd, u32 val){
+ unsigned char ac[4];
+ ac[0] = (val>>24) & 0xff;
+ ac[1] = (val>>16) & 0xff;
+ ac[2] = (val>>8) & 0xff;
+ ac[3] = val & 0xff;
+ return sqlite3OsWrite(fd, ac, 4);
+}
+
+/*
+** Write the 32-bit integer 'val' into the page identified by page header
+** 'p' at offset 'offset'.
+*/
+static void store32bits(u32 val, PgHdr *p, int offset){
+ unsigned char *ac;
+ ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
+ ac[0] = (val>>24) & 0xff;
+ ac[1] = (val>>16) & 0xff;
+ ac[2] = (val>>8) & 0xff;
+ ac[3] = val & 0xff;
+}
+
+/*
+** Read a 32-bit integer at offset 'offset' from the page identified by
+** page header 'p'.
+*/
+static u32 retrieve32bits(PgHdr *p, int offset){
+ unsigned char *ac;
+ ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
+ return (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
+}
+
+
+/*
+** Convert the bits in the pPager->errMask into an approprate
+** return code.
+*/
+static int pager_errcode(Pager *pPager){
+ int rc = SQLITE_OK;
+ if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL;
+ if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR;
+ if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL;
+ if( pPager->errMask & PAGER_ERR_MEM ) rc = SQLITE_NOMEM;
+ if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
+ return rc;
+}
+
+#ifdef SQLITE_CHECK_PAGES
+/*
+** Return a 32-bit hash of the page data for pPage.
+*/
+static u32 pager_pagehash(PgHdr *pPage){
+ u32 hash = 0;
+ int i;
+ unsigned char *pData = (unsigned char *)PGHDR_TO_DATA(pPage);
+ for(i=0; i<pPage->pPager->pageSize; i++){
+ hash = (hash+i)^pData[i];
+ }
+ return hash;
+}
+
+/*
+** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
+** is defined, and NDEBUG is not defined, an assert() statement checks
+** that the page is either dirty or still matches the calculated page-hash.
+*/
+#define CHECK_PAGE(x) checkPage(x)
+static void checkPage(PgHdr *pPg){
+ Pager *pPager = pPg->pPager;
+ assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty ||
+ pPg->pageHash==pager_pagehash(pPg) );
+}
+
+#else
+#define CHECK_PAGE(x)
+#endif
+
+/*
+** When this is called the journal file for pager pPager must be open.
+** The master journal file name is read from the end of the file and
+** written into memory obtained from sqliteMalloc(). *pzMaster is
+** set to point at the memory and SQLITE_OK returned. The caller must
+** sqliteFree() *pzMaster.
+**
+** If no master journal file name is present *pzMaster is set to 0 and
+** SQLITE_OK returned.
+*/
+static int readMasterJournal(OsFile *pJrnl, char **pzMaster){
+ int rc;
+ u32 len;
+ i64 szJ;
+ u32 cksum;
+ int i;
+ unsigned char aMagic[8]; /* A buffer to hold the magic header */
+
+ *pzMaster = 0;
+
+ rc = sqlite3OsFileSize(pJrnl, &szJ);
+ if( rc!=SQLITE_OK || szJ<16 ) return rc;
+
+ rc = sqlite3OsSeek(pJrnl, szJ-16);
+ if( rc!=SQLITE_OK ) return rc;
+
+ rc = read32bits(pJrnl, &len);
+ if( rc!=SQLITE_OK ) return rc;
+
+ rc = read32bits(pJrnl, &cksum);
+ if( rc!=SQLITE_OK ) return rc;
+
+ rc = sqlite3OsRead(pJrnl, aMagic, 8);
+ if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc;
+
+ rc = sqlite3OsSeek(pJrnl, szJ-16-len);
+ if( rc!=SQLITE_OK ) return rc;
+
+ *pzMaster = (char *)sqliteMalloc(len+1);
+ if( !*pzMaster ){
+ return SQLITE_NOMEM;
+ }
+ rc = sqlite3OsRead(pJrnl, *pzMaster, len);
+ if( rc!=SQLITE_OK ){
+ sqliteFree(*pzMaster);
+ *pzMaster = 0;
+ return rc;
+ }
+
+ /* See if the checksum matches the master journal name */
+ for(i=0; i<len; i++){
+ cksum -= (*pzMaster)[i];
+ }
+ if( cksum ){
+ /* If the checksum doesn't add up, then one or more of the disk sectors
+ ** containing the master journal filename is corrupted. This means
+ ** definitely roll back, so just return SQLITE_OK and report a (nul)
+ ** master-journal filename.
+ */
+ sqliteFree(*pzMaster);
+ *pzMaster = 0;
+ }else{
+ (*pzMaster)[len] = '\0';
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Seek the journal file descriptor to the next sector boundary where a
+** journal header may be read or written. Pager.journalOff is updated with
+** the new seek offset.
+**
+** i.e for a sector size of 512:
+**
+** Input Offset Output Offset
+** ---------------------------------------
+** 0 0
+** 512 512
+** 100 512
+** 2000 2048
+**
+*/
+static int seekJournalHdr(Pager *pPager){
+ i64 offset = 0;
+ i64 c = pPager->journalOff;
+ if( c ){
+ offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
+ }
+ assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
+ assert( offset>=c );
+ assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
+ pPager->journalOff = offset;
+ return sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
+}
+
+/*
+** The journal file must be open when this routine is called. A journal
+** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
+** current location.
+**
+** The format for the journal header is as follows:
+** - 8 bytes: Magic identifying journal format.
+** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
+** - 4 bytes: Random number used for page hash.
+** - 4 bytes: Initial database page count.
+** - 4 bytes: Sector size used by the process that wrote this journal.
+**
+** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space.
+*/
+static int writeJournalHdr(Pager *pPager){
+
+ int rc = seekJournalHdr(pPager);
+ if( rc ) return rc;
+
+ pPager->journalHdr = pPager->journalOff;
+ if( pPager->stmtHdrOff==0 ){
+ pPager->stmtHdrOff = pPager->journalHdr;
+ }
+ pPager->journalOff += JOURNAL_HDR_SZ(pPager);
+
+ /* FIX ME:
+ **
+ ** Possibly for a pager not in no-sync mode, the journal magic should not
+ ** be written until nRec is filled in as part of next syncJournal().
+ **
+ ** Actually maybe the whole journal header should be delayed until that
+ ** point. Think about this.
+ */
+ rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
+
+ if( rc==SQLITE_OK ){
+ /* The nRec Field. 0xFFFFFFFF for no-sync journals. */
+ rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
+ }
+ if( rc==SQLITE_OK ){
+ /* The random check-hash initialiser */
+ sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
+ rc = write32bits(&pPager->jfd, pPager->cksumInit);
+ }
+ if( rc==SQLITE_OK ){
+ /* The initial database size */
+ rc = write32bits(&pPager->jfd, pPager->dbSize);
+ }
+ if( rc==SQLITE_OK ){
+ /* The assumed sector size for this process */
+ rc = write32bits(&pPager->jfd, pPager->sectorSize);
+ }
+
+ /* The journal header has been written successfully. Seek the journal
+ ** file descriptor to the end of the journal header sector.
+ */
+ if( rc==SQLITE_OK ){
+ sqlite3OsSeek(&pPager->jfd, pPager->journalOff-1);
+ rc = sqlite3OsWrite(&pPager->jfd, "\000", 1);
+ }
+ return rc;
+}
+
+/*
+** The journal file must be open when this is called. A journal header file
+** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
+** file. See comments above function writeJournalHdr() for a description of
+** the journal header format.
+**
+** If the header is read successfully, *nRec is set to the number of
+** page records following this header and *dbSize is set to the size of the
+** database before the transaction began, in pages. Also, pPager->cksumInit
+** is set to the value read from the journal header. SQLITE_OK is returned
+** in this case.
+**
+** If the journal header file appears to be corrupted, SQLITE_DONE is
+** returned and *nRec and *dbSize are not set. If JOURNAL_HDR_SZ bytes
+** cannot be read from the journal file an error code is returned.
+*/
+static int readJournalHdr(
+ Pager *pPager,
+ i64 journalSize,
+ u32 *pNRec,
+ u32 *pDbSize
+){
+ int rc;
+ unsigned char aMagic[8]; /* A buffer to hold the magic header */
+
+ rc = seekJournalHdr(pPager);
+ if( rc ) return rc;
+
+ if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
+ return SQLITE_DONE;
+ }
+
+ rc = sqlite3OsRead(&pPager->jfd, aMagic, sizeof(aMagic));
+ if( rc ) return rc;
+
+ if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
+ return SQLITE_DONE;
+ }
+
+ rc = read32bits(&pPager->jfd, pNRec);
+ if( rc ) return rc;
+
+ rc = read32bits(&pPager->jfd, &pPager->cksumInit);
+ if( rc ) return rc;
+
+ rc = read32bits(&pPager->jfd, pDbSize);
+ if( rc ) return rc;
+
+ /* Update the assumed sector-size to match the value used by
+ ** the process that created this journal. If this journal was
+ ** created by a process other than this one, then this routine
+ ** is being called from within pager_playback(). The local value
+ ** of Pager.sectorSize is restored at the end of that routine.
+ */
+ rc = read32bits(&pPager->jfd, (u32 *)&pPager->sectorSize);
+ if( rc ) return rc;
+
+ pPager->journalOff += JOURNAL_HDR_SZ(pPager);
+ rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
+ return rc;
+}
+
+
+/*
+** Write the supplied master journal name into the journal file for pager
+** pPager at the current location. The master journal name must be the last
+** thing written to a journal file. If the pager is in full-sync mode, the
+** journal file descriptor is advanced to the next sector boundary before
+** anything is written. The format is:
+**
+** + 4 bytes: PAGER_MJ_PGNO.
+** + N bytes: length of master journal name.
+** + 4 bytes: N
+** + 4 bytes: Master journal name checksum.
+** + 8 bytes: aJournalMagic[].
+**
+** The master journal page checksum is the sum of the bytes in the master
+** journal name.
+*/
+static int writeMasterJournal(Pager *pPager, const char *zMaster){
+ int rc;
+ int len;
+ int i;
+ u32 cksum = 0;
+
+ if( !zMaster || pPager->setMaster) return SQLITE_OK;
+ pPager->setMaster = 1;
+
+ len = strlen(zMaster);
+ for(i=0; i<len; i++){
+ cksum += zMaster[i];
+ }
+
+ /* If in full-sync mode, advance to the next disk sector before writing
+ ** the master journal name. This is in case the previous page written to
+ ** the journal has already been synced.
+ */
+ if( pPager->fullSync ){
+ rc = seekJournalHdr(pPager);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ pPager->journalOff += (len+20);
+
+ rc = write32bits(&pPager->jfd, PAGER_MJ_PGNO(pPager));
+ if( rc!=SQLITE_OK ) return rc;
+
+ rc = sqlite3OsWrite(&pPager->jfd, zMaster, len);
+ if( rc!=SQLITE_OK ) return rc;
+
+ rc = write32bits(&pPager->jfd, len);
+ if( rc!=SQLITE_OK ) return rc;
+
+ rc = write32bits(&pPager->jfd, cksum);
+ if( rc!=SQLITE_OK ) return rc;
+
+ rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
+ pPager->needSync = 1;
+ return rc;
+}
+
+/*
+** Add or remove a page from the list of all pages that are in the
+** statement journal.
+**
+** The Pager keeps a separate list of pages that are currently in
+** the statement journal. This helps the sqlite3pager_stmt_commit()
+** routine run MUCH faster for the common case where there are many
+** pages in memory but only a few are in the statement journal.
+*/
+static void page_add_to_stmt_list(PgHdr *pPg){
+ Pager *pPager = pPg->pPager;
+ if( pPg->inStmt ) return;
+ assert( pPg->pPrevStmt==0 && pPg->pNextStmt==0 );
+ pPg->pPrevStmt = 0;
+ if( pPager->pStmt ){
+ pPager->pStmt->pPrevStmt = pPg;
+ }
+ pPg->pNextStmt = pPager->pStmt;
+ pPager->pStmt = pPg;
+ pPg->inStmt = 1;
+}
+static void page_remove_from_stmt_list(PgHdr *pPg){
+ if( !pPg->inStmt ) return;
+ if( pPg->pPrevStmt ){
+ assert( pPg->pPrevStmt->pNextStmt==pPg );
+ pPg->pPrevStmt->pNextStmt = pPg->pNextStmt;
+ }else{
+ assert( pPg->pPager->pStmt==pPg );
+ pPg->pPager->pStmt = pPg->pNextStmt;
+ }
+ if( pPg->pNextStmt ){
+ assert( pPg->pNextStmt->pPrevStmt==pPg );
+ pPg->pNextStmt->pPrevStmt = pPg->pPrevStmt;
+ }
+ pPg->pNextStmt = 0;
+ pPg->pPrevStmt = 0;
+ pPg->inStmt = 0;
+}
+
+/*
+** Find a page in the hash table given its page number. Return
+** a pointer to the page or NULL if not found.
+*/
+static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
+ PgHdr *p = pPager->aHash[pager_hash(pgno)];
+ while( p && p->pgno!=pgno ){
+ p = p->pNextHash;
+ }
+ return p;
+}
+
+/*
+** Unlock the database and clear the in-memory cache. This routine
+** sets the state of the pager back to what it was when it was first
+** opened. Any outstanding pages are invalidated and subsequent attempts
+** to access those pages will likely result in a coredump.
+*/
+static void pager_reset(Pager *pPager){
+ PgHdr *pPg, *pNext;
+ if( pPager->errMask ) return;
+ for(pPg=pPager->pAll; pPg; pPg=pNext){
+ pNext = pPg->pNextAll;
+ sqliteFree(pPg);
+ }
+ pPager->pFirst = 0;
+ pPager->pFirstSynced = 0;
+ pPager->pLast = 0;
+ pPager->pAll = 0;
+ memset(pPager->aHash, 0, sizeof(pPager->aHash));
+ pPager->nPage = 0;
+ if( pPager->state>=PAGER_RESERVED ){
+ sqlite3pager_rollback(pPager);
+ }
+ sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+ pPager->state = PAGER_UNLOCK;
+ pPager->dbSize = -1;
+ pPager->nRef = 0;
+ assert( pPager->journalOpen==0 );
+}
+
+/*
+** This function is used to reset the pager after a malloc() failure. This
+** doesn't work with in-memory databases. If a malloc() fails when an
+** in-memory database is in use it is not possible to recover.
+**
+** If a transaction or statement transaction is active, it is rolled back.
+**
+** It is an error to call this function if any pages are in use.
+*/
+#ifndef SQLITE_OMIT_GLOBALRECOVER
+int sqlite3pager_reset(Pager *pPager){
+ if( pPager ){
+ if( pPager->nRef || MEMDB ){
+ return SQLITE_ERROR;
+ }
+ pPager->errMask &= ~(PAGER_ERR_MEM);
+ pager_reset(pPager);
+ }
+ return SQLITE_OK;
+}
+#endif
+
+
+/*
+** When this routine is called, the pager has the journal file open and
+** a RESERVED or EXCLUSIVE lock on the database. This routine releases
+** the database lock and acquires a SHARED lock in its place. The journal
+** file is deleted and closed.
+**
+** TODO: Consider keeping the journal file open for temporary databases.
+** This might give a performance improvement on windows where opening
+** a file is an expensive operation.
+*/
+static int pager_unwritelock(Pager *pPager){
+ PgHdr *pPg;
+ int rc;
+ assert( !MEMDB );
+ if( pPager->state<PAGER_RESERVED ){
+ return SQLITE_OK;
+ }
+ sqlite3pager_stmt_commit(pPager);
+ if( pPager->stmtOpen ){
+ sqlite3OsClose(&pPager->stfd);
+ pPager->stmtOpen = 0;
+ }
+ if( pPager->journalOpen ){
+ sqlite3OsClose(&pPager->jfd);
+ pPager->journalOpen = 0;
+ sqlite3OsDelete(pPager->zJournal);
+ sqliteFree( pPager->aInJournal );
+ pPager->aInJournal = 0;
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ pPg->inJournal = 0;
+ pPg->dirty = 0;
+ pPg->needSync = 0;
+#ifdef SQLITE_CHECK_PAGES
+ pPg->pageHash = pager_pagehash(pPg);
+#endif
+ }
+ pPager->dirtyCache = 0;
+ pPager->nRec = 0;
+ }else{
+ assert( pPager->aInJournal==0 );
+ assert( pPager->dirtyCache==0 || pPager->useJournal==0 );
+ }
+ rc = sqlite3OsUnlock(&pPager->fd, SHARED_LOCK);
+ pPager->state = PAGER_SHARED;
+ pPager->origDbSize = 0;
+ pPager->setMaster = 0;
+ return rc;
+}
+
+/*
+** Compute and return a checksum for the page of data.
+**
+** This is not a real checksum. It is really just the sum of the
+** random initial value and the page number. We experimented with
+** a checksum of the entire data, but that was found to be too slow.
+**
+** Note that the page number is stored at the beginning of data and
+** the checksum is stored at the end. This is important. If journal
+** corruption occurs due to a power failure, the most likely scenario
+** is that one end or the other of the record will be changed. It is
+** much less likely that the two ends of the journal record will be
+** correct and the middle be corrupt. Thus, this "checksum" scheme,
+** though fast and simple, catches the mostly likely kind of corruption.
+**
+** FIX ME: Consider adding every 200th (or so) byte of the data to the
+** checksum. That way if a single page spans 3 or more disk sectors and
+** only the middle sector is corrupt, we will still have a reasonable
+** chance of failing the checksum and thus detecting the problem.
+*/
+static u32 pager_cksum(Pager *pPager, Pgno pgno, const char *aData){
+ u32 cksum = pPager->cksumInit;
+ int i = pPager->pageSize-200;
+ while( i>0 ){
+ cksum += aData[i];
+ i -= 200;
+ }
+ return cksum;
+}
+
+/*
+** Read a single page from the journal file opened on file descriptor
+** jfd. Playback this one page.
+**
+** If useCksum==0 it means this journal does not use checksums. Checksums
+** are not used in statement journals because statement journals do not
+** need to survive power failures.
+*/
+static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
+ int rc;
+ PgHdr *pPg; /* An existing page in the cache */
+ Pgno pgno; /* The page number of a page in journal */
+ u32 cksum; /* Checksum used for sanity checking */
+ u8 aData[SQLITE_MAX_PAGE_SIZE]; /* Temp storage for a page */
+
+ /* useCksum should be true for the main journal and false for
+ ** statement journals. Verify that this is always the case
+ */
+ assert( jfd == (useCksum ? &pPager->jfd : &pPager->stfd) );
+
+
+ rc = read32bits(jfd, &pgno);
+ if( rc!=SQLITE_OK ) return rc;
+ rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
+ if( rc!=SQLITE_OK ) return rc;
+ pPager->journalOff += pPager->pageSize + 4;
+
+ /* Sanity checking on the page. This is more important that I originally
+ ** thought. If a power failure occurs while the journal is being written,
+ ** it could cause invalid data to be written into the journal. We need to
+ ** detect this invalid data (with high probability) and ignore it.
+ */
+ if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
+ return SQLITE_DONE;
+ }
+ if( pgno>(unsigned)pPager->dbSize ){
+ return SQLITE_OK;
+ }
+ if( useCksum ){
+ rc = read32bits(jfd, &cksum);
+ if( rc ) return rc;
+ pPager->journalOff += 4;
+ if( pager_cksum(pPager, pgno, aData)!=cksum ){
+ return SQLITE_DONE;
+ }
+ }
+
+ assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );
+
+ /* If the pager is in RESERVED state, then there must be a copy of this
+ ** page in the pager cache. In this case just update the pager cache,
+ ** not the database file. The page is left marked dirty in this case.
+ **
+ ** If in EXCLUSIVE state, then we update the pager cache if it exists
+ ** and the main file. The page is then marked not dirty.
+ **
+ ** Ticket #1171: The statement journal might contain page content that is
+ ** different from the page content at the start of the transaction.
+ ** This occurs when a page is changed prior to the start of a statement
+ ** then changed again within the statement. When rolling back such a
+ ** statement we must not write to the original database unless we know
+ ** for certain that original page contents are in the main rollback
+ ** journal. Otherwise, if a full ROLLBACK occurs after the statement
+ ** rollback the full ROLLBACK will not restore the page to its original
+ ** content. Two conditions must be met before writing to the database
+ ** files. (1) the database must be locked. (2) we know that the original
+ ** page content is in the main journal either because the page is not in
+ ** cache or else it is marked as needSync==0.
+ */
+ pPg = pager_lookup(pPager, pgno);
+ assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 );
+ TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno);
+ if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){
+ sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);
+ rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);
+ if( pPg ) pPg->dirty = 0;
+ }
+ if( pPg ){
+ /* No page should ever be explicitly rolled back that is in use, except
+ ** for page 1 which is held in use in order to keep the lock on the
+ ** database active. However such a page may be rolled back as a result
+ ** of an internal error resulting in an automatic call to
+ ** sqlite3pager_rollback().
+ */
+ void *pData;
+ /* assert( pPg->nRef==0 || pPg->pgno==1 ); */
+ pData = PGHDR_TO_DATA(pPg);
+ memcpy(pData, aData, pPager->pageSize);
+ if( pPager->xDestructor ){ /*** FIX ME: Should this be xReinit? ***/
+ pPager->xDestructor(pData, pPager->pageSize);
+ }
+#ifdef SQLITE_CHECK_PAGES
+ pPg->pageHash = pager_pagehash(pPg);
+#endif
+ CODEC(pPager, pData, pPg->pgno, 3);
+ }
+ return rc;
+}
+
+/*
+** Parameter zMaster is the name of a master journal file. A single journal
+** file that referred to the master journal file has just been rolled back.
+** This routine checks if it is possible to delete the master journal file,
+** and does so if it is.
+**
+** The master journal file contains the names of all child journals.
+** To tell if a master journal can be deleted, check to each of the
+** children. If all children are either missing or do not refer to
+** a different master journal, then this master journal can be deleted.
+*/
+static int pager_delmaster(const char *zMaster){
+ int rc;
+ int master_open = 0;
+ OsFile master;
+ char *zMasterJournal = 0; /* Contents of master journal file */
+ i64 nMasterJournal; /* Size of master journal file */
+
+ /* Open the master journal file exclusively in case some other process
+ ** is running this routine also. Not that it makes too much difference.
+ */
+ memset(&master, 0, sizeof(master));
+ rc = sqlite3OsOpenReadOnly(zMaster, &master);
+ if( rc!=SQLITE_OK ) goto delmaster_out;
+ master_open = 1;
+ rc = sqlite3OsFileSize(&master, &nMasterJournal);
+ if( rc!=SQLITE_OK ) goto delmaster_out;
+
+ if( nMasterJournal>0 ){
+ char *zJournal;
+ char *zMasterPtr = 0;
+
+ /* Load the entire master journal file into space obtained from
+ ** sqliteMalloc() and pointed to by zMasterJournal.
+ */
+ zMasterJournal = (char *)sqliteMalloc(nMasterJournal);
+ if( !zMasterJournal ){
+ rc = SQLITE_NOMEM;
+ goto delmaster_out;
+ }
+ rc = sqlite3OsRead(&master, zMasterJournal, nMasterJournal);
+ if( rc!=SQLITE_OK ) goto delmaster_out;
+
+ zJournal = zMasterJournal;
+ while( (zJournal-zMasterJournal)<nMasterJournal ){
+ if( sqlite3OsFileExists(zJournal) ){
+ /* One of the journals pointed to by the master journal exists.
+ ** Open it and check if it points at the master journal. If
+ ** so, return without deleting the master journal file.
+ */
+ OsFile journal;
+ int c;
+
+ memset(&journal, 0, sizeof(journal));
+ rc = sqlite3OsOpenReadOnly(zJournal, &journal);
+ if( rc!=SQLITE_OK ){
+ goto delmaster_out;
+ }
+
+ rc = readMasterJournal(&journal, &zMasterPtr);
+ sqlite3OsClose(&journal);
+ if( rc!=SQLITE_OK ){
+ goto delmaster_out;
+ }
+
+ c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0;
+ sqliteFree(zMasterPtr);
+ if( c ){
+ /* We have a match. Do not delete the master journal file. */
+ goto delmaster_out;
+ }
+ }
+ zJournal += (strlen(zJournal)+1);
+ }
+ }
+
+ sqlite3OsDelete(zMaster);
+
+delmaster_out:
+ if( zMasterJournal ){
+ sqliteFree(zMasterJournal);
+ }
+ if( master_open ){
+ sqlite3OsClose(&master);
+ }
+ return rc;
+}
+
+/*
+** Make every page in the cache agree with what is on disk. In other words,
+** reread the disk to reset the state of the cache.
+**
+** This routine is called after a rollback in which some of the dirty cache
+** pages had never been written out to disk. We need to roll back the
+** cache content and the easiest way to do that is to reread the old content
+** back from the disk.
+*/
+static int pager_reload_cache(Pager *pPager){
+ PgHdr *pPg;
+ int rc = SQLITE_OK;
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ char zBuf[SQLITE_MAX_PAGE_SIZE];
+ if( !pPg->dirty ) continue;
+ if( (int)pPg->pgno <= pPager->origDbSize ){
+ sqlite3OsSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));
+ rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
+ TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
+ if( rc ) break;
+ CODEC(pPager, zBuf, pPg->pgno, 2);
+ }else{
+ memset(zBuf, 0, pPager->pageSize);
+ }
+ if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
+ memcpy(PGHDR_TO_DATA(pPg), zBuf, pPager->pageSize);
+ if( pPager->xReiniter ){
+ pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize);
+ }else{
+ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
+ }
+ }
+ pPg->needSync = 0;
+ pPg->dirty = 0;
+#ifdef SQLITE_CHECK_PAGES
+ pPg->pageHash = pager_pagehash(pPg);
+#endif
+ }
+ return rc;
+}
+
+/*
+** Truncate the main file of the given pager to the number of pages
+** indicated.
+*/
+static int pager_truncate(Pager *pPager, int nPage){
+ assert( pPager->state>=PAGER_EXCLUSIVE );
+ return sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(i64)nPage);
+}
+
+/*
+** Playback the journal and thus restore the database file to
+** the state it was in before we started making changes.
+**
+** The journal file format is as follows:
+**
+** (1) 8 byte prefix. A copy of aJournalMagic[].
+** (2) 4 byte big-endian integer which is the number of valid page records
+** in the journal. If this value is 0xffffffff, then compute the
+** number of page records from the journal size.
+** (3) 4 byte big-endian integer which is the initial value for the
+** sanity checksum.
+** (4) 4 byte integer which is the number of pages to truncate the
+** database to during a rollback.
+** (5) 4 byte integer which is the number of bytes in the master journal
+** name. The value may be zero (indicate that there is no master
+** journal.)
+** (6) N bytes of the master journal name. The name will be nul-terminated
+** and might be shorter than the value read from (5). If the first byte
+** of the name is \000 then there is no master journal. The master
+** journal name is stored in UTF-8.
+** (7) Zero or more pages instances, each as follows:
+** + 4 byte page number.
+** + pPager->pageSize bytes of data.
+** + 4 byte checksum
+**
+** When we speak of the journal header, we mean the first 6 items above.
+** Each entry in the journal is an instance of the 7th item.
+**
+** Call the value from the second bullet "nRec". nRec is the number of
+** valid page entries in the journal. In most cases, you can compute the
+** value of nRec from the size of the journal file. But if a power
+** failure occurred while the journal was being written, it could be the
+** case that the size of the journal file had already been increased but
+** the extra entries had not yet made it safely to disk. In such a case,
+** the value of nRec computed from the file size would be too large. For
+** that reason, we always use the nRec value in the header.
+**
+** If the nRec value is 0xffffffff it means that nRec should be computed
+** from the file size. This value is used when the user selects the
+** no-sync option for the journal. A power failure could lead to corruption
+** in this case. But for things like temporary table (which will be
+** deleted when the power is restored) we don't care.
+**
+** If the file opened as the journal file is not a well-formed
+** journal file then all pages up to the first corrupted page are rolled
+** back (or no pages if the journal header is corrupted). The journal file
+** is then deleted and SQLITE_OK returned, just as if no corruption had
+** been encountered.
+**
+** If an I/O or malloc() error occurs, the journal-file is not deleted
+** and an error code is returned.
+*/
+static int pager_playback(Pager *pPager){
+ i64 szJ; /* Size of the journal file in bytes */
+ u32 nRec; /* Number of Records in the journal */
+ int i; /* Loop counter */
+ Pgno mxPg = 0; /* Size of the original file in pages */
+ int rc; /* Result code of a subroutine */
+ char *zMaster = 0; /* Name of master journal file if any */
+
+ /* Figure out how many records are in the journal. Abort early if
+ ** the journal is empty.
+ */
+ assert( pPager->journalOpen );
+ rc = sqlite3OsFileSize(&pPager->jfd, &szJ);
+ if( rc!=SQLITE_OK ){
+ goto end_playback;
+ }
+
+ /* Read the master journal name from the journal, if it is present.
+ ** If a master journal file name is specified, but the file is not
+ ** present on disk, then the journal is not hot and does not need to be
+ ** played back.
+ */
+ rc = readMasterJournal(&pPager->jfd, &zMaster);
+ assert( rc!=SQLITE_DONE );
+ if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){
+ sqliteFree(zMaster);
+ zMaster = 0;
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ goto end_playback;
+ }
+ sqlite3OsSeek(&pPager->jfd, 0);
+ pPager->journalOff = 0;
+
+ /* This loop terminates either when the readJournalHdr() call returns
+ ** SQLITE_DONE or an IO error occurs. */
+ while( 1 ){
+
+ /* Read the next journal header from the journal file. If there are
+ ** not enough bytes left in the journal file for a complete header, or
+ ** it is corrupted, then a process must of failed while writing it.
+ ** This indicates nothing more needs to be rolled back.
+ */
+ rc = readJournalHdr(pPager, szJ, &nRec, &mxPg);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_DONE ){
+ rc = SQLITE_OK;
+ }
+ goto end_playback;
+ }
+
+ /* If nRec is 0xffffffff, then this journal was created by a process
+ ** working in no-sync mode. This means that the rest of the journal
+ ** file consists of pages, there are no more journal headers. Compute
+ ** the value of nRec based on this assumption.
+ */
+ if( nRec==0xffffffff ){
+ assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
+ nRec = (szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager);
+ }
+
+ /* If this is the first header read from the journal, truncate the
+ ** database file back to it's original size.
+ */
+ if( pPager->state>=PAGER_EXCLUSIVE &&
+ pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
+ assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
+ rc = pager_truncate(pPager, mxPg);
+ if( rc!=SQLITE_OK ){
+ goto end_playback;
+ }
+ pPager->dbSize = mxPg;
+ }
+
+ /* rc = sqlite3OsSeek(&pPager->jfd, JOURNAL_HDR_SZ(pPager)); */
+ if( rc!=SQLITE_OK ) goto end_playback;
+
+ /* Copy original pages out of the journal and back into the database file.
+ */
+ for(i=0; i<nRec; i++){
+ rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_DONE ){
+ rc = SQLITE_OK;
+ pPager->journalOff = szJ;
+ break;
+ }else{
+ goto end_playback;
+ }
+ }
+ }
+ }
+
+ /* Pages that have been written to the journal but never synced
+ ** where not restored by the loop above. We have to restore those
+ ** pages by reading them back from the original database.
+ */
+ assert( rc==SQLITE_OK );
+ pager_reload_cache(pPager);
+
+end_playback:
+ if( rc==SQLITE_OK ){
+ rc = pager_unwritelock(pPager);
+ }
+ if( zMaster ){
+ /* If there was a master journal and this routine will return true,
+ ** see if it is possible to delete the master journal.
+ */
+ if( rc==SQLITE_OK ){
+ rc = pager_delmaster(zMaster);
+ }
+ sqliteFree(zMaster);
+ }
+
+ /* The Pager.sectorSize variable may have been updated while rolling
+ ** back a journal created by a process with a different PAGER_SECTOR_SIZE
+ ** value. Reset it to the correct value for this process.
+ */
+ pPager->sectorSize = PAGER_SECTOR_SIZE;
+ return rc;
+}
+
+/*
+** Playback the statement journal.
+**
+** This is similar to playing back the transaction journal but with
+** a few extra twists.
+**
+** (1) The number of pages in the database file at the start of
+** the statement is stored in pPager->stmtSize, not in the
+** journal file itself.
+**
+** (2) In addition to playing back the statement journal, also
+** playback all pages of the transaction journal beginning
+** at offset pPager->stmtJSize.
+*/
+static int pager_stmt_playback(Pager *pPager){
+ i64 szJ; /* Size of the full journal */
+ i64 hdrOff;
+ int nRec; /* Number of Records */
+ int i; /* Loop counter */
+ int rc;
+
+ szJ = pPager->journalOff;
+#ifndef NDEBUG
+ {
+ i64 os_szJ;
+ rc = sqlite3OsFileSize(&pPager->jfd, &os_szJ);
+ if( rc!=SQLITE_OK ) return rc;
+ assert( szJ==os_szJ );
+ }
+#endif
+
+ /* Set hdrOff to be the offset to the first journal header written
+ ** this statement transaction, or the end of the file if no journal
+ ** header was written.
+ */
+ hdrOff = pPager->stmtHdrOff;
+ assert( pPager->fullSync || !hdrOff );
+ if( !hdrOff ){
+ hdrOff = szJ;
+ }
+
+ /* Truncate the database back to its original size.
+ */
+ if( pPager->state>=PAGER_EXCLUSIVE ){
+ rc = pager_truncate(pPager, pPager->stmtSize);
+ }
+ pPager->dbSize = pPager->stmtSize;
+
+ /* Figure out how many records are in the statement journal.
+ */
+ assert( pPager->stmtInUse && pPager->journalOpen );
+ sqlite3OsSeek(&pPager->stfd, 0);
+ nRec = pPager->stmtNRec;
+
+ /* Copy original pages out of the statement journal and back into the
+ ** database file. Note that the statement journal omits checksums from
+ ** each record since power-failure recovery is not important to statement
+ ** journals.
+ */
+ for(i=nRec-1; i>=0; i--){
+ rc = pager_playback_one_page(pPager, &pPager->stfd, 0);
+ assert( rc!=SQLITE_DONE );
+ if( rc!=SQLITE_OK ) goto end_stmt_playback;
+ }
+
+ /* Now roll some pages back from the transaction journal. Pager.stmtJSize
+ ** was the size of the journal file when this statement was started, so
+ ** everything after that needs to be rolled back, either into the
+ ** database, the memory cache, or both.
+ **
+ ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
+ ** of the first journal header written during this statement transaction.
+ */
+ rc = sqlite3OsSeek(&pPager->jfd, pPager->stmtJSize);
+ if( rc!=SQLITE_OK ){
+ goto end_stmt_playback;
+ }
+ pPager->journalOff = pPager->stmtJSize;
+ pPager->cksumInit = pPager->stmtCksum;
+ assert( JOURNAL_HDR_SZ(pPager)<(pPager->pageSize+8) );
+ while( pPager->journalOff <= (hdrOff-(pPager->pageSize+8)) ){
+ rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
+ assert( rc!=SQLITE_DONE );
+ if( rc!=SQLITE_OK ) goto end_stmt_playback;
+ }
+
+ while( pPager->journalOff < szJ ){
+ u32 nRec;
+ u32 dummy;
+ rc = readJournalHdr(pPager, szJ, &nRec, &dummy);
+ if( rc!=SQLITE_OK ){
+ assert( rc!=SQLITE_DONE );
+ goto end_stmt_playback;
+ }
+ if( nRec==0 ){
+ nRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
+ }
+ for(i=nRec-1; i>=0 && pPager->journalOff < szJ; i--){
+ rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
+ assert( rc!=SQLITE_DONE );
+ if( rc!=SQLITE_OK ) goto end_stmt_playback;
+ }
+ }
+
+ pPager->journalOff = szJ;
+
+end_stmt_playback:
+ if( rc!=SQLITE_OK ){
+ pPager->errMask |= PAGER_ERR_CORRUPT;
+ rc = SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ }else{
+ pPager->journalOff = szJ;
+ /* pager_reload_cache(pPager); */
+ }
+ return rc;
+}
+
+/*
+** Change the maximum number of in-memory pages that are allowed.
+*/
+void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
+ if( mxPage>10 ){
+ pPager->mxPage = mxPage;
+ }else{
+ pPager->mxPage = 10;
+ }
+}
+
+/*
+** Adjust the robustness of the database to damage due to OS crashes
+** or power failures by changing the number of syncs()s when writing
+** the rollback journal. There are three levels:
+**
+** OFF sqlite3OsSync() is never called. This is the default
+** for temporary and transient files.
+**
+** NORMAL The journal is synced once before writes begin on the
+** database. This is normally adequate protection, but
+** it is theoretically possible, though very unlikely,
+** that an inopertune power failure could leave the journal
+** in a state which would cause damage to the database
+** when it is rolled back.
+**
+** FULL The journal is synced twice before writes begin on the
+** database (with some additional information - the nRec field
+** of the journal header - being written in between the two
+** syncs). If we assume that writing a
+** single disk sector is atomic, then this mode provides
+** assurance that the journal will not be corrupted to the
+** point of causing damage to the database during rollback.
+**
+** Numeric values associated with these states are OFF==1, NORMAL=2,
+** and FULL=3.
+*/
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+void sqlite3pager_set_safety_level(Pager *pPager, int level){
+ pPager->noSync = level==1 || pPager->tempFile;
+ pPager->fullSync = level==3 && !pPager->tempFile;
+ if( pPager->noSync ) pPager->needSync = 0;
+}
+#endif
+
+/*
+** The following global variable is incremented whenever the library
+** attempts to open a temporary file. This information is used for
+** testing and analysis only.
+*/
+int sqlite3_opentemp_count = 0;
+
+/*
+** Open a temporary file. Write the name of the file into zFile
+** (zFile must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write
+** the file descriptor into *fd. Return SQLITE_OK on success or some
+** other error code if we fail.
+**
+** The OS will automatically delete the temporary file when it is
+** closed.
+*/
+static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
+ int cnt = 8;
+ int rc;
+ sqlite3_opentemp_count++; /* Used for testing and analysis only */
+ do{
+ cnt--;
+ sqlite3OsTempFileName(zFile);
+ rc = sqlite3OsOpenExclusive(zFile, fd, 1);
+ }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
+ return rc;
+}
+
+/*
+** Create a new page cache and put a pointer to the page cache in *ppPager.
+** The file to be cached need not exist. The file is not locked until
+** the first call to sqlite3pager_get() and is only held open until the
+** last page is released using sqlite3pager_unref().
+**
+** If zFilename is NULL then a randomly-named temporary file is created
+** and used as the file to be cached. The file will be deleted
+** automatically when it is closed.
+**
+** If zFilename is ":memory:" then all information is held in cache.
+** It is never written to disk. This can be used to implement an
+** in-memory database.
+*/
+int sqlite3pager_open(
+ Pager **ppPager, /* Return the Pager structure here */
+ const char *zFilename, /* Name of the database file to open */
+ int nExtra, /* Extra bytes append to each in-memory page */
+ int flags /* flags controlling this file */
+){
+ Pager *pPager;
+ char *zFullPathname = 0;
+ int nameLen;
+ OsFile fd;
+ int rc = SQLITE_OK;
+ int i;
+ int tempFile = 0;
+ int memDb = 0;
+ int readOnly = 0;
+ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
+ int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
+ char zTemp[SQLITE_TEMPNAME_SIZE];
+
+ *ppPager = 0;
+ memset(&fd, 0, sizeof(fd));
+ if( sqlite3_malloc_failed ){
+ return SQLITE_NOMEM;
+ }
+ if( zFilename && zFilename[0] ){
+#ifndef SQLITE_OMIT_MEMORYDB
+ if( strcmp(zFilename,":memory:")==0 ){
+ memDb = 1;
+ zFullPathname = sqliteStrDup("");
+ rc = SQLITE_OK;
+ }else
+#endif
+ {
+ zFullPathname = sqlite3OsFullPathname(zFilename);
+ if( zFullPathname ){
+ rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
+ }
+ }
+ }else{
+ rc = sqlite3pager_opentemp(zTemp, &fd);
+ zFilename = zTemp;
+ zFullPathname = sqlite3OsFullPathname(zFilename);
+ if( rc==SQLITE_OK ){
+ tempFile = 1;
+ }
+ }
+ if( !zFullPathname ){
+ sqlite3OsClose(&fd);
+ return SQLITE_NOMEM;
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3OsClose(&fd);
+ sqliteFree(zFullPathname);
+ return rc;
+ }
+ nameLen = strlen(zFullPathname);
+ pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
+ if( pPager==0 ){
+ sqlite3OsClose(&fd);
+ sqliteFree(zFullPathname);
+ return SQLITE_NOMEM;
+ }
+ TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
+ pPager->zFilename = (char*)&pPager[1];
+ pPager->zDirectory = &pPager->zFilename[nameLen+1];
+ pPager->zJournal = &pPager->zDirectory[nameLen+1];
+ strcpy(pPager->zFilename, zFullPathname);
+ strcpy(pPager->zDirectory, zFullPathname);
+ for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
+ if( i>0 ) pPager->zDirectory[i-1] = 0;
+ strcpy(pPager->zJournal, zFullPathname);
+ sqliteFree(zFullPathname);
+ strcpy(&pPager->zJournal[nameLen], "-journal");
+ pPager->fd = fd;
+#if OS_UNIX
+ pPager->fd.pPager = pPager;
+#endif
+ pPager->journalOpen = 0;
+ pPager->useJournal = useJournal && !memDb;
+ pPager->noReadlock = noReadlock && readOnly;
+ pPager->stmtOpen = 0;
+ pPager->stmtInUse = 0;
+ pPager->nRef = 0;
+ pPager->dbSize = memDb-1;
+ pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
+ pPager->stmtSize = 0;
+ pPager->stmtJSize = 0;
+ pPager->nPage = 0;
+ pPager->nMaxPage = 0;
+ pPager->mxPage = 100;
+ pPager->state = PAGER_UNLOCK;
+ pPager->errMask = 0;
+ pPager->tempFile = tempFile;
+ pPager->memDb = memDb;
+ pPager->readOnly = readOnly;
+ pPager->needSync = 0;
+ pPager->noSync = pPager->tempFile || !useJournal;
+ pPager->fullSync = (pPager->noSync?0:1);
+ pPager->pFirst = 0;
+ pPager->pFirstSynced = 0;
+ pPager->pLast = 0;
+ pPager->nExtra = FORCE_ALIGNMENT(nExtra);
+ pPager->sectorSize = PAGER_SECTOR_SIZE;
+ pPager->pBusyHandler = 0;
+ memset(pPager->aHash, 0, sizeof(pPager->aHash));
+ *ppPager = pPager;
+ return SQLITE_OK;
+}
+
+/*
+** Set the busy handler function.
+*/
+void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
+ pPager->pBusyHandler = pBusyHandler;
+}
+
+/*
+** Set the destructor for this pager. If not NULL, the destructor is called
+** when the reference count on each page reaches zero. The destructor can
+** be used to clean up information in the extra segment appended to each page.
+**
+** The destructor is not called as a result sqlite3pager_close().
+** Destructors are only called by sqlite3pager_unref().
+*/
+void sqlite3pager_set_destructor(Pager *pPager, void (*xDesc)(void*,int)){
+ pPager->xDestructor = xDesc;
+}
+
+/*
+** Set the reinitializer for this pager. If not NULL, the reinitializer
+** is called when the content of a page in cache is restored to its original
+** value as a result of a rollback. The callback gives higher-level code
+** an opportunity to restore the EXTRA section to agree with the restored
+** page data.
+*/
+void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
+ pPager->xReiniter = xReinit;
+}
+
+/*
+** Set the page size. Return the new size. If the suggest new page
+** size is inappropriate, then an alternative page size is selected
+** and returned.
+*/
+int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
+ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
+ if( !pPager->memDb ){
+ pPager->pageSize = pageSize;
+ }
+ return pPager->pageSize;
+}
+
+/*
+** Read the first N bytes from the beginning of the file into memory
+** that pDest points to. No error checking is done.
+*/
+void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
+ memset(pDest, 0, N);
+ if( MEMDB==0 ){
+ sqlite3OsSeek(&pPager->fd, 0);
+ sqlite3OsRead(&pPager->fd, pDest, N);
+ }
+}
+
+/*
+** Return the total number of pages in the disk file associated with
+** pPager.
+*/
+int sqlite3pager_pagecount(Pager *pPager){
+ i64 n;
+ assert( pPager!=0 );
+ if( pPager->dbSize>=0 ){
+ return pPager->dbSize;
+ }
+ if( sqlite3OsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
+ pPager->errMask |= PAGER_ERR_DISK;
+ return 0;
+ }
+ n /= pPager->pageSize;
+ if( !MEMDB && n==PENDING_BYTE/pPager->pageSize ){
+ n++;
+ }
+ if( pPager->state!=PAGER_UNLOCK ){
+ pPager->dbSize = n;
+ }
+ return n;
+}
+
+/*
+** Forward declaration
+*/
+static int syncJournal(Pager*);
+
+
+/*
+** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate
+** that the page is not part of any hash chain. This is required because the
+** sqlite3pager_movepage() routine can leave a page in the
+** pNextFree/pPrevFree list that is not a part of any hash-chain.
+*/
+static void unlinkHashChain(Pager *pPager, PgHdr *pPg){
+ if( pPg->pgno==0 ){
+ /* If the page number is zero, then this page is not in any hash chain. */
+ return;
+ }
+ if( pPg->pNextHash ){
+ pPg->pNextHash->pPrevHash = pPg->pPrevHash;
+ }
+ if( pPg->pPrevHash ){
+ assert( pPager->aHash[pager_hash(pPg->pgno)]!=pPg );
+ pPg->pPrevHash->pNextHash = pPg->pNextHash;
+ }else{
+ int h = pager_hash(pPg->pgno);
+ assert( pPager->aHash[h]==pPg );
+ pPager->aHash[h] = pPg->pNextHash;
+ }
+
+ pPg->pgno = 0;
+ pPg->pNextHash = pPg->pPrevHash = 0;
+}
+
+/*
+** Unlink a page from the free list (the list of all pages where nRef==0)
+** and from its hash collision chain.
+*/
+static void unlinkPage(PgHdr *pPg){
+ Pager *pPager = pPg->pPager;
+
+ /* Keep the pFirstSynced pointer pointing at the first synchronized page */
+ if( pPg==pPager->pFirstSynced ){
+ PgHdr *p = pPg->pNextFree;
+ while( p && p->needSync ){ p = p->pNextFree; }
+ pPager->pFirstSynced = p;
+ }
+
+ /* Unlink from the freelist */
+ if( pPg->pPrevFree ){
+ pPg->pPrevFree->pNextFree = pPg->pNextFree;
+ }else{
+ assert( pPager->pFirst==pPg );
+ pPager->pFirst = pPg->pNextFree;
+ }
+ if( pPg->pNextFree ){
+ pPg->pNextFree->pPrevFree = pPg->pPrevFree;
+ }else{
+ assert( pPager->pLast==pPg );
+ pPager->pLast = pPg->pPrevFree;
+ }
+ pPg->pNextFree = pPg->pPrevFree = 0;
+
+ /* Unlink from the pgno hash table */
+ unlinkHashChain(pPager, pPg);
+}
+
+#ifndef SQLITE_OMIT_MEMORYDB
+/*
+** This routine is used to truncate an in-memory database. Delete
+** all pages whose pgno is larger than pPager->dbSize and is unreferenced.
+** Referenced pages larger than pPager->dbSize are zeroed.
+*/
+static void memoryTruncate(Pager *pPager){
+ PgHdr *pPg;
+ PgHdr **ppPg;
+ int dbSize = pPager->dbSize;
+
+ ppPg = &pPager->pAll;
+ while( (pPg = *ppPg)!=0 ){
+ if( pPg->pgno<=dbSize ){
+ ppPg = &pPg->pNextAll;
+ }else if( pPg->nRef>0 ){
+ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
+ ppPg = &pPg->pNextAll;
+ }else{
+ *ppPg = pPg->pNextAll;
+ unlinkPage(pPg);
+ sqliteFree(pPg);
+ pPager->nPage--;
+ }
+ }
+}
+#else
+#define memoryTruncate(p)
+#endif
+
+/*
+** Try to obtain a lock on a file. Invoke the busy callback if the lock
+** is currently not available. Repeate until the busy callback returns
+** false or until the lock succeeds.
+**
+** Return SQLITE_OK on success and an error code if we cannot obtain
+** the lock.
+*/
+static int pager_wait_on_lock(Pager *pPager, int locktype){
+ int rc;
+ assert( PAGER_SHARED==SHARED_LOCK );
+ assert( PAGER_RESERVED==RESERVED_LOCK );
+ assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
+ if( pPager->state>=locktype ){
+ rc = SQLITE_OK;
+ }else{
+ int busy = 1;
+ BusyHandler *pH;
+ do {
+ rc = sqlite3OsLock(&pPager->fd, locktype);
+ }while( rc==SQLITE_BUSY &&
+ (pH = pPager->pBusyHandler)!=0 &&
+ pH->xFunc && pH->xFunc(pH->pArg, busy++)
+ );
+ if( rc==SQLITE_OK ){
+ pPager->state = locktype;
+ }
+ }
+ return rc;
+}
+
+/*
+** Truncate the file to the number of pages specified.
+*/
+int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
+ int rc;
+ sqlite3pager_pagecount(pPager);
+ if( pPager->errMask!=0 ){
+ rc = pager_errcode(pPager);
+ return rc;
+ }
+ if( nPage>=(unsigned)pPager->dbSize ){
+ return SQLITE_OK;
+ }
+ if( MEMDB ){
+ pPager->dbSize = nPage;
+ memoryTruncate(pPager);
+ return SQLITE_OK;
+ }
+ rc = syncJournal(pPager);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ /* Get an exclusive lock on the database before truncating. */
+ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ rc = pager_truncate(pPager, nPage);
+ if( rc==SQLITE_OK ){
+ pPager->dbSize = nPage;
+ }
+ return rc;
+}
+
+/*
+** Shutdown the page cache. Free all memory and close all files.
+**
+** If a transaction was in progress when this routine is called, that
+** transaction is rolled back. All outstanding pages are invalidated
+** and their memory is freed. Any attempt to use a page associated
+** with this page cache after this function returns will likely
+** result in a coredump.
+*/
+int sqlite3pager_close(Pager *pPager){
+ PgHdr *pPg, *pNext;
+ switch( pPager->state ){
+ case PAGER_RESERVED:
+ case PAGER_SYNCED:
+ case PAGER_EXCLUSIVE: {
+ /* We ignore any IO errors that occur during the rollback
+ ** operation. So disable IO error simulation so that testing
+ ** works more easily.
+ */
+#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
+ extern int sqlite3_io_error_pending;
+ int ioerr_cnt = sqlite3_io_error_pending;
+ sqlite3_io_error_pending = -1;
+#endif
+ sqlite3pager_rollback(pPager);
+#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
+ sqlite3_io_error_pending = ioerr_cnt;
+#endif
+ if( !MEMDB ){
+ sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+ }
+ assert( pPager->errMask || pPager->journalOpen==0 );
+ break;
+ }
+ case PAGER_SHARED: {
+ if( !MEMDB ){
+ sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+ }
+ break;
+ }
+ default: {
+ /* Do nothing */
+ break;
+ }
+ }
+ for(pPg=pPager->pAll; pPg; pPg=pNext){
+#ifndef NDEBUG
+ if( MEMDB ){
+ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+ assert( !pPg->alwaysRollback );
+ assert( !pHist->pOrig );
+ assert( !pHist->pStmt );
+ }
+#endif
+ pNext = pPg->pNextAll;
+ sqliteFree(pPg);
+ }
+ TRACE2("CLOSE %d\n", PAGERID(pPager));
+ assert( pPager->errMask || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
+ if( pPager->journalOpen ){
+ sqlite3OsClose(&pPager->jfd);
+ }
+ sqliteFree(pPager->aInJournal);
+ if( pPager->stmtOpen ){
+ sqlite3OsClose(&pPager->stfd);
+ }
+ sqlite3OsClose(&pPager->fd);
+ /* Temp files are automatically deleted by the OS
+ ** if( pPager->tempFile ){
+ ** sqlite3OsDelete(pPager->zFilename);
+ ** }
+ */
+
+ sqliteFree(pPager);
+ return SQLITE_OK;
+}
+
+/*
+** Return the page number for the given page data.
+*/
+Pgno sqlite3pager_pagenumber(void *pData){
+ PgHdr *p = DATA_TO_PGHDR(pData);
+ return p->pgno;
+}
+
+/*
+** The page_ref() function increments the reference count for a page.
+** If the page is currently on the freelist (the reference count is zero) then
+** remove it from the freelist.
+**
+** For non-test systems, page_ref() is a macro that calls _page_ref()
+** online of the reference count is zero. For test systems, page_ref()
+** is a real function so that we can set breakpoints and trace it.
+*/
+static void _page_ref(PgHdr *pPg){
+ if( pPg->nRef==0 ){
+ /* The page is currently on the freelist. Remove it. */
+ if( pPg==pPg->pPager->pFirstSynced ){
+ PgHdr *p = pPg->pNextFree;
+ while( p && p->needSync ){ p = p->pNextFree; }
+ pPg->pPager->pFirstSynced = p;
+ }
+ if( pPg->pPrevFree ){
+ pPg->pPrevFree->pNextFree = pPg->pNextFree;
+ }else{
+ pPg->pPager->pFirst = pPg->pNextFree;
+ }
+ if( pPg->pNextFree ){
+ pPg->pNextFree->pPrevFree = pPg->pPrevFree;
+ }else{
+ pPg->pPager->pLast = pPg->pPrevFree;
+ }
+ pPg->pPager->nRef++;
+ }
+ pPg->nRef++;
+ REFINFO(pPg);
+}
+#ifdef SQLITE_DEBUG
+ static void page_ref(PgHdr *pPg){
+ if( pPg->nRef==0 ){
+ _page_ref(pPg);
+ }else{
+ pPg->nRef++;
+ REFINFO(pPg);
+ }
+ }
+#else
+# define page_ref(P) ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++)
+#endif
+
+/*
+** Increment the reference count for a page. The input pointer is
+** a reference to the page data.
+*/
+int sqlite3pager_ref(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ page_ref(pPg);
+ return SQLITE_OK;
+}
+
+/*
+** Sync the journal. In other words, make sure all the pages that have
+** been written to the journal have actually reached the surface of the
+** disk. It is not safe to modify the original database file until after
+** the journal has been synced. If the original database is modified before
+** the journal is synced and a power failure occurs, the unsynced journal
+** data would be lost and we would be unable to completely rollback the
+** database changes. Database corruption would occur.
+**
+** This routine also updates the nRec field in the header of the journal.
+** (See comments on the pager_playback() routine for additional information.)
+** If the sync mode is FULL, two syncs will occur. First the whole journal
+** is synced, then the nRec field is updated, then a second sync occurs.
+**
+** For temporary databases, we do not care if we are able to rollback
+** after a power failure, so sync occurs.
+**
+** This routine clears the needSync field of every page current held in
+** memory.
+*/
+static int syncJournal(Pager *pPager){
+ PgHdr *pPg;
+ int rc = SQLITE_OK;
+
+ /* Sync the journal before modifying the main database
+ ** (assuming there is a journal and it needs to be synced.)
+ */
+ if( pPager->needSync ){
+ if( !pPager->tempFile ){
+ assert( pPager->journalOpen );
+ /* assert( !pPager->noSync ); // noSync might be set if synchronous
+ ** was turned off after the transaction was started. Ticket #615 */
+#ifndef NDEBUG
+ {
+ /* Make sure the pPager->nRec counter we are keeping agrees
+ ** with the nRec computed from the size of the journal file.
+ */
+ i64 jSz;
+ rc = sqlite3OsFileSize(&pPager->jfd, &jSz);
+ if( rc!=0 ) return rc;
+ assert( pPager->journalOff==jSz );
+ }
+#endif
+ {
+ /* Write the nRec value into the journal file header. If in
+ ** full-synchronous mode, sync the journal first. This ensures that
+ ** all data has really hit the disk before nRec is updated to mark
+ ** it as a candidate for rollback.
+ */
+ if( pPager->fullSync ){
+ TRACE2("SYNC journal of %d\n", PAGERID(pPager));
+ rc = sqlite3OsSync(&pPager->jfd);
+ if( rc!=0 ) return rc;
+ }
+ sqlite3OsSeek(&pPager->jfd, pPager->journalHdr + sizeof(aJournalMagic));
+ rc = write32bits(&pPager->jfd, pPager->nRec);
+ if( rc ) return rc;
+
+ sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
+ }
+ TRACE2("SYNC journal of %d\n", PAGERID(pPager));
+ rc = sqlite3OsSync(&pPager->jfd);
+ if( rc!=0 ) return rc;
+ pPager->journalStarted = 1;
+ }
+ pPager->needSync = 0;
+
+ /* Erase the needSync flag from every page.
+ */
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ pPg->needSync = 0;
+ }
+ pPager->pFirstSynced = pPager->pFirst;
+ }
+
+#ifndef NDEBUG
+ /* If the Pager.needSync flag is clear then the PgHdr.needSync
+ ** flag must also be clear for all pages. Verify that this
+ ** invariant is true.
+ */
+ else{
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ assert( pPg->needSync==0 );
+ }
+ assert( pPager->pFirstSynced==pPager->pFirst );
+ }
+#endif
+
+ return rc;
+}
+
+/*
+** Given a list of pages (connected by the PgHdr.pDirty pointer) write
+** every one of those pages out to the database file and mark them all
+** as clean.
+*/
+static int pager_write_pagelist(PgHdr *pList){
+ Pager *pPager;
+ int rc;
+
+ if( pList==0 ) return SQLITE_OK;
+ pPager = pList->pPager;
+
+ /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
+ ** database file. If there is already an EXCLUSIVE lock, the following
+ ** calls to sqlite3OsLock() are no-ops.
+ **
+ ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
+ ** through an intermediate state PENDING. A PENDING lock prevents new
+ ** readers from attaching to the database but is unsufficient for us to
+ ** write. The idea of a PENDING lock is to prevent new readers from
+ ** coming in while we wait for existing readers to clear.
+ **
+ ** While the pager is in the RESERVED state, the original database file
+ ** is unchanged and we can rollback without having to playback the
+ ** journal into the original database file. Once we transition to
+ ** EXCLUSIVE, it means the database file has been changed and any rollback
+ ** will require a journal playback.
+ */
+ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ while( pList ){
+ assert( pList->dirty );
+ sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);
+ /* If there are dirty pages in the page cache with page numbers greater
+ ** than Pager.dbSize, this means sqlite3pager_truncate() was called to
+ ** make the file smaller (presumably by auto-vacuum code). Do not write
+ ** any such pages to the file.
+ */
+ if( pList->pgno<=pPager->dbSize ){
+ CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
+ TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
+ rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize);
+ CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
+ TEST_INCR(pPager->nWrite);
+ }
+#ifndef NDEBUG
+ else{
+ TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
+ }
+#endif
+ if( rc ) return rc;
+ pList->dirty = 0;
+#ifdef SQLITE_CHECK_PAGES
+ pList->pageHash = pager_pagehash(pList);
+#endif
+ pList = pList->pDirty;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Collect every dirty page into a dirty list and
+** return a pointer to the head of that list. All pages are
+** collected even if they are still in use.
+*/
+static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
+ PgHdr *p, *pList;
+ pList = 0;
+ for(p=pPager->pAll; p; p=p->pNextAll){
+ if( p->dirty ){
+ p->pDirty = pList;
+ pList = p;
+ }
+ }
+ return pList;
+}
+
+/*
+** Return TRUE if there is a hot journal on the given pager.
+** A hot journal is one that needs to be played back.
+**
+** If the current size of the database file is 0 but a journal file
+** exists, that is probably an old journal left over from a prior
+** database with the same name. Just delete the journal.
+*/
+static int hasHotJournal(Pager *pPager){
+ if( !pPager->useJournal ) return 0;
+ if( !sqlite3OsFileExists(pPager->zJournal) ) return 0;
+ if( sqlite3OsCheckReservedLock(&pPager->fd) ) return 0;
+ if( sqlite3pager_pagecount(pPager)==0 ){
+ sqlite3OsDelete(pPager->zJournal);
+ return 0;
+ }else{
+ return 1;
+ }
+}
+
+/*
+** Acquire a page.
+**
+** A read lock on the disk file is obtained when the first page is acquired.
+** This read lock is dropped when the last page is released.
+**
+** A _get works for any page number greater than 0. If the database
+** file is smaller than the requested page, then no actual disk
+** read occurs and the memory image of the page is initialized to
+** all zeros. The extra data appended to a page is always initialized
+** to zeros the first time a page is loaded into memory.
+**
+** The acquisition might fail for several reasons. In all cases,
+** an appropriate error code is returned and *ppPage is set to NULL.
+**
+** See also sqlite3pager_lookup(). Both this routine and _lookup() attempt
+** to find a page in the in-memory cache first. If the page is not already
+** in memory, this routine goes to disk to read it in whereas _lookup()
+** just returns 0. This routine acquires a read-lock the first time it
+** has to go to disk, and could also playback an old journal if necessary.
+** Since _lookup() never goes to disk, it never has to deal with locks
+** or journal files.
+*/
+int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
+ PgHdr *pPg;
+ int rc;
+
+ /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
+ ** number greater than this, or zero, is requested.
+ */
+ if( pgno>PAGER_MAX_PGNO || pgno==0 ){
+ return SQLITE_CORRUPT;
+ }
+
+ /* Make sure we have not hit any critical errors.
+ */
+ assert( pPager!=0 );
+ *ppPage = 0;
+ if( pPager->errMask & ~(PAGER_ERR_FULL) ){
+ return pager_errcode(pPager);
+ }
+
+ /* If this is the first page accessed, then get a SHARED lock
+ ** on the database file.
+ */
+ if( pPager->nRef==0 && !MEMDB ){
+ if( !pPager->noReadlock ){
+ rc = pager_wait_on_lock(pPager, SHARED_LOCK);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
+
+ /* If a journal file exists, and there is no RESERVED lock on the
+ ** database file, then it either needs to be played back or deleted.
+ */
+ if( hasHotJournal(pPager) ){
+ int rc;
+
+ /* Get an EXCLUSIVE lock on the database file. At this point it is
+ ** important that a RESERVED lock is not obtained on the way to the
+ ** EXCLUSIVE lock. If it were, another process might open the
+ ** database file, detect the RESERVED lock, and conclude that the
+ ** database is safe to read while this process is still rolling it
+ ** back.
+ **
+ ** Because the intermediate RESERVED lock is not requested, the
+ ** second process will get to this point in the code and fail to
+ ** obtain it's own EXCLUSIVE lock on the database file.
+ */
+ rc = sqlite3OsLock(&pPager->fd, EXCLUSIVE_LOCK);
+ if( rc!=SQLITE_OK ){
+ sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+ pPager->state = PAGER_UNLOCK;
+ return rc;
+ }
+ pPager->state = PAGER_EXCLUSIVE;
+
+ /* Open the journal for reading only. Return SQLITE_BUSY if
+ ** we are unable to open the journal file.
+ **
+ ** The journal file does not need to be locked itself. The
+ ** journal file is never open unless the main database file holds
+ ** a write lock, so there is never any chance of two or more
+ ** processes opening the journal at the same time.
+ */
+ rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
+ if( rc!=SQLITE_OK ){
+ sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+ pPager->state = PAGER_UNLOCK;
+ return SQLITE_BUSY;
+ }
+ pPager->journalOpen = 1;
+ pPager->journalStarted = 0;
+ pPager->journalOff = 0;
+ pPager->setMaster = 0;
+ pPager->journalHdr = 0;
+
+ /* Playback and delete the journal. Drop the database write
+ ** lock and reacquire the read lock.
+ */
+ rc = pager_playback(pPager);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
+ pPg = 0;
+ }else{
+ /* Search for page in cache */
+ pPg = pager_lookup(pPager, pgno);
+ if( MEMDB && pPager->state==PAGER_UNLOCK ){
+ pPager->state = PAGER_SHARED;
+ }
+ }
+ if( pPg==0 ){
+ /* The requested page is not in the page cache. */
+ int h;
+ TEST_INCR(pPager->nMiss);
+ if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ){
+ /* Create a new page */
+ pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
+ + sizeof(u32) + pPager->nExtra
+ + MEMDB*sizeof(PgHistory) );
+ if( pPg==0 ){
+ pPager->errMask |= PAGER_ERR_MEM;
+ return SQLITE_NOMEM;
+ }
+ memset(pPg, 0, sizeof(*pPg));
+ if( MEMDB ){
+ memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
+ }
+ pPg->pPager = pPager;
+ pPg->pNextAll = pPager->pAll;
+ pPager->pAll = pPg;
+ pPager->nPage++;
+ if( pPager->nPage>pPager->nMaxPage ){
+ assert( pPager->nMaxPage==(pPager->nPage-1) );
+ pPager->nMaxPage++;
+ }
+ }else{
+ /* Find a page to recycle. Try to locate a page that does not
+ ** require us to do an fsync() on the journal.
+ */
+ pPg = pPager->pFirstSynced;
+
+ /* If we could not find a page that does not require an fsync()
+ ** on the journal file then fsync the journal file. This is a
+ ** very slow operation, so we work hard to avoid it. But sometimes
+ ** it can't be helped.
+ */
+ if( pPg==0 ){
+ int rc = syncJournal(pPager);
+ if( rc!=0 ){
+ sqlite3pager_rollback(pPager);
+ return SQLITE_IOERR;
+ }
+ if( pPager->fullSync ){
+ /* If in full-sync mode, write a new journal header into the
+ ** journal file. This is done to avoid ever modifying a journal
+ ** header that is involved in the rollback of pages that have
+ ** already been written to the database (in case the header is
+ ** trashed when the nRec field is updated).
+ */
+ pPager->nRec = 0;
+ assert( pPager->journalOff > 0 );
+ rc = writeJournalHdr(pPager);
+ if( rc!=0 ){
+ sqlite3pager_rollback(pPager);
+ return SQLITE_IOERR;
+ }
+ }
+ pPg = pPager->pFirst;
+ }
+ assert( pPg->nRef==0 );
+
+ /* Write the page to the database file if it is dirty.
+ */
+ if( pPg->dirty ){
+ assert( pPg->needSync==0 );
+ pPg->pDirty = 0;
+ rc = pager_write_pagelist( pPg );
+ if( rc!=SQLITE_OK ){
+ sqlite3pager_rollback(pPager);
+ return SQLITE_IOERR;
+ }
+ }
+ assert( pPg->dirty==0 );
+
+ /* If the page we are recycling is marked as alwaysRollback, then
+ ** set the global alwaysRollback flag, thus disabling the
+ ** sqlite_dont_rollback() optimization for the rest of this transaction.
+ ** It is necessary to do this because the page marked alwaysRollback
+ ** might be reloaded at a later time but at that point we won't remember
+ ** that is was marked alwaysRollback. This means that all pages must
+ ** be marked as alwaysRollback from here on out.
+ */
+ if( pPg->alwaysRollback ){
+ pPager->alwaysRollback = 1;
+ }
+
+ /* Unlink the old page from the free list and the hash table
+ */
+ unlinkPage(pPg);
+ TEST_INCR(pPager->nOvfl);
+ }
+ pPg->pgno = pgno;
+ if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
+ sqlite3CheckMemory(pPager->aInJournal, pgno/8);
+ assert( pPager->journalOpen );
+ pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
+ pPg->needSync = 0;
+ }else{
+ pPg->inJournal = 0;
+ pPg->needSync = 0;
+ }
+ if( pPager->aInStmt && (int)pgno<=pPager->stmtSize
+ && (pPager->aInStmt[pgno/8] & (1<<(pgno&7)))!=0 ){
+ page_add_to_stmt_list(pPg);
+ }else{
+ page_remove_from_stmt_list(pPg);
+ }
+ pPg->dirty = 0;
+ pPg->nRef = 1;
+ REFINFO(pPg);
+ pPager->nRef++;
+ h = pager_hash(pgno);
+ pPg->pNextHash = pPager->aHash[h];
+ pPager->aHash[h] = pPg;
+ if( pPg->pNextHash ){
+ assert( pPg->pNextHash->pPrevHash==0 );
+ pPg->pNextHash->pPrevHash = pPg;
+ }
+ if( pPager->nExtra>0 ){
+ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
+ }
+ if( pPager->errMask!=0 ){
+ sqlite3pager_unref(PGHDR_TO_DATA(pPg));
+ rc = pager_errcode(pPager);
+ return rc;
+ }
+ if( sqlite3pager_pagecount(pPager)<(int)pgno ){
+ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
+ }else{
+ int rc;
+ assert( MEMDB==0 );
+ sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);
+ rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize);
+ TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
+ CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
+ if( rc!=SQLITE_OK ){
+ i64 fileSize;
+ if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
+ || fileSize>=pgno*pPager->pageSize ){
+ sqlite3pager_unref(PGHDR_TO_DATA(pPg));
+ return rc;
+ }else{
+ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
+ }
+ }else{
+ TEST_INCR(pPager->nRead);
+ }
+ }
+#ifdef SQLITE_CHECK_PAGES
+ pPg->pageHash = pager_pagehash(pPg);
+#endif
+ }else{
+ /* The requested page is in the page cache. */
+ TEST_INCR(pPager->nHit);
+ page_ref(pPg);
+ }
+ *ppPage = PGHDR_TO_DATA(pPg);
+ return SQLITE_OK;
+}
+
+/*
+** Acquire a page if it is already in the in-memory cache. Do
+** not read the page from disk. Return a pointer to the page,
+** or 0 if the page is not in cache.
+**
+** See also sqlite3pager_get(). The difference between this routine
+** and sqlite3pager_get() is that _get() will go to the disk and read
+** in the page if the page is not already in cache. This routine
+** returns NULL if the page is not in cache or if a disk I/O error
+** has ever happened.
+*/
+void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){
+ PgHdr *pPg;
+
+ assert( pPager!=0 );
+ assert( pgno!=0 );
+ if( pPager->errMask & ~(PAGER_ERR_FULL) ){
+ return 0;
+ }
+ pPg = pager_lookup(pPager, pgno);
+ if( pPg==0 ) return 0;
+ page_ref(pPg);
+ return PGHDR_TO_DATA(pPg);
+}
+
+/*
+** Release a page.
+**
+** If the number of references to the page drop to zero, then the
+** page is added to the LRU list. When all references to all pages
+** are released, a rollback occurs and the lock on the database is
+** removed.
+*/
+int sqlite3pager_unref(void *pData){
+ PgHdr *pPg;
+
+ /* Decrement the reference count for this page
+ */
+ pPg = DATA_TO_PGHDR(pData);
+ assert( pPg->nRef>0 );
+ pPg->nRef--;
+ REFINFO(pPg);
+
+ CHECK_PAGE(pPg);
+
+ /* When the number of references to a page reach 0, call the
+ ** destructor and add the page to the freelist.
+ */
+ if( pPg->nRef==0 ){
+ Pager *pPager;
+ pPager = pPg->pPager;
+ pPg->pNextFree = 0;
+ pPg->pPrevFree = pPager->pLast;
+ pPager->pLast = pPg;
+ if( pPg->pPrevFree ){
+ pPg->pPrevFree->pNextFree = pPg;
+ }else{
+ pPager->pFirst = pPg;
+ }
+ if( pPg->needSync==0 && pPager->pFirstSynced==0 ){
+ pPager->pFirstSynced = pPg;
+ }
+ if( pPager->xDestructor ){
+ pPager->xDestructor(pData, pPager->pageSize);
+ }
+
+ /* When all pages reach the freelist, drop the read lock from
+ ** the database file.
+ */
+ pPager->nRef--;
+ assert( pPager->nRef>=0 );
+ if( pPager->nRef==0 && !MEMDB ){
+ pager_reset(pPager);
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Create a journal file for pPager. There should already be a RESERVED
+** or EXCLUSIVE lock on the database file when this routine is called.
+**
+** Return SQLITE_OK if everything. Return an error code and release the
+** write lock if anything goes wrong.
+*/
+static int pager_open_journal(Pager *pPager){
+ int rc;
+ assert( !MEMDB );
+ assert( pPager->state>=PAGER_RESERVED );
+ assert( pPager->journalOpen==0 );
+ assert( pPager->useJournal );
+ assert( pPager->aInJournal==0 );
+ sqlite3pager_pagecount(pPager);
+ pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
+ if( pPager->aInJournal==0 ){
+ rc = SQLITE_NOMEM;
+ goto failed_to_open_journal;
+ }
+ rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
+ pPager->journalOff = 0;
+ pPager->setMaster = 0;
+ pPager->journalHdr = 0;
+ if( rc!=SQLITE_OK ){
+ goto failed_to_open_journal;
+ }
+ SET_FULLSYNC(pPager->jfd, pPager->fullSync);
+ SET_FULLSYNC(pPager->fd, pPager->fullSync);
+ sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd);
+ pPager->journalOpen = 1;
+ pPager->journalStarted = 0;
+ pPager->needSync = 0;
+ pPager->alwaysRollback = 0;
+ pPager->nRec = 0;
+ if( pPager->errMask!=0 ){
+ rc = pager_errcode(pPager);
+ goto failed_to_open_journal;
+ }
+ pPager->origDbSize = pPager->dbSize;
+
+ rc = writeJournalHdr(pPager);
+
+ if( pPager->stmtAutoopen && rc==SQLITE_OK ){
+ rc = sqlite3pager_stmt_begin(pPager);
+ }
+ if( rc!=SQLITE_OK ){
+ rc = pager_unwritelock(pPager);
+ if( rc==SQLITE_OK ){
+ rc = SQLITE_FULL;
+ }
+ }
+ return rc;
+
+failed_to_open_journal:
+ sqliteFree(pPager->aInJournal);
+ pPager->aInJournal = 0;
+ sqlite3OsUnlock(&pPager->fd, NO_LOCK);
+ pPager->state = PAGER_UNLOCK;
+ return rc;
+}
+
+/*
+** Acquire a write-lock on the database. The lock is removed when
+** the any of the following happen:
+**
+** * sqlite3pager_commit() is called.
+** * sqlite3pager_rollback() is called.
+** * sqlite3pager_close() is called.
+** * sqlite3pager_unref() is called to on every outstanding page.
+**
+** The first parameter to this routine is a pointer to any open page of the
+** database file. Nothing changes about the page - it is used merely to
+** acquire a pointer to the Pager structure and as proof that there is
+** already a read-lock on the database.
+**
+** The second parameter indicates how much space in bytes to reserve for a
+** master journal file-name at the start of the journal when it is created.
+**
+** A journal file is opened if this is not a temporary file. For temporary
+** files, the opening of the journal file is deferred until there is an
+** actual need to write to the journal.
+**
+** If the database is already reserved for writing, this routine is a no-op.
+**
+** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file
+** immediately instead of waiting until we try to flush the cache. The
+** exFlag is ignored if a transaction is already active.
+*/
+int sqlite3pager_begin(void *pData, int exFlag){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ Pager *pPager = pPg->pPager;
+ int rc = SQLITE_OK;
+ assert( pPg->nRef>0 );
+ assert( pPager->state!=PAGER_UNLOCK );
+ if( pPager->state==PAGER_SHARED ){
+ assert( pPager->aInJournal==0 );
+ if( MEMDB ){
+ pPager->state = PAGER_EXCLUSIVE;
+ pPager->origDbSize = pPager->dbSize;
+ }else{
+ rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK);
+ if( rc==SQLITE_OK ){
+ pPager->state = PAGER_RESERVED;
+ if( exFlag ){
+ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+ }
+ }
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ pPager->dirtyCache = 0;
+ TRACE2("TRANSACTION %d\n", PAGERID(pPager));
+ if( pPager->useJournal && !pPager->tempFile ){
+ rc = pager_open_journal(pPager);
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+** Mark a data page as writeable. The page is written into the journal
+** if it is not there already. This routine must be called before making
+** changes to a page.
+**
+** The first time this routine is called, the pager creates a new
+** journal and acquires a RESERVED lock on the database. If the RESERVED
+** lock could not be acquired, this routine returns SQLITE_BUSY. The
+** calling routine must check for that return value and be careful not to
+** change any page data until this routine returns SQLITE_OK.
+**
+** If the journal file could not be written because the disk is full,
+** then this routine returns SQLITE_FULL and does an immediate rollback.
+** All subsequent write attempts also return SQLITE_FULL until there
+** is a call to sqlite3pager_commit() or sqlite3pager_rollback() to
+** reset.
+*/
+int sqlite3pager_write(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ Pager *pPager = pPg->pPager;
+ int rc = SQLITE_OK;
+
+ /* Check for errors
+ */
+ if( pPager->errMask ){
+ return pager_errcode(pPager);
+ }
+ if( pPager->readOnly ){
+ return SQLITE_PERM;
+ }
+
+ assert( !pPager->setMaster );
+
+ CHECK_PAGE(pPg);
+
+ /* Mark the page as dirty. If the page has already been written
+ ** to the journal then we can return right away.
+ */
+ pPg->dirty = 1;
+ if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){
+ pPager->dirtyCache = 1;
+ }else{
+
+ /* If we get this far, it means that the page needs to be
+ ** written to the transaction journal or the ckeckpoint journal
+ ** or both.
+ **
+ ** First check to see that the transaction journal exists and
+ ** create it if it does not.
+ */
+ assert( pPager->state!=PAGER_UNLOCK );
+ rc = sqlite3pager_begin(pData, 0);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ assert( pPager->state>=PAGER_RESERVED );
+ if( !pPager->journalOpen && pPager->useJournal ){
+ rc = pager_open_journal(pPager);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ assert( pPager->journalOpen || !pPager->useJournal );
+ pPager->dirtyCache = 1;
+
+ /* The transaction journal now exists and we have a RESERVED or an
+ ** EXCLUSIVE lock on the main database file. Write the current page to
+ ** the transaction journal if it is not there already.
+ */
+ if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
+ if( (int)pPg->pgno <= pPager->origDbSize ){
+ int szPg;
+ u32 saved;
+ if( MEMDB ){
+ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+ TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
+ assert( pHist->pOrig==0 );
+ pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
+ if( pHist->pOrig ){
+ memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
+ }
+ }else{
+ u32 cksum;
+ CODEC(pPager, pData, pPg->pgno, 7);
+ cksum = pager_cksum(pPager, pPg->pgno, pData);
+ saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
+ store32bits(cksum, pPg, pPager->pageSize);
+ szPg = pPager->pageSize+8;
+ store32bits(pPg->pgno, pPg, -4);
+ rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
+ pPager->journalOff += szPg;
+ TRACE4("JOURNAL %d page %d needSync=%d\n",
+ PAGERID(pPager), pPg->pgno, pPg->needSync);
+ CODEC(pPager, pData, pPg->pgno, 0);
+ *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
+ if( rc!=SQLITE_OK ){
+ sqlite3pager_rollback(pPager);
+ pPager->errMask |= PAGER_ERR_FULL;
+ return rc;
+ }
+ pPager->nRec++;
+ assert( pPager->aInJournal!=0 );
+ pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ pPg->needSync = !pPager->noSync;
+ if( pPager->stmtInUse ){
+ pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ page_add_to_stmt_list(pPg);
+ }
+ }
+ }else{
+ pPg->needSync = !pPager->journalStarted && !pPager->noSync;
+ TRACE4("APPEND %d page %d needSync=%d\n",
+ PAGERID(pPager), pPg->pgno, pPg->needSync);
+ }
+ if( pPg->needSync ){
+ pPager->needSync = 1;
+ }
+ pPg->inJournal = 1;
+ }
+
+ /* If the statement journal is open and the page is not in it,
+ ** then write the current page to the statement journal. Note that
+ ** the statement journal format differs from the standard journal format
+ ** in that it omits the checksums and the header.
+ */
+ if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){
+ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
+ if( MEMDB ){
+ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+ assert( pHist->pStmt==0 );
+ pHist->pStmt = sqliteMallocRaw( pPager->pageSize );
+ if( pHist->pStmt ){
+ memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
+ }
+ TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
+ }else{
+ store32bits(pPg->pgno, pPg, -4);
+ CODEC(pPager, pData, pPg->pgno, 7);
+ rc = sqlite3OsWrite(&pPager->stfd,((char*)pData)-4, pPager->pageSize+4);
+ TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
+ CODEC(pPager, pData, pPg->pgno, 0);
+ if( rc!=SQLITE_OK ){
+ sqlite3pager_rollback(pPager);
+ pPager->errMask |= PAGER_ERR_FULL;
+ return rc;
+ }
+ pPager->stmtNRec++;
+ assert( pPager->aInStmt!=0 );
+ pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ }
+ page_add_to_stmt_list(pPg);
+ }
+ }
+
+ /* Update the database size and return.
+ */
+ if( pPager->dbSize<(int)pPg->pgno ){
+ pPager->dbSize = pPg->pgno;
+ if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
+ pPager->dbSize++;
+ }
+ }
+ return rc;
+}
+
+/*
+** Return TRUE if the page given in the argument was previously passed
+** to sqlite3pager_write(). In other words, return TRUE if it is ok
+** to change the content of the page.
+*/
+int sqlite3pager_iswriteable(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ return pPg->dirty;
+}
+
+#ifndef SQLITE_OMIT_VACUUM
+/*
+** Replace the content of a single page with the information in the third
+** argument.
+*/
+int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){
+ void *pPage;
+ int rc;
+
+ rc = sqlite3pager_get(pPager, pgno, &pPage);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3pager_write(pPage);
+ if( rc==SQLITE_OK ){
+ memcpy(pPage, pData, pPager->pageSize);
+ }
+ sqlite3pager_unref(pPage);
+ }
+ return rc;
+}
+#endif
+
+/*
+** A call to this routine tells the pager that it is not necessary to
+** write the information on page "pgno" back to the disk, even though
+** that page might be marked as dirty.
+**
+** The overlying software layer calls this routine when all of the data
+** on the given page is unused. The pager marks the page as clean so
+** that it does not get written to disk.
+**
+** Tests show that this optimization, together with the
+** sqlite3pager_dont_rollback() below, more than double the speed
+** of large INSERT operations and quadruple the speed of large DELETEs.
+**
+** When this routine is called, set the alwaysRollback flag to true.
+** Subsequent calls to sqlite3pager_dont_rollback() for the same page
+** will thereafter be ignored. This is necessary to avoid a problem
+** where a page with data is added to the freelist during one part of
+** a transaction then removed from the freelist during a later part
+** of the same transaction and reused for some other purpose. When it
+** is first added to the freelist, this routine is called. When reused,
+** the dont_rollback() routine is called. But because the page contains
+** critical data, we still need to be sure it gets rolled back in spite
+** of the dont_rollback() call.
+*/
+void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
+ PgHdr *pPg;
+
+ if( MEMDB ) return;
+
+ pPg = pager_lookup(pPager, pgno);
+ pPg->alwaysRollback = 1;
+ if( pPg && pPg->dirty ){
+ if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
+ /* If this pages is the last page in the file and the file has grown
+ ** during the current transaction, then do NOT mark the page as clean.
+ ** When the database file grows, we must make sure that the last page
+ ** gets written at least once so that the disk file will be the correct
+ ** size. If you do not write this page and the size of the file
+ ** on the disk ends up being too small, that can lead to database
+ ** corruption during the next transaction.
+ */
+ }else{
+ TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager));
+ pPg->dirty = 0;
+#ifdef SQLITE_CHECK_PAGES
+ pPg->pageHash = pager_pagehash(pPg);
+#endif
+ }
+ }
+}
+
+/*
+** A call to this routine tells the pager that if a rollback occurs,
+** it is not necessary to restore the data on the given page. This
+** means that the pager does not have to record the given page in the
+** rollback journal.
+*/
+void sqlite3pager_dont_rollback(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ Pager *pPager = pPg->pPager;
+
+ if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return;
+ if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
+ if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
+ assert( pPager->aInJournal!=0 );
+ pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ pPg->inJournal = 1;
+ if( pPager->stmtInUse ){
+ pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ page_add_to_stmt_list(pPg);
+ }
+ TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager));
+ }
+ if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){
+ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
+ assert( pPager->aInStmt!=0 );
+ pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ page_add_to_stmt_list(pPg);
+ }
+}
+
+
+#ifndef SQLITE_OMIT_MEMORYDB
+/*
+** Clear a PgHistory block
+*/
+static void clearHistory(PgHistory *pHist){
+ sqliteFree(pHist->pOrig);
+ sqliteFree(pHist->pStmt);
+ pHist->pOrig = 0;
+ pHist->pStmt = 0;
+}
+#else
+#define clearHistory(x)
+#endif
+
+/*
+** Commit all changes to the database and release the write lock.
+**
+** If the commit fails for any reason, a rollback attempt is made
+** and an error code is returned. If the commit worked, SQLITE_OK
+** is returned.
+*/
+int sqlite3pager_commit(Pager *pPager){
+ int rc;
+ PgHdr *pPg;
+
+ if( pPager->errMask==PAGER_ERR_FULL ){
+ rc = sqlite3pager_rollback(pPager);
+ if( rc==SQLITE_OK ){
+ rc = SQLITE_FULL;
+ }
+ return rc;
+ }
+ if( pPager->errMask!=0 ){
+ rc = pager_errcode(pPager);
+ return rc;
+ }
+ if( pPager->state<PAGER_RESERVED ){
+ return SQLITE_ERROR;
+ }
+ TRACE2("COMMIT %d\n", PAGERID(pPager));
+ if( MEMDB ){
+ pPg = pager_get_all_dirty_pages(pPager);
+ while( pPg ){
+ clearHistory(PGHDR_TO_HIST(pPg, pPager));
+ pPg->dirty = 0;
+ pPg->inJournal = 0;
+ pPg->inStmt = 0;
+ pPg->pPrevStmt = pPg->pNextStmt = 0;
+ pPg = pPg->pDirty;
+ }
+#ifndef NDEBUG
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+ assert( !pPg->alwaysRollback );
+ assert( !pHist->pOrig );
+ assert( !pHist->pStmt );
+ }
+#endif
+ pPager->pStmt = 0;
+ pPager->state = PAGER_SHARED;
+ return SQLITE_OK;
+ }
+ if( pPager->dirtyCache==0 ){
+ /* Exit early (without doing the time-consuming sqlite3OsSync() calls)
+ ** if there have been no changes to the database file. */
+ assert( pPager->needSync==0 );
+ rc = pager_unwritelock(pPager);
+ pPager->dbSize = -1;
+ return rc;
+ }
+ assert( pPager->journalOpen );
+ rc = sqlite3pager_sync(pPager, 0, 0);
+ if( rc!=SQLITE_OK ){
+ goto commit_abort;
+ }
+ rc = pager_unwritelock(pPager);
+ pPager->dbSize = -1;
+ return rc;
+
+ /* Jump here if anything goes wrong during the commit process.
+ */
+commit_abort:
+ sqlite3pager_rollback(pPager);
+ return rc;
+}
+
+/*
+** Rollback all changes. The database falls back to PAGER_SHARED mode.
+** All in-memory cache pages revert to their original data contents.
+** The journal is deleted.
+**
+** This routine cannot fail unless some other process is not following
+** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
+** process is writing trash into the journal file (SQLITE_CORRUPT) or
+** unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error
+** codes are returned for all these occasions. Otherwise,
+** SQLITE_OK is returned.
+*/
+int sqlite3pager_rollback(Pager *pPager){
+ int rc;
+ TRACE2("ROLLBACK %d\n", PAGERID(pPager));
+ if( MEMDB ){
+ PgHdr *p;
+ for(p=pPager->pAll; p; p=p->pNextAll){
+ PgHistory *pHist;
+ assert( !p->alwaysRollback );
+ if( !p->dirty ){
+ assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pOrig );
+ assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pStmt );
+ continue;
+ }
+
+ pHist = PGHDR_TO_HIST(p, pPager);
+ if( pHist->pOrig ){
+ memcpy(PGHDR_TO_DATA(p), pHist->pOrig, pPager->pageSize);
+ TRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager));
+ }else{
+ TRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager));
+ }
+ clearHistory(pHist);
+ p->dirty = 0;
+ p->inJournal = 0;
+ p->inStmt = 0;
+ p->pPrevStmt = p->pNextStmt = 0;
+
+ if( pPager->xReiniter ){
+ pPager->xReiniter(PGHDR_TO_DATA(p), pPager->pageSize);
+ }
+
+ }
+ pPager->pStmt = 0;
+ pPager->dbSize = pPager->origDbSize;
+ memoryTruncate(pPager);
+ pPager->stmtInUse = 0;
+ pPager->state = PAGER_SHARED;
+ return SQLITE_OK;
+ }
+
+ if( !pPager->dirtyCache || !pPager->journalOpen ){
+ rc = pager_unwritelock(pPager);
+ pPager->dbSize = -1;
+ return rc;
+ }
+
+ if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
+ if( pPager->state>=PAGER_EXCLUSIVE ){
+ pager_playback(pPager);
+ }
+ return pager_errcode(pPager);
+ }
+ if( pPager->state==PAGER_RESERVED ){
+ int rc2;
+ rc = pager_reload_cache(pPager);
+ rc2 = pager_unwritelock(pPager);
+ if( rc==SQLITE_OK ){
+ rc = rc2;
+ }
+ }else{
+ rc = pager_playback(pPager);
+ }
+ if( rc!=SQLITE_OK ){
+ rc = SQLITE_CORRUPT; /* bkpt-CORRUPT */
+ pPager->errMask |= PAGER_ERR_CORRUPT;
+ }
+ pPager->dbSize = -1;
+ return rc;
+}
+
+/*
+** Return TRUE if the database file is opened read-only. Return FALSE
+** if the database is (in theory) writable.
+*/
+int sqlite3pager_isreadonly(Pager *pPager){
+ return pPager->readOnly;
+}
+
+/*
+** This routine is used for testing and analysis only.
+*/
+int *sqlite3pager_stats(Pager *pPager){
+ static int a[11];
+ a[0] = pPager->nRef;
+ a[1] = pPager->nPage;
+ a[2] = pPager->mxPage;
+ a[3] = pPager->dbSize;
+ a[4] = pPager->state;
+ a[5] = pPager->errMask;
+#ifdef SQLITE_TEST
+ a[6] = pPager->nHit;
+ a[7] = pPager->nMiss;
+ a[8] = pPager->nOvfl;
+ a[9] = pPager->nRead;
+ a[10] = pPager->nWrite;
+#endif
+ return a;
+}
+
+/*
+** Set the statement rollback point.
+**
+** This routine should be called with the transaction journal already
+** open. A new statement journal is created that can be used to rollback
+** changes of a single SQL command within a larger transaction.
+*/
+int sqlite3pager_stmt_begin(Pager *pPager){
+ int rc;
+ char zTemp[SQLITE_TEMPNAME_SIZE];
+ assert( !pPager->stmtInUse );
+ assert( pPager->dbSize>=0 );
+ TRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
+ if( MEMDB ){
+ pPager->stmtInUse = 1;
+ pPager->stmtSize = pPager->dbSize;
+ return SQLITE_OK;
+ }
+ if( !pPager->journalOpen ){
+ pPager->stmtAutoopen = 1;
+ return SQLITE_OK;
+ }
+ assert( pPager->journalOpen );
+ pPager->aInStmt = sqliteMalloc( pPager->dbSize/8 + 1 );
+ if( pPager->aInStmt==0 ){
+ sqlite3OsLock(&pPager->fd, SHARED_LOCK);
+ return SQLITE_NOMEM;
+ }
+#ifndef NDEBUG
+ rc = sqlite3OsFileSize(&pPager->jfd, &pPager->stmtJSize);
+ if( rc ) goto stmt_begin_failed;
+ assert( pPager->stmtJSize == pPager->journalOff );
+#endif
+ pPager->stmtJSize = pPager->journalOff;
+ pPager->stmtSize = pPager->dbSize;
+ pPager->stmtHdrOff = 0;
+ pPager->stmtCksum = pPager->cksumInit;
+ if( !pPager->stmtOpen ){
+ rc = sqlite3pager_opentemp(zTemp, &pPager->stfd);
+ if( rc ) goto stmt_begin_failed;
+ pPager->stmtOpen = 1;
+ pPager->stmtNRec = 0;
+ }
+ pPager->stmtInUse = 1;
+ return SQLITE_OK;
+
+stmt_begin_failed:
+ if( pPager->aInStmt ){
+ sqliteFree(pPager->aInStmt);
+ pPager->aInStmt = 0;
+ }
+ return rc;
+}
+
+/*
+** Commit a statement.
+*/
+int sqlite3pager_stmt_commit(Pager *pPager){
+ if( pPager->stmtInUse ){
+ PgHdr *pPg, *pNext;
+ TRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
+ if( !MEMDB ){
+ sqlite3OsSeek(&pPager->stfd, 0);
+ /* sqlite3OsTruncate(&pPager->stfd, 0); */
+ sqliteFree( pPager->aInStmt );
+ pPager->aInStmt = 0;
+ }
+ for(pPg=pPager->pStmt; pPg; pPg=pNext){
+ pNext = pPg->pNextStmt;
+ assert( pPg->inStmt );
+ pPg->inStmt = 0;
+ pPg->pPrevStmt = pPg->pNextStmt = 0;
+ if( MEMDB ){
+ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+ sqliteFree(pHist->pStmt);
+ pHist->pStmt = 0;
+ }
+ }
+ pPager->stmtNRec = 0;
+ pPager->stmtInUse = 0;
+ pPager->pStmt = 0;
+ }
+ pPager->stmtAutoopen = 0;
+ return SQLITE_OK;
+}
+
+/*
+** Rollback a statement.
+*/
+int sqlite3pager_stmt_rollback(Pager *pPager){
+ int rc;
+ if( pPager->stmtInUse ){
+ TRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
+ if( MEMDB ){
+ PgHdr *pPg;
+ for(pPg=pPager->pStmt; pPg; pPg=pPg->pNextStmt){
+ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
+ if( pHist->pStmt ){
+ memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize);
+ sqliteFree(pHist->pStmt);
+ pHist->pStmt = 0;
+ }
+ }
+ pPager->dbSize = pPager->stmtSize;
+ memoryTruncate(pPager);
+ rc = SQLITE_OK;
+ }else{
+ rc = pager_stmt_playback(pPager);
+ }
+ sqlite3pager_stmt_commit(pPager);
+ }else{
+ rc = SQLITE_OK;
+ }
+ pPager->stmtAutoopen = 0;
+ return rc;
+}
+
+/*
+** Return the full pathname of the database file.
+*/
+const char *sqlite3pager_filename(Pager *pPager){
+ return pPager->zFilename;
+}
+
+/*
+** Return the directory of the database file.
+*/
+const char *sqlite3pager_dirname(Pager *pPager){
+ return pPager->zDirectory;
+}
+
+/*
+** Return the full pathname of the journal file.
+*/
+const char *sqlite3pager_journalname(Pager *pPager){
+ return pPager->zJournal;
+}
+
+/*
+** Set the codec for this pager
+*/
+void sqlite3pager_set_codec(
+ Pager *pPager,
+ void (*xCodec)(void*,void*,Pgno,int),
+ void *pCodecArg
+){
+ pPager->xCodec = xCodec;
+ pPager->pCodecArg = pCodecArg;
+}
+
+/*
+** This routine is called to increment the database file change-counter,
+** stored at byte 24 of the pager file.
+*/
+static int pager_incr_changecounter(Pager *pPager){
+ void *pPage;
+ PgHdr *pPgHdr;
+ u32 change_counter;
+ int rc;
+
+ /* Open page 1 of the file for writing. */
+ rc = sqlite3pager_get(pPager, 1, &pPage);
+ if( rc!=SQLITE_OK ) return rc;
+ rc = sqlite3pager_write(pPage);
+ if( rc!=SQLITE_OK ) return rc;
+
+ /* Read the current value at byte 24. */
+ pPgHdr = DATA_TO_PGHDR(pPage);
+ change_counter = retrieve32bits(pPgHdr, 24);
+
+ /* Increment the value just read and write it back to byte 24. */
+ change_counter++;
+ store32bits(change_counter, pPgHdr, 24);
+
+ /* Release the page reference. */
+ sqlite3pager_unref(pPage);
+ return SQLITE_OK;
+}
+
+/*
+** Sync the database file for the pager pPager. zMaster points to the name
+** of a master journal file that should be written into the individual
+** journal file. zMaster may be NULL, which is interpreted as no master
+** journal (a single database transaction).
+**
+** This routine ensures that the journal is synced, all dirty pages written
+** to the database file and the database file synced. The only thing that
+** remains to commit the transaction is to delete the journal file (or
+** master journal file if specified).
+**
+** Note that if zMaster==NULL, this does not overwrite a previous value
+** passed to an sqlite3pager_sync() call.
+**
+** If parameter nTrunc is non-zero, then the pager file is truncated to
+** nTrunc pages (this is used by auto-vacuum databases).
+*/
+int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){
+ int rc = SQLITE_OK;
+
+ TRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n",
+ pPager->zFilename, zMaster, nTrunc);
+
+ /* If this is an in-memory db, or no pages have been written to, or this
+ ** function has already been called, it is a no-op.
+ */
+ if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
+ PgHdr *pPg;
+ assert( pPager->journalOpen );
+
+ /* If a master journal file name has already been written to the
+ ** journal file, then no sync is required. This happens when it is
+ ** written, then the process fails to upgrade from a RESERVED to an
+ ** EXCLUSIVE lock. The next time the process tries to commit the
+ ** transaction the m-j name will have already been written.
+ */
+ if( !pPager->setMaster ){
+ rc = pager_incr_changecounter(pPager);
+ if( rc!=SQLITE_OK ) goto sync_exit;
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( nTrunc!=0 ){
+ /* If this transaction has made the database smaller, then all pages
+ ** being discarded by the truncation must be written to the journal
+ ** file.
+ */
+ Pgno i;
+ void *pPage;
+ for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
+ if( !(pPager->aInJournal[i/8] & (1<<(i&7))) ){
+ rc = sqlite3pager_get(pPager, i, &pPage);
+ if( rc!=SQLITE_OK ) goto sync_exit;
+ rc = sqlite3pager_write(pPage);
+ sqlite3pager_unref(pPage);
+ if( rc!=SQLITE_OK ) goto sync_exit;
+ }
+ }
+ }
+#endif
+ rc = writeMasterJournal(pPager, zMaster);
+ if( rc!=SQLITE_OK ) goto sync_exit;
+ rc = syncJournal(pPager);
+ if( rc!=SQLITE_OK ) goto sync_exit;
+ }
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( nTrunc!=0 ){
+ rc = sqlite3pager_truncate(pPager, nTrunc);
+ if( rc!=SQLITE_OK ) goto sync_exit;
+ }
+#endif
+
+ /* Write all dirty pages to the database file */
+ pPg = pager_get_all_dirty_pages(pPager);
+ rc = pager_write_pagelist(pPg);
+ if( rc!=SQLITE_OK ) goto sync_exit;
+
+ /* Sync the database file. */
+ if( !pPager->noSync ){
+ rc = sqlite3OsSync(&pPager->fd);
+ }
+
+ pPager->state = PAGER_SYNCED;
+ }
+
+sync_exit:
+ return rc;
+}
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+/*
+** Move the page identified by pData to location pgno in the file.
+**
+** There must be no references to the current page pgno. If current page
+** pgno is not already in the rollback journal, it is not written there by
+** by this routine. The same applies to the page pData refers to on entry to
+** this routine.
+**
+** References to the page refered to by pData remain valid. Updating any
+** meta-data associated with page pData (i.e. data stored in the nExtra bytes
+** allocated along with the page) is the responsibility of the caller.
+**
+** A transaction must be active when this routine is called. It used to be
+** required that a statement transaction was not active, but this restriction
+** has been removed (CREATE INDEX needs to move a page when a statement
+** transaction is active).
+*/
+int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ PgHdr *pPgOld;
+ int h;
+ Pgno needSyncPgno = 0;
+
+ assert( pPg->nRef>0 );
+
+ TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n",
+ PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);
+
+ if( pPg->needSync ){
+ needSyncPgno = pPg->pgno;
+ assert( pPg->inJournal );
+ assert( pPg->dirty );
+ assert( pPager->needSync );
+ }
+
+ /* Unlink pPg from it's hash-chain */
+ unlinkHashChain(pPager, pPg);
+
+ /* If the cache contains a page with page-number pgno, remove it
+ ** from it's hash chain. Also, if the PgHdr.needSync was set for
+ ** page pgno before the 'move' operation, it needs to be retained
+ ** for the page moved there.
+ */
+ pPgOld = pager_lookup(pPager, pgno);
+ if( pPgOld ){
+ assert( pPgOld->nRef==0 );
+ unlinkHashChain(pPager, pPgOld);
+ pPgOld->dirty = 0;
+ if( pPgOld->needSync ){
+ assert( pPgOld->inJournal );
+ pPg->inJournal = 1;
+ pPg->needSync = 1;
+ assert( pPager->needSync );
+ }
+ }
+
+ /* Change the page number for pPg and insert it into the new hash-chain. */
+ pPg->pgno = pgno;
+ h = pager_hash(pgno);
+ if( pPager->aHash[h] ){
+ assert( pPager->aHash[h]->pPrevHash==0 );
+ pPager->aHash[h]->pPrevHash = pPg;
+ }
+ pPg->pNextHash = pPager->aHash[h];
+ pPager->aHash[h] = pPg;
+ pPg->pPrevHash = 0;
+
+ pPg->dirty = 1;
+ pPager->dirtyCache = 1;
+
+ if( needSyncPgno ){
+ /* If needSyncPgno is non-zero, then the journal file needs to be
+ ** sync()ed before any data is written to database file page needSyncPgno.
+ ** Currently, no such page exists in the page-cache and the
+ ** Pager.aInJournal bit has been set. This needs to be remedied by loading
+ ** the page into the pager-cache and setting the PgHdr.needSync flag.
+ **
+ ** The sqlite3pager_get() call may cause the journal to sync. So make
+ ** sure the Pager.needSync flag is set too.
+ */
+ int rc;
+ void *pNeedSync;
+ assert( pPager->needSync );
+ rc = sqlite3pager_get(pPager, needSyncPgno, &pNeedSync);
+ if( rc!=SQLITE_OK ) return rc;
+ pPager->needSync = 1;
+ DATA_TO_PGHDR(pNeedSync)->needSync = 1;
+ DATA_TO_PGHDR(pNeedSync)->inJournal = 1;
+ DATA_TO_PGHDR(pNeedSync)->dirty = 1;
+ sqlite3pager_unref(pNeedSync);
+ }
+
+ return SQLITE_OK;
+}
+#endif
+
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+/*
+** Return the current state of the file lock for the given pager.
+** The return value is one of NO_LOCK, SHARED_LOCK, RESERVED_LOCK,
+** PENDING_LOCK, or EXCLUSIVE_LOCK.
+*/
+int sqlite3pager_lockstate(Pager *pPager){
+#ifdef OS_TEST
+ return pPager->fd->fd.locktype;
+#else
+ return pPager->fd.locktype;
+#endif
+}
+#endif
+
+#ifdef SQLITE_DEBUG
+/*
+** Print a listing of all referenced pages and their ref count.
+*/
+void sqlite3pager_refdump(Pager *pPager){
+ PgHdr *pPg;
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ if( pPg->nRef<=0 ) continue;
+ sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n",
+ pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef);
+ }
+}
+#endif
+
+#endif /* SQLITE_OMIT_DISKIO */
diff --git a/src/sqlite/pager.h b/src/sqlite/pager.h
new file mode 100644
index 0000000..580f26e
--- /dev/null
+++ b/src/sqlite/pager.h
@@ -0,0 +1,115 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the interface that the sqlite page cache
+** subsystem. The page cache subsystem reads and writes a file a page
+** at a time and provides a journal for rollback.
+**
+** @(#) $Id: pager.h,v 1.1.1.1 2006/02/03 20:35:17 hoganrobert Exp $
+*/
+
+/*
+** The default size of a database page.
+*/
+#ifndef SQLITE_DEFAULT_PAGE_SIZE
+# define SQLITE_DEFAULT_PAGE_SIZE 1024
+#endif
+
+/* Maximum page size. The upper bound on this value is 32768. This a limit
+** imposed by necessity of storing the value in a 2-byte unsigned integer
+** and the fact that the page size must be a power of 2.
+**
+** This value is used to initialize certain arrays on the stack at
+** various places in the code. On embedded machines where stack space
+** is limited and the flexibility of having large pages is not needed,
+** it makes good sense to reduce the maximum page size to something more
+** reasonable, like 1024.
+*/
+#ifndef SQLITE_MAX_PAGE_SIZE
+# define SQLITE_MAX_PAGE_SIZE 8192
+#endif
+
+/*
+** Maximum number of pages in one database.
+*/
+#define SQLITE_MAX_PAGE 1073741823
+
+/*
+** The type used to represent a page number. The first page in a file
+** is called page 1. 0 is used to represent "not a page".
+*/
+typedef unsigned int Pgno;
+
+/*
+** Each open file is managed by a separate instance of the "Pager" structure.
+*/
+typedef struct Pager Pager;
+
+/*
+** Allowed values for the flags parameter to sqlite3pager_open().
+**
+** NOTE: This values must match the corresponding BTREE_ values in btree.h.
+*/
+#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */
+#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */
+
+
+/*
+** See source code comments for a detailed description of the following
+** routines:
+*/
+int sqlite3pager_open(Pager **ppPager, const char *zFilename,
+ int nExtra, int flags);
+void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
+void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
+void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
+int sqlite3pager_set_pagesize(Pager*, int);
+void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
+void sqlite3pager_set_cachesize(Pager*, int);
+int sqlite3pager_close(Pager *pPager);
+int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
+void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
+int sqlite3pager_ref(void*);
+int sqlite3pager_unref(void*);
+Pgno sqlite3pager_pagenumber(void*);
+int sqlite3pager_write(void*);
+int sqlite3pager_iswriteable(void*);
+int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*);
+int sqlite3pager_pagecount(Pager*);
+int sqlite3pager_truncate(Pager*,Pgno);
+int sqlite3pager_begin(void*, int exFlag);
+int sqlite3pager_commit(Pager*);
+int sqlite3pager_sync(Pager*,const char *zMaster, Pgno);
+int sqlite3pager_rollback(Pager*);
+int sqlite3pager_isreadonly(Pager*);
+int sqlite3pager_stmt_begin(Pager*);
+int sqlite3pager_stmt_commit(Pager*);
+int sqlite3pager_stmt_rollback(Pager*);
+void sqlite3pager_dont_rollback(void*);
+void sqlite3pager_dont_write(Pager*, Pgno);
+int *sqlite3pager_stats(Pager*);
+void sqlite3pager_set_safety_level(Pager*,int);
+const char *sqlite3pager_filename(Pager*);
+const char *sqlite3pager_dirname(Pager*);
+const char *sqlite3pager_journalname(Pager*);
+int sqlite3pager_rename(Pager*, const char *zNewName);
+void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
+int sqlite3pager_movepage(Pager*,void*,Pgno);
+int sqlite3pager_reset(Pager*);
+
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+int sqlite3pager_lockstate(Pager*);
+#endif
+
+#ifdef SQLITE_TEST
+void sqlite3pager_refdump(Pager*);
+int pager3_refinfo_enable;
+#endif
diff --git a/src/sqlite/parse.c b/src/sqlite/parse.c
new file mode 100644
index 0000000..0c387f2
--- /dev/null
+++ b/src/sqlite/parse.c
@@ -0,0 +1,3355 @@
+/* Driver template for the LEMON parser generator.
+** The author disclaims copyright to this source code.
+*/
+/* First off, code is include which follows the "include" declaration
+** in the input file. */
+#include <stdio.h>
+#line 33 "parse.y"
+
+#include "sqliteInt.h"
+#include "parse.h"
+
+/*
+** An instance of this structure holds information about the
+** LIMIT clause of a SELECT statement.
+*/
+struct LimitVal {
+ Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
+ Expr *pOffset; /* The OFFSET expression. NULL if there is none */
+};
+
+/*
+** An instance of this structure is used to store the LIKE,
+** GLOB, NOT LIKE, and NOT GLOB operators.
+*/
+struct LikeOp {
+ Token operator; /* "like" or "glob" or "regexp" */
+ int not; /* True if the NOT keyword is present */
+};
+
+/*
+** An instance of the following structure describes the event of a
+** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
+** TK_DELETE, or TK_INSTEAD. If the event is of the form
+**
+** UPDATE ON (a,b,c)
+**
+** Then the "b" IdList records the list "a,b,c".
+*/
+struct TrigEvent { int a; IdList * b; };
+
+/*
+** An instance of this structure holds the ATTACH key and the key type.
+*/
+struct AttachKey { int type; Token key; };
+
+#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.
+*/
+/*
+** These constants (all generated automatically by the parser generator)
+** specify the various kinds of tokens (terminals) that the parser
+** understands.
+**
+** Each symbol here is a terminal symbol in the grammar.
+*/
+/* Make sure the INTERFACE macro is defined.
+*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/* The next thing included is series of defines which control
+** various aspects of the generated parser.
+** YYCODETYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 terminals
+** and nonterminals. "int" is used otherwise.
+** YYNOCODE is a number of type YYCODETYPE which corresponds
+** to no legal terminal or nonterminal number. This
+** number is used to fill in empty slots of the hash
+** table.
+** YYFALLBACK If defined, this indicates that one or more tokens
+** have fall-back values which should be used if the
+** original value of the token will not parse.
+** YYACTIONTYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 rules and
+** states combined. "int" is used otherwise.
+** sqlite3ParserTOKENTYPE is the data type used for minor tokens given
+** directly to the parser from the tokenizer.
+** YYMINORTYPE is the data type used for all minor tokens.
+** This is typically a union of many types, one of
+** which is sqlite3ParserTOKENTYPE. The entry in the union
+** for base tokens is called "yy0".
+** YYSTACKDEPTH is the maximum depth of the parser's stack.
+** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument
+** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument
+** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser
+** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser
+** YYNSTATE the combined number of states.
+** YYNRULE the number of rules in the grammar
+** YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+*/
+#define YYCODETYPE unsigned char
+#define YYNOCODE 241
+#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;
+} 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 YYFALLBACK 1
+#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
+#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
+#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
+
+/* Next are that tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
+** token onto the stack and goto state N.
+**
+** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
+**
+** N == YYNSTATE+YYNRULE A syntax error has occurred.
+**
+** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
+**
+** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
+** slots in the yy_action[] table.
+**
+** The action table is constructed as a single large table named yy_action[].
+** Given state S and lookahead X, the action is computed as
+**
+** yy_action[ yy_shift_ofst[S] + X ]
+**
+** If the index value yy_shift_ofst[S]+X is out of range or if the value
+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
+** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
+** and that yy_default[S] should be used instead.
+**
+** The formula above is for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the yy_reduce_ofst[] array is used in place of
+** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
+** YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** yy_action[] A single table containing all actions.
+** yy_lookahead[] A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** yy_shift_ofst[] For each state, the offset into yy_action for
+** shifting terminals.
+** yy_reduce_ofst[] For each state, the offset into yy_action for
+** shifting non-terminals after a reduce.
+** 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,
+};
+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,
+ /* 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,
+};
+#define YY_SHIFT_USE_DFLT (-70)
+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,
+};
+#define YY_REDUCE_USE_DFLT (-71)
+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,
+};
+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,
+};
+#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
+
+/* The next table maps tokens into fallback tokens. If a construct
+** like the following:
+**
+** %fallback ID X Y Z.
+**
+** appears in the grammer, then ID becomes a fallback token for X, Y,
+** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+** but it does not parse, the type of the token is changed to ID and
+** the parse is retried before an error is thrown.
+*/
+#ifdef YYFALLBACK
+static const YYCODETYPE yyFallback[] = {
+ 0, /* $ => nothing */
+ 0, /* END_OF_FILE => nothing */
+ 0, /* ILLEGAL => nothing */
+ 0, /* SPACE => nothing */
+ 0, /* UNCLOSED_STRING => nothing */
+ 0, /* COMMENT => nothing */
+ 0, /* FUNCTION => nothing */
+ 0, /* COLUMN => nothing */
+ 0, /* AGG_FUNCTION => nothing */
+ 0, /* CONST_FUNC => nothing */
+ 0, /* SEMI => nothing */
+ 27, /* EXPLAIN => ID */
+ 27, /* BEGIN => ID */
+ 0, /* TRANSACTION => nothing */
+ 27, /* DEFERRED => ID */
+ 27, /* IMMEDIATE => ID */
+ 27, /* EXCLUSIVE => ID */
+ 0, /* COMMIT => nothing */
+ 27, /* END => ID */
+ 0, /* ROLLBACK => nothing */
+ 0, /* CREATE => nothing */
+ 0, /* TABLE => nothing */
+ 27, /* TEMP => ID */
+ 0, /* LP => nothing */
+ 0, /* RP => nothing */
+ 0, /* AS => nothing */
+ 0, /* COMMA => nothing */
+ 0, /* ID => nothing */
+ 27, /* ABORT => ID */
+ 27, /* AFTER => ID */
+ 27, /* ASC => ID */
+ 27, /* ATTACH => ID */
+ 27, /* BEFORE => ID */
+ 27, /* CASCADE => ID */
+ 27, /* CONFLICT => ID */
+ 27, /* DATABASE => ID */
+ 27, /* DESC => ID */
+ 27, /* DETACH => ID */
+ 27, /* EACH => ID */
+ 27, /* FAIL => ID */
+ 27, /* FOR => ID */
+ 27, /* IGNORE => ID */
+ 27, /* INITIALLY => ID */
+ 27, /* INSTEAD => ID */
+ 27, /* LIKE_KW => ID */
+ 27, /* MATCH => ID */
+ 27, /* KEY => ID */
+ 27, /* OF => ID */
+ 27, /* OFFSET => ID */
+ 27, /* PRAGMA => ID */
+ 27, /* RAISE => ID */
+ 27, /* REPLACE => ID */
+ 27, /* RESTRICT => ID */
+ 27, /* ROW => ID */
+ 27, /* STATEMENT => ID */
+ 27, /* TRIGGER => ID */
+ 27, /* VACUUM => ID */
+ 27, /* VIEW => ID */
+ 27, /* REINDEX => ID */
+ 27, /* RENAME => ID */
+ 27, /* CTIME_KW => ID */
+ 27, /* ALTER => ID */
+ 0, /* OR => nothing */
+ 0, /* AND => nothing */
+ 0, /* NOT => nothing */
+ 0, /* IS => nothing */
+ 0, /* BETWEEN => nothing */
+ 0, /* IN => nothing */
+ 0, /* ISNULL => nothing */
+ 0, /* NOTNULL => nothing */
+ 0, /* NE => nothing */
+ 0, /* EQ => nothing */
+ 0, /* GT => nothing */
+ 0, /* LE => nothing */
+ 0, /* LT => nothing */
+ 0, /* GE => nothing */
+ 0, /* ESCAPE => nothing */
+ 0, /* BITAND => nothing */
+ 0, /* BITOR => nothing */
+ 0, /* LSHIFT => nothing */
+ 0, /* RSHIFT => nothing */
+ 0, /* PLUS => nothing */
+ 0, /* MINUS => nothing */
+ 0, /* STAR => nothing */
+ 0, /* SLASH => nothing */
+ 0, /* REM => nothing */
+ 0, /* CONCAT => nothing */
+ 0, /* UMINUS => nothing */
+ 0, /* UPLUS => nothing */
+ 0, /* BITNOT => nothing */
+ 0, /* STRING => nothing */
+ 0, /* JOIN_KW => nothing */
+ 0, /* CONSTRAINT => nothing */
+ 0, /* DEFAULT => nothing */
+ 0, /* NULL => nothing */
+ 0, /* PRIMARY => nothing */
+ 0, /* UNIQUE => nothing */
+ 0, /* CHECK => nothing */
+ 0, /* REFERENCES => nothing */
+ 0, /* COLLATE => nothing */
+ 0, /* AUTOINCR => nothing */
+ 0, /* ON => nothing */
+ 0, /* DELETE => nothing */
+ 0, /* UPDATE => nothing */
+ 0, /* INSERT => nothing */
+ 0, /* SET => nothing */
+ 0, /* DEFERRABLE => nothing */
+ 0, /* FOREIGN => nothing */
+ 0, /* DROP => nothing */
+ 0, /* UNION => nothing */
+ 0, /* ALL => nothing */
+ 0, /* INTERSECT => nothing */
+ 0, /* EXCEPT => nothing */
+ 0, /* SELECT => nothing */
+ 0, /* DISTINCT => nothing */
+ 0, /* DOT => nothing */
+ 0, /* FROM => nothing */
+ 0, /* JOIN => nothing */
+ 0, /* USING => nothing */
+ 0, /* ORDER => nothing */
+ 0, /* BY => nothing */
+ 0, /* GROUP => nothing */
+ 0, /* HAVING => nothing */
+ 0, /* LIMIT => nothing */
+ 0, /* WHERE => nothing */
+ 0, /* INTO => nothing */
+ 0, /* VALUES => nothing */
+ 0, /* INTEGER => nothing */
+ 0, /* FLOAT => nothing */
+ 0, /* BLOB => nothing */
+ 0, /* REGISTER => nothing */
+ 0, /* VARIABLE => nothing */
+ 0, /* EXISTS => nothing */
+ 0, /* CASE => nothing */
+ 0, /* WHEN => nothing */
+ 0, /* THEN => nothing */
+ 0, /* ELSE => nothing */
+ 0, /* INDEX => nothing */
+ 0, /* TO => nothing */
+ 0, /* ADD => nothing */
+ 0, /* COLUMNKW => nothing */
+};
+#endif /* YYFALLBACK */
+
+/* The following structure represents a single element of the
+** parser's stack. Information stored includes:
+**
+** + The state number for the parser at this level of the stack.
+**
+** + The value of the token stored at this level of the stack.
+** (In other words, the "major" token.)
+**
+** + The semantic value stored at this level of the stack. This is
+** the information used by the action routines in the grammar.
+** It is sometimes called the "minor" token.
+*/
+struct yyStackEntry {
+ int stateno; /* The state-number */
+ int major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+typedef struct yyStackEntry yyStackEntry;
+
+/* The state of the parser is completely contained in an instance of
+** the following structure */
+struct yyParser {
+ int yyidx; /* Index of top element in stack */
+ int yyerrcnt; /* Shifts left before out of the error */
+ sqlite3ParserARG_SDECL /* A place to hold %extra_argument */
+ yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
+};
+typedef struct yyParser yyParser;
+
+#ifndef NDEBUG
+#include <stdio.h>
+static FILE *yyTraceFILE = 0;
+static char *yyTracePrompt = 0;
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/*
+** Turn parser tracing on by giving a stream to which to write the trace
+** and a prompt to preface each trace message. Tracing is turned off
+** by making either argument NULL
+**
+** Inputs:
+** <ul>
+** <li> A FILE* to which trace output should be written.
+** If NULL, then tracing is turned off.
+** <li> A prefix string written at the beginning of every
+** line of trace output. If NULL, then tracing is
+** turned off.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){
+ yyTraceFILE = TraceFILE;
+ yyTracePrompt = zTracePrompt;
+ if( yyTraceFILE==0 ) yyTracePrompt = 0;
+ else if( yyTracePrompt==0 ) yyTraceFILE = 0;
+}
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing shifts, the names of all terminals and nonterminals
+** are required. The following table supplies these names */
+static const char *const yyTokenName[] = {
+ "$", "END_OF_FILE", "ILLEGAL", "SPACE",
+ "UNCLOSED_STRING", "COMMENT", "FUNCTION", "COLUMN",
+ "AGG_FUNCTION", "CONST_FUNC", "SEMI", "EXPLAIN",
+ "BEGIN", "TRANSACTION", "DEFERRED", "IMMEDIATE",
+ "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",
+};
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing reduce actions, the names of all rules are required.
+*/
+static const char *const yyRuleName[] = {
+ /* 0 */ "input ::= cmdlist",
+ /* 1 */ "cmdlist ::= cmdlist ecmd",
+ /* 2 */ "cmdlist ::= ecmd",
+ /* 3 */ "cmdx ::= cmd",
+ /* 4 */ "ecmd ::= SEMI",
+ /* 5 */ "ecmd ::= explain cmdx SEMI",
+ /* 6 */ "explain ::=",
+ /* 7 */ "explain ::= EXPLAIN",
+ /* 8 */ "cmd ::= BEGIN transtype trans_opt",
+ /* 9 */ "trans_opt ::=",
+ /* 10 */ "trans_opt ::= TRANSACTION",
+ /* 11 */ "trans_opt ::= TRANSACTION nm",
+ /* 12 */ "transtype ::=",
+ /* 13 */ "transtype ::= DEFERRED",
+ /* 14 */ "transtype ::= IMMEDIATE",
+ /* 15 */ "transtype ::= EXCLUSIVE",
+ /* 16 */ "cmd ::= COMMIT trans_opt",
+ /* 17 */ "cmd ::= END trans_opt",
+ /* 18 */ "cmd ::= ROLLBACK trans_opt",
+ /* 19 */ "cmd ::= create_table create_table_args",
+ /* 20 */ "create_table ::= CREATE temp TABLE nm dbnm",
+ /* 21 */ "temp ::= TEMP",
+ /* 22 */ "temp ::=",
+ /* 23 */ "create_table_args ::= LP columnlist conslist_opt RP",
+ /* 24 */ "create_table_args ::= AS select",
+ /* 25 */ "columnlist ::= columnlist COMMA column",
+ /* 26 */ "columnlist ::= column",
+ /* 27 */ "column ::= columnid type carglist",
+ /* 28 */ "columnid ::= nm",
+ /* 29 */ "id ::= ID",
+ /* 30 */ "ids ::= ID",
+ /* 31 */ "ids ::= STRING",
+ /* 32 */ "nm ::= ID",
+ /* 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",
+};
+#endif /* NDEBUG */
+
+/*
+** This function returns the symbolic name associated with a token
+** value.
+*/
+const char *sqlite3ParserTokenName(int tokenType){
+#ifndef NDEBUG
+ if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
+ return yyTokenName[tokenType];
+ }else{
+ return "Unknown";
+ }
+#else
+ return "";
+#endif
+}
+
+/*
+** This function allocates a new parser.
+** The only argument is a pointer to a function which works like
+** malloc.
+**
+** Inputs:
+** A pointer to the function used to allocate memory.
+**
+** Outputs:
+** A pointer to a parser. This pointer is used in subsequent calls
+** to sqlite3Parser and sqlite3ParserFree.
+*/
+void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
+ yyParser *pParser;
+ pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
+ if( pParser ){
+ pParser->yyidx = -1;
+ }
+ return pParser;
+}
+
+/* The following function deletes the value associated with a
+** symbol. The symbol can be either a terminal or nonterminal.
+** "yymajor" is the symbol code, and "yypminor" is a pointer to
+** the value.
+*/
+static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
+ switch( yymajor ){
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** 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 "parse.y"
+{sqlite3SelectDelete((yypminor->yy459));}
+#line 1301 "parse.c"
+ break;
+ case 170:
+ case 174:
+ case 194:
+ case 196:
+ case 204:
+ case 210:
+ case 224:
+#line 593 "parse.y"
+{sqlite3ExprDelete((yypminor->yy2));}
+#line 1312 "parse.c"
+ break;
+ case 175:
+ case 183:
+ case 192:
+ case 195:
+ case 197:
+ case 199:
+ case 209:
+ case 212:
+ case 213:
+ case 216:
+ case 222:
+#line 812 "parse.y"
+{sqlite3ExprListDelete((yypminor->yy82));}
+#line 1327 "parse.c"
+ break;
+ case 188:
+ case 193:
+ case 201:
+ case 202:
+#line 463 "parse.y"
+{sqlite3SrcListDelete((yypminor->yy67));}
+#line 1335 "parse.c"
+ break;
+ case 198:
+#line 525 "parse.y"
+{
+ sqlite3ExprDelete((yypminor->yy244).pLimit);
+ sqlite3ExprDelete((yypminor->yy244).pOffset);
+}
+#line 1343 "parse.c"
+ break;
+ case 205:
+ case 208:
+ case 215:
+#line 481 "parse.y"
+{sqlite3IdListDelete((yypminor->yy240));}
+#line 1350 "parse.c"
+ break;
+ case 230:
+ case 235:
+#line 905 "parse.y"
+{sqlite3DeleteTriggerStep((yypminor->yy347));}
+#line 1356 "parse.c"
+ break;
+ case 232:
+#line 889 "parse.y"
+{sqlite3IdListDelete((yypminor->yy210).b);}
+#line 1361 "parse.c"
+ break;
+ default: break; /* If no destructor action specified: do nothing */
+ }
+}
+
+/*
+** Pop the parser's stack once.
+**
+** If there is a destructor routine associated with the token which
+** is popped from the stack, then call it.
+**
+** Return the major token number for the symbol popped.
+*/
+static int yy_pop_parser_stack(yyParser *pParser){
+ YYCODETYPE yymajor;
+ yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
+
+ if( pParser->yyidx<0 ) return 0;
+#ifndef NDEBUG
+ if( yyTraceFILE && pParser->yyidx>=0 ){
+ fprintf(yyTraceFILE,"%sPopping %s\n",
+ yyTracePrompt,
+ yyTokenName[yytos->major]);
+ }
+#endif
+ yymajor = yytos->major;
+ yy_destructor( yymajor, &yytos->minor);
+ pParser->yyidx--;
+ return yymajor;
+}
+
+/*
+** Deallocate and destroy a parser. Destructors are all called for
+** all stack elements before shutting the parser down.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser. This should be a pointer
+** obtained from sqlite3ParserAlloc.
+** <li> A pointer to a function used to reclaim memory obtained
+** from malloc.
+** </ul>
+*/
+void sqlite3ParserFree(
+ void *p, /* The parser to be deleted */
+ void (*freeProc)(void*) /* Function used to reclaim memory */
+){
+ yyParser *pParser = (yyParser*)p;
+ if( pParser==0 ) return;
+ while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
+ (*freeProc)((void*)pParser);
+}
+
+/*
+** Find the appropriate action for a parser given the terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_find_shift_action(
+ yyParser *pParser, /* The parser */
+ int iLookAhead /* The look-ahead token */
+){
+ int i;
+ int stateno = pParser->yystack[pParser->yyidx].stateno;
+
+ /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */
+ i = yy_shift_ofst[stateno];
+ if( i==YY_SHIFT_USE_DFLT ){
+ return yy_default[stateno];
+ }
+ if( iLookAhead==YYNOCODE ){
+ return YY_NO_ACTION;
+ }
+ i += iLookAhead;
+ if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
+#ifdef YYFALLBACK
+ int iFallback; /* Fallback token */
+ if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+ && (iFallback = yyFallback[iLookAhead])!=0 ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+ }
+#endif
+ return yy_find_shift_action(pParser, iFallback);
+ }
+#endif
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
+ }
+}
+
+/*
+** Find the appropriate action for a parser given the non-terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_find_reduce_action(
+ int stateno, /* Current state number */
+ int iLookAhead /* The look-ahead token */
+){
+ int i;
+ /* int stateno = pParser->yystack[pParser->yyidx].stateno; */
+
+ i = yy_reduce_ofst[stateno];
+ if( i==YY_REDUCE_USE_DFLT ){
+ return yy_default[stateno];
+ }
+ if( iLookAhead==YYNOCODE ){
+ return YY_NO_ACTION;
+ }
+ i += iLookAhead;
+ if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
+ }
+}
+
+/*
+** Perform a shift action.
+*/
+static void yy_shift(
+ yyParser *yypParser, /* The parser to be shifted */
+ int yyNewState, /* The new state to shift in */
+ int yyMajor, /* The major token to shift in */
+ YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
+){
+ yyStackEntry *yytos;
+ yypParser->yyidx++;
+ if( yypParser->yyidx>=YYSTACKDEPTH ){
+ sqlite3ParserARG_FETCH;
+ yypParser->yyidx--;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will execute if the parser
+ ** stack every overflows */
+ sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
+ return;
+ }
+ yytos = &yypParser->yystack[yypParser->yyidx];
+ yytos->stateno = yyNewState;
+ yytos->major = yyMajor;
+ yytos->minor = *yypMinor;
+#ifndef NDEBUG
+ if( yyTraceFILE && yypParser->yyidx>0 ){
+ int i;
+ fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
+ fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
+ for(i=1; i<=yypParser->yyidx; i++)
+ fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
+ fprintf(yyTraceFILE,"\n");
+ }
+#endif
+}
+
+/* The following table contains information about every rule that
+** is used during the reduce.
+*/
+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 },
+ { 147, 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 },
+ { 150, 1 },
+ { 150, 1 },
+ { 150, 1 },
+ { 160, 0 },
+ { 160, 1 },
+ { 160, 4 },
+ { 160, 6 },
+ { 164, 1 },
+ { 164, 2 },
+ { 165, 1 },
+ { 165, 1 },
+ { 161, 2 },
+ { 161, 0 },
+ { 168, 3 },
+ { 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 },
+ { 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 },
+ { 182, 2 },
+ { 182, 7 },
+ { 182, 5 },
+ { 182, 3 },
+ { 182, 10 },
+ { 184, 0 },
+ { 184, 1 },
+ { 171, 0 },
+ { 171, 3 },
+ { 185, 0 },
+ { 185, 2 },
+ { 186, 1 },
+ { 186, 1 },
+ { 186, 1 },
+ { 146, 3 },
+ { 146, 7 },
+ { 146, 3 },
+ { 146, 1 },
+ { 157, 1 },
+ { 157, 3 },
+ { 190, 1 },
+ { 190, 2 },
+ { 190, 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 },
+ { 193, 2 },
+ { 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 },
+ { 196, 0 },
+ { 196, 2 },
+ { 198, 0 },
+ { 198, 2 },
+ { 198, 4 },
+ { 198, 4 },
+ { 146, 4 },
+ { 194, 0 },
+ { 194, 2 },
+ { 146, 6 },
+ { 213, 5 },
+ { 213, 3 },
+ { 146, 8 },
+ { 146, 5 },
+ { 214, 2 },
+ { 214, 1 },
+ { 216, 3 },
+ { 216, 1 },
+ { 215, 0 },
+ { 215, 3 },
+ { 208, 3 },
+ { 208, 1 },
+ { 174, 1 },
+ { 174, 3 },
+ { 170, 1 },
+ { 174, 1 },
+ { 174, 1 },
+ { 174, 3 },
+ { 174, 5 },
+ { 170, 1 },
+ { 170, 1 },
+ { 170, 1 },
+ { 170, 1 },
+ { 174, 1 },
+ { 174, 1 },
+ { 174, 4 },
+ { 174, 4 },
+ { 170, 1 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 3 },
+ { 217, 1 },
+ { 217, 2 },
+ { 218, 2 },
+ { 218, 0 },
+ { 174, 4 },
+ { 174, 2 },
+ { 174, 3 },
+ { 174, 2 },
+ { 174, 3 },
+ { 174, 4 },
+ { 174, 2 },
+ { 174, 2 },
+ { 174, 2 },
+ { 174, 2 },
+ { 219, 1 },
+ { 219, 2 },
+ { 174, 5 },
+ { 220, 1 },
+ { 220, 2 },
+ { 174, 5 },
+ { 174, 3 },
+ { 174, 5 },
+ { 174, 4 },
+ { 174, 4 },
+ { 174, 5 },
+ { 222, 5 },
+ { 222, 4 },
+ { 223, 2 },
+ { 223, 0 },
+ { 221, 1 },
+ { 221, 0 },
+ { 212, 3 },
+ { 212, 1 },
+ { 224, 1 },
+ { 224, 0 },
+ { 146, 11 },
+ { 225, 1 },
+ { 225, 0 },
+ { 175, 0 },
+ { 175, 3 },
+ { 183, 5 },
+ { 183, 3 },
+ { 226, 1 },
+ { 146, 3 },
+ { 146, 1 },
+ { 146, 2 },
+ { 146, 5 },
+ { 146, 5 },
+ { 146, 5 },
+ { 146, 5 },
+ { 146, 6 },
+ { 146, 3 },
+ { 166, 2 },
+ { 167, 2 },
+ { 228, 1 },
+ { 228, 1 },
+ { 227, 1 },
+ { 227, 0 },
+ { 146, 5 },
+ { 229, 10 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 2 },
+ { 231, 0 },
+ { 232, 1 },
+ { 232, 1 },
+ { 232, 1 },
+ { 232, 3 },
+ { 233, 0 },
+ { 233, 3 },
+ { 233, 3 },
+ { 234, 0 },
+ { 234, 2 },
+ { 230, 3 },
+ { 230, 0 },
+ { 235, 6 },
+ { 235, 8 },
+ { 235, 5 },
+ { 235, 4 },
+ { 235, 1 },
+ { 174, 4 },
+ { 174, 6 },
+ { 187, 1 },
+ { 187, 1 },
+ { 187, 1 },
+ { 146, 3 },
+ { 146, 6 },
+ { 237, 0 },
+ { 237, 2 },
+ { 237, 2 },
+ { 236, 1 },
+ { 236, 0 },
+ { 146, 3 },
+ { 146, 1 },
+ { 146, 3 },
+ { 146, 6 },
+ { 146, 6 },
+ { 238, 1 },
+ { 239, 0 },
+ { 239, 1 },
+};
+
+static void yy_accept(yyParser*); /* Forward Declaration */
+
+/*
+** Perform a reduce action and the shift that must immediately
+** follow the reduce.
+*/
+static void yy_reduce(
+ yyParser *yypParser, /* The parser */
+ int yyruleno /* Number of the rule by which to reduce */
+){
+ int yygoto; /* The next state */
+ int yyact; /* The next action */
+ YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
+ yyStackEntry *yymsp; /* The top of the parser's stack */
+ int yysize; /* Amount to pop the stack */
+ sqlite3ParserARG_FETCH;
+ yymsp = &yypParser->yystack[yypParser->yyidx];
+#ifndef NDEBUG
+ if( yyTraceFILE && yyruleno>=0
+ && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
+ fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
+ yyRuleName[yyruleno]);
+ }
+#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:
+ ** case 0:
+ ** #line <lineno> <grammarfile>
+ ** { ... } // User supplied code
+ ** #line <lineno> <thisfile>
+ ** break;
+ */
+ case 3:
+#line 84 "parse.y"
+{ sqlite3FinishCoding(pParse); }
+#line 1893 "parse.c"
+ break;
+ case 6:
+#line 87 "parse.y"
+{ sqlite3BeginParse(pParse, 0); }
+#line 1898 "parse.c"
+ break;
+ case 7:
+#line 89 "parse.y"
+{ sqlite3BeginParse(pParse, 1); }
+#line 1903 "parse.c"
+ break;
+ case 8:
+#line 95 "parse.y"
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy412);}
+#line 1908 "parse.c"
+ break;
+ case 12:
+#line 100 "parse.y"
+{yygotominor.yy412 = TK_DEFERRED;}
+#line 1913 "parse.c"
+ break;
+ case 13:
+ case 14:
+ case 15:
+ case 101:
+ case 103:
+ case 104:
+#line 101 "parse.y"
+{yygotominor.yy412 = yymsp[0].major;}
+#line 1923 "parse.c"
+ break;
+ case 16:
+ case 17:
+#line 104 "parse.y"
+{sqlite3CommitTransaction(pParse);}
+#line 1929 "parse.c"
+ break;
+ case 18:
+#line 106 "parse.y"
+{sqlite3RollbackTransaction(pParse);}
+#line 1934 "parse.c"
+ break;
+ case 20:
+#line 111 "parse.y"
+{
+ sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258,yymsp[-3].minor.yy412,0);
+}
+#line 1941 "parse.c"
+ break;
+ case 21:
+ case 60:
+ case 74:
+ case 106:
+ case 220:
+ case 223:
+#line 116 "parse.y"
+{yygotominor.yy412 = 1;}
+#line 1951 "parse.c"
+ break;
+ case 22:
+ case 59:
+ case 73:
+ case 75:
+ case 86:
+ case 107:
+ case 108:
+ case 219:
+ case 222:
+#line 118 "parse.y"
+{yygotominor.yy412 = 0;}
+#line 1964 "parse.c"
+ break;
+ case 23:
+#line 119 "parse.y"
+{
+ sqlite3EndTable(pParse,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy0,0);
+}
+#line 1971 "parse.c"
+ break;
+ case 24:
+#line 122 "parse.y"
+{
+ sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy459);
+ sqlite3SelectDelete(yymsp[0].minor.yy459);
+}
+#line 1979 "parse.c"
+ break;
+ case 27:
+#line 133 "parse.y"
+{
+ yygotominor.yy258.z = yymsp[-2].minor.yy258.z;
+ yygotominor.yy258.n = (pParse->sLastToken.z-yymsp[-2].minor.yy258.z) + pParse->sLastToken.n;
+}
+#line 1987 "parse.c"
+ break;
+ case 28:
+#line 137 "parse.y"
+{
+ sqlite3AddColumn(pParse,&yymsp[0].minor.yy258);
+ yygotominor.yy258 = yymsp[0].minor.yy258;
+}
+#line 1995 "parse.c"
+ break;
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 259:
+ case 260:
+#line 147 "parse.y"
+{yygotominor.yy258 = yymsp[0].minor.yy0;}
+#line 2007 "parse.c"
+ break;
+ case 36:
+#line 202 "parse.y"
+{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy258,&yymsp[0].minor.yy258);}
+#line 2012 "parse.c"
+ break;
+ case 37:
+#line 203 "parse.y"
+{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy258,&yymsp[0].minor.yy0);}
+#line 2017 "parse.c"
+ break;
+ case 38:
+#line 205 "parse.y"
+{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy258,&yymsp[0].minor.yy0);}
+#line 2022 "parse.c"
+ break;
+ case 39:
+ case 114:
+ case 115:
+ case 126:
+ case 146:
+ case 247:
+ case 257:
+ case 258:
+#line 207 "parse.y"
+{yygotominor.yy258 = yymsp[0].minor.yy258;}
+#line 2034 "parse.c"
+ break;
+ case 40:
+#line 208 "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 "parse.c"
+ break;
+ case 41:
+#line 210 "parse.y"
+{ yygotominor.yy412 = atoi(yymsp[0].minor.yy258.z); }
+#line 2044 "parse.c"
+ break;
+ case 42:
+#line 211 "parse.y"
+{ yygotominor.yy412 = -atoi(yymsp[0].minor.yy258.z); }
+#line 2049 "parse.c"
+ break;
+ case 47:
+ case 48:
+#line 216 "parse.y"
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy2);}
+#line 2055 "parse.c"
+ break;
+ case 49:
+#line 218 "parse.y"
+{
+ Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy2, 0, 0);
+ sqlite3AddDefaultValue(pParse,p);
+}
+#line 2063 "parse.c"
+ break;
+ case 50:
+#line 222 "parse.y"
+{
+ Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy258);
+ sqlite3AddDefaultValue(pParse,p);
+}
+#line 2071 "parse.c"
+ break;
+ case 52:
+#line 231 "parse.y"
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy412);}
+#line 2076 "parse.c"
+ break;
+ case 53:
+#line 233 "parse.y"
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy412,yymsp[0].minor.yy412);}
+#line 2081 "parse.c"
+ break;
+ case 54:
+#line 234 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy412,0,0);}
+#line 2086 "parse.c"
+ break;
+ case 55:
+#line 235 "parse.y"
+{sqlite3ExprDelete(yymsp[-2].minor.yy2);}
+#line 2091 "parse.c"
+ break;
+ case 56:
+#line 237 "parse.y"
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy258,yymsp[-1].minor.yy82,yymsp[0].minor.yy412);}
+#line 2096 "parse.c"
+ break;
+ case 57:
+#line 238 "parse.y"
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy412);}
+#line 2101 "parse.c"
+ break;
+ case 58:
+#line 239 "parse.y"
+{sqlite3AddCollateType(pParse, yymsp[0].minor.yy258.z, yymsp[0].minor.yy258.n);}
+#line 2106 "parse.c"
+ break;
+ case 61:
+#line 252 "parse.y"
+{ yygotominor.yy412 = OE_Restrict * 0x010101; }
+#line 2111 "parse.c"
+ break;
+ case 62:
+#line 253 "parse.y"
+{ yygotominor.yy412 = (yymsp[-1].minor.yy412 & yymsp[0].minor.yy47.mask) | yymsp[0].minor.yy47.value; }
+#line 2116 "parse.c"
+ break;
+ case 63:
+#line 255 "parse.y"
+{ yygotominor.yy47.value = 0; yygotominor.yy47.mask = 0x000000; }
+#line 2121 "parse.c"
+ break;
+ case 64:
+#line 256 "parse.y"
+{ yygotominor.yy47.value = yymsp[0].minor.yy412; yygotominor.yy47.mask = 0x0000ff; }
+#line 2126 "parse.c"
+ break;
+ case 65:
+#line 257 "parse.y"
+{ yygotominor.yy47.value = yymsp[0].minor.yy412<<8; yygotominor.yy47.mask = 0x00ff00; }
+#line 2131 "parse.c"
+ break;
+ case 66:
+#line 258 "parse.y"
+{ yygotominor.yy47.value = yymsp[0].minor.yy412<<16; yygotominor.yy47.mask = 0xff0000; }
+#line 2136 "parse.c"
+ break;
+ case 67:
+#line 260 "parse.y"
+{ yygotominor.yy412 = OE_SetNull; }
+#line 2141 "parse.c"
+ break;
+ case 68:
+#line 261 "parse.y"
+{ yygotominor.yy412 = OE_SetDflt; }
+#line 2146 "parse.c"
+ break;
+ case 69:
+#line 262 "parse.y"
+{ yygotominor.yy412 = OE_Cascade; }
+#line 2151 "parse.c"
+ break;
+ case 70:
+#line 263 "parse.y"
+{ yygotominor.yy412 = OE_Restrict; }
+#line 2156 "parse.c"
+ break;
+ case 71:
+ case 72:
+ case 87:
+ case 89:
+ case 91:
+ case 92:
+ case 163:
+#line 265 "parse.y"
+{yygotominor.yy412 = yymsp[0].minor.yy412;}
+#line 2167 "parse.c"
+ break;
+ case 76:
+#line 275 "parse.y"
+{yygotominor.yy258.n = 0; yygotominor.yy258.z = 0;}
+#line 2172 "parse.c"
+ break;
+ case 77:
+#line 276 "parse.y"
+{yygotominor.yy258 = yymsp[-1].minor.yy0;}
+#line 2177 "parse.c"
+ break;
+ case 82:
+#line 282 "parse.y"
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy82,yymsp[0].minor.yy412,yymsp[-2].minor.yy412);}
+#line 2182 "parse.c"
+ break;
+ case 83:
+#line 284 "parse.y"
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy82,yymsp[0].minor.yy412,0,0);}
+#line 2187 "parse.c"
+ break;
+ case 85:
+#line 287 "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);
+}
+#line 2195 "parse.c"
+ break;
+ case 88:
+ case 90:
+#line 301 "parse.y"
+{yygotominor.yy412 = OE_Default;}
+#line 2201 "parse.c"
+ break;
+ case 93:
+#line 306 "parse.y"
+{yygotominor.yy412 = OE_Ignore;}
+#line 2206 "parse.c"
+ break;
+ case 94:
+ case 164:
+#line 307 "parse.y"
+{yygotominor.yy412 = OE_Replace;}
+#line 2212 "parse.c"
+ break;
+ case 95:
+#line 311 "parse.y"
+{
+ sqlite3DropTable(pParse, yymsp[0].minor.yy67, 0);
+}
+#line 2219 "parse.c"
+ break;
+ case 96:
+#line 318 "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 "parse.c"
+ break;
+ case 97:
+#line 321 "parse.y"
+{
+ sqlite3DropTable(pParse, yymsp[0].minor.yy67, 1);
+}
+#line 2233 "parse.c"
+ break;
+ case 98:
+#line 328 "parse.y"
+{
+ sqlite3Select(pParse, yymsp[0].minor.yy459, SRT_Callback, 0, 0, 0, 0, 0);
+ sqlite3SelectDelete(yymsp[0].minor.yy459);
+}
+#line 2241 "parse.c"
+ break;
+ case 99:
+ case 123:
+#line 338 "parse.y"
+{yygotominor.yy459 = yymsp[0].minor.yy459;}
+#line 2247 "parse.c"
+ break;
+ case 100:
+#line 340 "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;
+}
+#line 2258 "parse.c"
+ break;
+ case 102:
+#line 349 "parse.y"
+{yygotominor.yy412 = TK_ALL;}
+#line 2263 "parse.c"
+ break;
+ case 105:
+#line 354 "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);
+}
+#line 2270 "parse.c"
+ break;
+ case 109:
+ case 244:
+#line 375 "parse.y"
+{yygotominor.yy82 = yymsp[-1].minor.yy82;}
+#line 2276 "parse.c"
+ break;
+ case 110:
+ case 137:
+ case 147:
+ case 243:
+#line 376 "parse.y"
+{yygotominor.yy82 = 0;}
+#line 2284 "parse.c"
+ break;
+ case 111:
+#line 377 "parse.y"
+{
+ yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-2].minor.yy82,yymsp[-1].minor.yy2,yymsp[0].minor.yy258.n?&yymsp[0].minor.yy258:0);
+}
+#line 2291 "parse.c"
+ break;
+ case 112:
+#line 380 "parse.y"
+{
+ yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-1].minor.yy82, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
+}
+#line 2298 "parse.c"
+ break;
+ case 113:
+#line 383 "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);
+}
+#line 2307 "parse.c"
+ break;
+ case 116:
+#line 395 "parse.y"
+{yygotominor.yy258.n = 0;}
+#line 2312 "parse.c"
+ break;
+ case 117:
+#line 407 "parse.y"
+{yygotominor.yy67 = sqliteMalloc(sizeof(*yygotominor.yy67));}
+#line 2317 "parse.c"
+ break;
+ case 118:
+#line 408 "parse.y"
+{yygotominor.yy67 = yymsp[0].minor.yy67;}
+#line 2322 "parse.c"
+ break;
+ case 119:
+#line 413 "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 "parse.c"
+ break;
+ case 120:
+#line 417 "parse.y"
+{yygotominor.yy67 = 0;}
+#line 2335 "parse.c"
+ break;
+ case 121:
+#line 418 "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); }
+ }
+ 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); }
+ }
+}
+#line 2351 "parse.c"
+ break;
+ case 122:
+#line 432 "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); }
+ }
+ 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); }
+ }
+ }
+#line 2368 "parse.c"
+ break;
+ case 124:
+#line 453 "parse.y"
+{
+ yygotominor.yy459 = sqlite3SelectNew(0,yymsp[0].minor.yy67,0,0,0,0,0,0,0);
+ }
+#line 2375 "parse.c"
+ break;
+ case 125:
+#line 459 "parse.y"
+{yygotominor.yy258.z=0; yygotominor.yy258.n=0;}
+#line 2380 "parse.c"
+ break;
+ case 127:
+#line 464 "parse.y"
+{yygotominor.yy67 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258);}
+#line 2385 "parse.c"
+ break;
+ case 128:
+ case 129:
+#line 468 "parse.y"
+{ yygotominor.yy412 = JT_INNER; }
+#line 2391 "parse.c"
+ break;
+ case 130:
+#line 470 "parse.y"
+{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+#line 2396 "parse.c"
+ break;
+ case 131:
+#line 471 "parse.y"
+{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy258,0); }
+#line 2401 "parse.c"
+ break;
+ case 132:
+#line 473 "parse.y"
+{ yygotominor.yy412 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy258,&yymsp[-1].minor.yy258); }
+#line 2406 "parse.c"
+ break;
+ case 133:
+ case 141:
+ case 150:
+ case 157:
+ case 171:
+ case 207:
+ case 232:
+ case 234:
+ case 238:
+#line 477 "parse.y"
+{yygotominor.yy2 = yymsp[0].minor.yy2;}
+#line 2419 "parse.c"
+ break;
+ case 134:
+ case 149:
+ case 156:
+ case 208:
+ case 233:
+ case 235:
+ case 239:
+#line 478 "parse.y"
+{yygotominor.yy2 = 0;}
+#line 2430 "parse.c"
+ break;
+ case 135:
+ case 168:
+#line 482 "parse.y"
+{yygotominor.yy240 = yymsp[-1].minor.yy240;}
+#line 2436 "parse.c"
+ break;
+ case 136:
+ case 167:
+#line 483 "parse.y"
+{yygotominor.yy240 = 0;}
+#line 2442 "parse.c"
+ break;
+ case 138:
+ case 148:
+#line 494 "parse.y"
+{yygotominor.yy82 = yymsp[0].minor.yy82;}
+#line 2448 "parse.c"
+ break;
+ case 139:
+#line 495 "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;
+}
+#line 2456 "parse.c"
+ break;
+ case 140:
+#line 499 "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;
+}
+#line 2464 "parse.c"
+ break;
+ case 142:
+ case 144:
+#line 508 "parse.y"
+{yygotominor.yy412 = SQLITE_SO_ASC;}
+#line 2470 "parse.c"
+ break;
+ case 143:
+#line 509 "parse.y"
+{yygotominor.yy412 = SQLITE_SO_DESC;}
+#line 2475 "parse.c"
+ break;
+ case 145:
+#line 511 "parse.y"
+{yygotominor.yy258.z = 0; yygotominor.yy258.n = 0;}
+#line 2480 "parse.c"
+ break;
+ case 151:
+#line 529 "parse.y"
+{yygotominor.yy244.pLimit = 0; yygotominor.yy244.pOffset = 0;}
+#line 2485 "parse.c"
+ break;
+ case 152:
+#line 530 "parse.y"
+{yygotominor.yy244.pLimit = yymsp[0].minor.yy2; yygotominor.yy244.pOffset = 0;}
+#line 2490 "parse.c"
+ break;
+ case 153:
+#line 532 "parse.y"
+{yygotominor.yy244.pLimit = yymsp[-2].minor.yy2; yygotominor.yy244.pOffset = yymsp[0].minor.yy2;}
+#line 2495 "parse.c"
+ break;
+ case 154:
+#line 534 "parse.y"
+{yygotominor.yy244.pOffset = yymsp[-2].minor.yy2; yygotominor.yy244.pLimit = yymsp[0].minor.yy2;}
+#line 2500 "parse.c"
+ break;
+ case 155:
+#line 538 "parse.y"
+{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy67,yymsp[0].minor.yy2);}
+#line 2505 "parse.c"
+ break;
+ case 158:
+#line 549 "parse.y"
+{sqlite3Update(pParse,yymsp[-3].minor.yy67,yymsp[-1].minor.yy82,yymsp[0].minor.yy2,yymsp[-4].minor.yy412);}
+#line 2510 "parse.c"
+ break;
+ case 159:
+#line 555 "parse.y"
+{yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82,yymsp[0].minor.yy2,&yymsp[-2].minor.yy258);}
+#line 2515 "parse.c"
+ break;
+ case 160:
+#line 556 "parse.y"
+{yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[0].minor.yy2,&yymsp[-2].minor.yy258);}
+#line 2520 "parse.c"
+ break;
+ case 161:
+#line 562 "parse.y"
+{sqlite3Insert(pParse, yymsp[-5].minor.yy67, yymsp[-1].minor.yy82, 0, yymsp[-4].minor.yy240, yymsp[-7].minor.yy412);}
+#line 2525 "parse.c"
+ break;
+ case 162:
+#line 564 "parse.y"
+{sqlite3Insert(pParse, yymsp[-2].minor.yy67, 0, yymsp[0].minor.yy459, yymsp[-1].minor.yy240, yymsp[-4].minor.yy412);}
+#line 2530 "parse.c"
+ break;
+ case 165:
+ case 236:
+#line 574 "parse.y"
+{yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-2].minor.yy82,yymsp[0].minor.yy2,0);}
+#line 2536 "parse.c"
+ break;
+ case 166:
+ case 237:
+#line 575 "parse.y"
+{yygotominor.yy82 = sqlite3ExprListAppend(0,yymsp[0].minor.yy2,0);}
+#line 2542 "parse.c"
+ break;
+ case 169:
+#line 584 "parse.y"
+{yygotominor.yy240 = sqlite3IdListAppend(yymsp[-2].minor.yy240,&yymsp[0].minor.yy258);}
+#line 2547 "parse.c"
+ break;
+ case 170:
+#line 585 "parse.y"
+{yygotominor.yy240 = sqlite3IdListAppend(0,&yymsp[0].minor.yy258);}
+#line 2552 "parse.c"
+ break;
+ case 172:
+#line 596 "parse.y"
+{yygotominor.yy2 = yymsp[-1].minor.yy2; sqlite3ExprSpan(yygotominor.yy2,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+#line 2557 "parse.c"
+ break;
+ case 173:
+ case 178:
+ case 179:
+ case 180:
+ case 181:
+#line 597 "parse.y"
+{yygotominor.yy2 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+#line 2566 "parse.c"
+ break;
+ case 174:
+ case 175:
+#line 598 "parse.y"
+{yygotominor.yy2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+#line 2572 "parse.c"
+ break;
+ case 176:
+#line 600 "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);
+}
+#line 2581 "parse.c"
+ break;
+ case 177:
+#line 605 "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 *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
+ yygotominor.yy2 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
+}
+#line 2592 "parse.c"
+ break;
+ case 182:
+#line 616 "parse.y"
+{yygotominor.yy2 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+#line 2597 "parse.c"
+ break;
+ case 183:
+#line 617 "parse.y"
+{
+ Token *pToken = &yymsp[0].minor.yy0;
+ Expr *pExpr = yygotominor.yy2 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
+ sqlite3ExprAssignVarNumber(pParse, pExpr);
+}
+#line 2606 "parse.c"
+ break;
+ case 184:
+#line 622 "parse.y"
+{
+ yygotominor.yy2 = sqlite3ExprFunction(yymsp[-1].minor.yy82, &yymsp[-3].minor.yy0);
+ sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+}
+#line 2614 "parse.c"
+ break;
+ case 185:
+#line 626 "parse.y"
+{
+ yygotominor.yy2 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
+ sqlite3ExprSpan(yygotominor.yy2,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+}
+#line 2622 "parse.c"
+ break;
+ case 186:
+#line 630 "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;
+}
+#line 2632 "parse.c"
+ break;
+ case 187:
+ case 188:
+ case 189:
+ case 190:
+ case 191:
+ case 192:
+ case 193:
+ case 194:
+ case 195:
+ case 196:
+ case 197:
+ case 198:
+ case 199:
+ case 200:
+ case 201:
+ case 202:
+ case 203:
+ case 204:
+#line 636 "parse.y"
+{yygotominor.yy2 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy2, yymsp[0].minor.yy2, 0);}
+#line 2654 "parse.c"
+ break;
+ case 205:
+#line 655 "parse.y"
+{yygotominor.yy438.operator = yymsp[0].minor.yy0; yygotominor.yy438.not = 0;}
+#line 2659 "parse.c"
+ break;
+ case 206:
+#line 656 "parse.y"
+{yygotominor.yy438.operator = yymsp[0].minor.yy0; yygotominor.yy438.not = 1;}
+#line 2664 "parse.c"
+ break;
+ case 209:
+#line 660 "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 "parse.c"
+ break;
+ case 210:
+#line 671 "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 "parse.c"
+ break;
+ case 211:
+#line 675 "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 "parse.c"
+ break;
+ case 212:
+#line 679 "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);
+}
+#line 2702 "parse.c"
+ break;
+ case 213:
+#line 683 "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);
+}
+#line 2710 "parse.c"
+ break;
+ case 214:
+#line 687 "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);
+}
+#line 2718 "parse.c"
+ break;
+ case 215:
+ case 216:
+#line 691 "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);
+}
+#line 2727 "parse.c"
+ break;
+ case 217:
+#line 699 "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);
+}
+#line 2735 "parse.c"
+ break;
+ case 218:
+#line 703 "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);
+}
+#line 2743 "parse.c"
+ break;
+ case 221:
+#line 710 "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);
+}
+#line 2755 "parse.c"
+ break;
+ case 224:
+#line 722 "parse.y"
+{
+ yygotominor.yy2 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy2, 0, 0);
+ if( yygotominor.yy2 ){
+ yygotominor.yy2->pList = yymsp[-1].minor.yy82;
+ }else{
+ sqlite3ExprListDelete(yymsp[-1].minor.yy82);
+ }
+ 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);
+ }
+#line 2769 "parse.c"
+ break;
+ case 225:
+#line 732 "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);
+ }
+#line 2779 "parse.c"
+ break;
+ case 226:
+#line 738 "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);
+ }
+#line 2790 "parse.c"
+ break;
+ case 227:
+#line 745 "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);
+ }
+#line 2801 "parse.c"
+ break;
+ case 228:
+#line 752 "parse.y"
+{
+ Expr *p = yygotominor.yy2 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
+ if( p ){
+ p->pSelect = yymsp[-1].minor.yy459;
+ sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ }
+ if( !p ) sqlite3SelectDelete(yymsp[-1].minor.yy459);
+ }
+#line 2813 "parse.c"
+ break;
+ case 229:
+#line 763 "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);
+}
+#line 2822 "parse.c"
+ break;
+ case 230:
+#line 770 "parse.y"
+{
+ yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82, yymsp[-2].minor.yy2, 0);
+ yygotominor.yy82 = sqlite3ExprListAppend(yygotominor.yy82, yymsp[0].minor.yy2, 0);
+}
+#line 2830 "parse.c"
+ break;
+ case 231:
+#line 774 "parse.y"
+{
+ yygotominor.yy82 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy2, 0);
+ yygotominor.yy82 = sqlite3ExprListAppend(yygotominor.yy82, yymsp[0].minor.yy2, 0);
+}
+#line 2838 "parse.c"
+ break;
+ case 240:
+#line 799 "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);
+}
+#line 2847 "parse.c"
+ break;
+ case 241:
+ case 288:
+#line 806 "parse.y"
+{yygotominor.yy412 = OE_Abort;}
+#line 2853 "parse.c"
+ break;
+ case 242:
+#line 807 "parse.y"
+{yygotominor.yy412 = OE_None;}
+#line 2858 "parse.c"
+ break;
+ case 245:
+#line 817 "parse.y"
+{
+ Expr *p = 0;
+ if( yymsp[-1].minor.yy258.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);
+ }
+ yygotominor.yy82 = sqlite3ExprListAppend(yymsp[-4].minor.yy82, p, &yymsp[-2].minor.yy258);
+}
+#line 2870 "parse.c"
+ break;
+ case 246:
+#line 825 "parse.y"
+{
+ Expr *p = 0;
+ if( yymsp[-1].minor.yy258.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);
+ }
+ yygotominor.yy82 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy258);
+}
+#line 2882 "parse.c"
+ break;
+ case 248:
+#line 838 "parse.y"
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy67);}
+#line 2887 "parse.c"
+ break;
+ case 249:
+ case 250:
+#line 842 "parse.y"
+{sqlite3Vacuum(pParse,0);}
+#line 2893 "parse.c"
+ break;
+ case 251:
+ case 253:
+#line 848 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy258,0);}
+#line 2899 "parse.c"
+ break;
+ case 252:
+#line 849 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy0,0);}
+#line 2904 "parse.c"
+ break;
+ case 254:
+#line 851 "parse.y"
+{
+ sqlite3Pragma(pParse,&yymsp[-3].minor.yy258,&yymsp[-2].minor.yy258,&yymsp[0].minor.yy258,1);
+}
+#line 2911 "parse.c"
+ break;
+ case 255:
+#line 854 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-4].minor.yy258,&yymsp[-3].minor.yy258,&yymsp[-1].minor.yy258,0);}
+#line 2916 "parse.c"
+ break;
+ case 256:
+#line 855 "parse.y"
+{sqlite3Pragma(pParse,&yymsp[-1].minor.yy258,&yymsp[0].minor.yy258,0,0);}
+#line 2921 "parse.c"
+ break;
+ case 263:
+#line 868 "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);
+}
+#line 2931 "parse.c"
+ break;
+ case 264:
+#line 877 "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);
+}
+#line 2939 "parse.c"
+ break;
+ case 265:
+ case 268:
+#line 883 "parse.y"
+{ yygotominor.yy412 = TK_BEFORE; }
+#line 2945 "parse.c"
+ break;
+ case 266:
+#line 884 "parse.y"
+{ yygotominor.yy412 = TK_AFTER; }
+#line 2950 "parse.c"
+ break;
+ case 267:
+#line 885 "parse.y"
+{ yygotominor.yy412 = TK_INSTEAD;}
+#line 2955 "parse.c"
+ break;
+ case 269:
+ case 270:
+ case 271:
+#line 890 "parse.y"
+{yygotominor.yy210.a = yymsp[0].major; yygotominor.yy210.b = 0;}
+#line 2962 "parse.c"
+ break;
+ case 272:
+#line 893 "parse.y"
+{yygotominor.yy210.a = TK_UPDATE; yygotominor.yy210.b = yymsp[0].minor.yy240;}
+#line 2967 "parse.c"
+ break;
+ case 273:
+ case 274:
+#line 896 "parse.y"
+{ yygotominor.yy412 = TK_ROW; }
+#line 2973 "parse.c"
+ break;
+ case 275:
+#line 898 "parse.y"
+{ yygotominor.yy412 = TK_STATEMENT; }
+#line 2978 "parse.c"
+ break;
+ case 276:
+#line 901 "parse.y"
+{ yygotominor.yy2 = 0; }
+#line 2983 "parse.c"
+ break;
+ case 277:
+#line 902 "parse.y"
+{ yygotominor.yy2 = yymsp[0].minor.yy2; }
+#line 2988 "parse.c"
+ break;
+ case 278:
+#line 906 "parse.y"
+{
+ yymsp[-2].minor.yy347->pNext = yymsp[0].minor.yy347;
+ yygotominor.yy347 = yymsp[-2].minor.yy347;
+}
+#line 2996 "parse.c"
+ break;
+ case 279:
+#line 910 "parse.y"
+{ yygotominor.yy347 = 0; }
+#line 3001 "parse.c"
+ break;
+ case 280:
+#line 916 "parse.y"
+{ yygotominor.yy347 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy258, yymsp[-1].minor.yy82, yymsp[0].minor.yy2, yymsp[-4].minor.yy412); }
+#line 3006 "parse.c"
+ break;
+ case 281:
+#line 921 "parse.y"
+{yygotominor.yy347 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy258, yymsp[-4].minor.yy240, yymsp[-1].minor.yy82, 0, yymsp[-7].minor.yy412);}
+#line 3011 "parse.c"
+ break;
+ case 282:
+#line 924 "parse.y"
+{yygotominor.yy347 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy258, yymsp[-1].minor.yy240, 0, yymsp[0].minor.yy459, yymsp[-4].minor.yy412);}
+#line 3016 "parse.c"
+ break;
+ case 283:
+#line 928 "parse.y"
+{yygotominor.yy347 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy258, yymsp[0].minor.yy2);}
+#line 3021 "parse.c"
+ break;
+ case 284:
+#line 931 "parse.y"
+{yygotominor.yy347 = sqlite3TriggerSelectStep(yymsp[0].minor.yy459); }
+#line 3026 "parse.c"
+ break;
+ case 285:
+#line 934 "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 "parse.c"
+ break;
+ case 286:
+#line 939 "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 "parse.c"
+ break;
+ case 287:
+#line 947 "parse.y"
+{yygotominor.yy412 = OE_Rollback;}
+#line 3049 "parse.c"
+ break;
+ case 289:
+#line 949 "parse.y"
+{yygotominor.yy412 = OE_Fail;}
+#line 3054 "parse.c"
+ break;
+ case 290:
+#line 954 "parse.y"
+{
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy67);
+}
+#line 3061 "parse.c"
+ break;
+ case 291:
+#line 960 "parse.y"
+{
+ sqlite3Attach(pParse, &yymsp[-3].minor.yy258, &yymsp[-1].minor.yy258, yymsp[0].minor.yy132.type, &yymsp[0].minor.yy132.key);
+}
+#line 3068 "parse.c"
+ break;
+ case 292:
+#line 964 "parse.y"
+{ yygotominor.yy132.type = 0; }
+#line 3073 "parse.c"
+ break;
+ case 293:
+#line 965 "parse.y"
+{ yygotominor.yy132.type=1; yygotominor.yy132.key = yymsp[0].minor.yy258; }
+#line 3078 "parse.c"
+ break;
+ case 294:
+#line 966 "parse.y"
+{ yygotominor.yy132.type=2; yygotominor.yy132.key = yymsp[0].minor.yy0; }
+#line 3083 "parse.c"
+ break;
+ case 297:
+#line 972 "parse.y"
+{
+ sqlite3Detach(pParse, &yymsp[0].minor.yy258);
+}
+#line 3090 "parse.c"
+ break;
+ case 298:
+#line 978 "parse.y"
+{sqlite3Reindex(pParse, 0, 0);}
+#line 3095 "parse.c"
+ break;
+ case 299:
+#line 979 "parse.y"
+{sqlite3Reindex(pParse, &yymsp[-1].minor.yy258, &yymsp[0].minor.yy258);}
+#line 3100 "parse.c"
+ break;
+ case 300:
+#line 984 "parse.y"
+{
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy67,&yymsp[0].minor.yy258);
+}
+#line 3107 "parse.c"
+ break;
+ case 301:
+#line 987 "parse.y"
+{
+ sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy258);
+}
+#line 3114 "parse.c"
+ break;
+ case 302:
+#line 990 "parse.y"
+{
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy67);
+}
+#line 3121 "parse.c"
+ break;
+ };
+ yygoto = yyRuleInfo[yyruleno].lhs;
+ yysize = yyRuleInfo[yyruleno].nrhs;
+ yypParser->yyidx -= yysize;
+ yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
+ if( yyact < YYNSTATE ){
+#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);
+ }
+}
+
+/*
+** The following code executes when the parse fails
+*/
+static void yy_parse_failed(
+ yyParser *yypParser /* The parser */
+){
+ sqlite3ParserARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+ sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following code executes when a syntax error first occurs.
+*/
+static void yy_syntax_error(
+ yyParser *yypParser, /* The parser */
+ int yymajor, /* The major type of the error token */
+ YYMINORTYPE yyminor /* The minor type of the error token */
+){
+ sqlite3ParserARG_FETCH;
+#define TOKEN (yyminor.yy0)
+#line 23 "parse.y"
+
+ if( pParse->zErrMsg==0 ){
+ if( TOKEN.z[0] ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
+ }else{
+ sqlite3ErrorMsg(pParse, "incomplete SQL statement");
+ }
+ }
+#line 3188 "parse.c"
+ sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following is executed when the parser accepts
+*/
+static void yy_accept(
+ yyParser *yypParser /* The parser */
+){
+ sqlite3ParserARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+ sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/* The main parser program.
+** The first argument is a pointer to a structure obtained from
+** "sqlite3ParserAlloc" which describes the current state of the parser.
+** The second argument is the major token number. The third is
+** the minor token. The fourth optional argument is whatever the
+** user wants (and specified in the grammar) and is available for
+** use by the action routines.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser (an opaque structure.)
+** <li> The major token number.
+** <li> The minor token number.
+** <li> An option argument of a grammar-specified type.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void sqlite3Parser(
+ void *yyp, /* The parser */
+ int yymajor, /* The major token code number */
+ sqlite3ParserTOKENTYPE yyminor /* The value for the token */
+ sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
+){
+ YYMINORTYPE yyminorunion;
+ int yyact; /* The parser action. */
+ int yyendofinput; /* True if we are at the end of input */
+ int yyerrorhit = 0; /* True if yymajor has invoked an error */
+ yyParser *yypParser; /* The parser */
+
+ /* (re)initialize the parser, if necessary */
+ yypParser = (yyParser*)yyp;
+ if( yypParser->yyidx<0 ){
+ /* if( yymajor==0 ) return; // not sure why this was here... */
+ yypParser->yyidx = 0;
+ yypParser->yyerrcnt = -1;
+ yypParser->yystack[0].stateno = 0;
+ yypParser->yystack[0].major = 0;
+ }
+ yyminorunion.yy0 = yyminor;
+ yyendofinput = (yymajor==0);
+ sqlite3ParserARG_STORE;
+
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+
+ do{
+ yyact = yy_find_shift_action(yypParser,yymajor);
+ if( yyact<YYNSTATE ){
+ yy_shift(yypParser,yyact,yymajor,&yyminorunion);
+ yypParser->yyerrcnt--;
+ if( yyendofinput && yypParser->yyidx>=0 ){
+ yymajor = 0;
+ }else{
+ yymajor = YYNOCODE;
+ }
+ }else if( yyact < YYNSTATE + YYNRULE ){
+ yy_reduce(yypParser,yyact-YYNSTATE);
+ }else if( yyact == YY_ERROR_ACTION ){
+ int yymx;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
+ }
+#endif
+#ifdef YYERRORSYMBOL
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if( yypParser->yyerrcnt<0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yymx = yypParser->yystack[yypParser->yyidx].major;
+ if( yymx==YYERRORSYMBOL || yyerrorhit ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sDiscard input token %s\n",
+ yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+ yy_destructor(yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+ }else{
+ while(
+ yypParser->yyidx >= 0 &&
+ yymx != YYERRORSYMBOL &&
+ (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
+ ){
+ yy_pop_parser_stack(yypParser);
+ }
+ if( yypParser->yyidx < 0 || yymajor==0 ){
+ yy_destructor(yymajor,&yyminorunion);
+ yy_parse_failed(yypParser);
+ yymajor = YYNOCODE;
+ }else if( yymx!=YYERRORSYMBOL ){
+ YYMINORTYPE u2;
+ u2.YYERRSYMDT = 0;
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
+ }
+ }
+ yypParser->yyerrcnt = 3;
+ yyerrorhit = 1;
+#else /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if( yypParser->yyerrcnt<=0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yypParser->yyerrcnt = 3;
+ yy_destructor(yymajor,&yyminorunion);
+ if( yyendofinput ){
+ yy_parse_failed(yypParser);
+ }
+ yymajor = YYNOCODE;
+#endif
+ }else{
+ yy_accept(yypParser);
+ yymajor = YYNOCODE;
+ }
+ }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
+ return;
+}
diff --git a/src/sqlite/parse.h b/src/sqlite/parse.h
new file mode 100644
index 0000000..9dc0a15
--- /dev/null
+++ b/src/sqlite/parse.h
@@ -0,0 +1,140 @@
+#define TK_END_OF_FILE 1
+#define TK_ILLEGAL 2
+#define TK_SPACE 3
+#define TK_UNCLOSED_STRING 4
+#define TK_COMMENT 5
+#define TK_FUNCTION 6
+#define TK_COLUMN 7
+#define TK_AGG_FUNCTION 8
+#define TK_CONST_FUNC 9
+#define TK_SEMI 10
+#define TK_EXPLAIN 11
+#define TK_BEGIN 12
+#define TK_TRANSACTION 13
+#define TK_DEFERRED 14
+#define TK_IMMEDIATE 15
+#define TK_EXCLUSIVE 16
+#define TK_COMMIT 17
+#define TK_END 18
+#define TK_ROLLBACK 19
+#define TK_CREATE 20
+#define TK_TABLE 21
+#define TK_TEMP 22
+#define TK_LP 23
+#define TK_RP 24
+#define TK_AS 25
+#define TK_COMMA 26
+#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
diff --git a/src/sqlite/pragma.c b/src/sqlite/pragma.c
new file mode 100644
index 0000000..3c129df
--- /dev/null
+++ b/src/sqlite/pragma.c
@@ -0,0 +1,933 @@
+/*
+** 2003 April 6
+**
+** 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 used to implement the PRAGMA command.
+**
+** $Id: pragma.c,v 1.1.1.1 2006/02/03 20:35:14 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+
+/* Ignore this whole file if pragmas are disabled
+*/
+#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
+
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+# include "pager.h"
+# include "btree.h"
+#endif
+
+/*
+** Interpret the given string as a safety level. Return 0 for OFF,
+** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
+** unrecognized string argument.
+**
+** Note that the values returned are one less that the values that
+** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
+** to support legacy SQL code. The safety level used to be boolean
+** and older scripts may have used numbers 0 for OFF and 1 for ON.
+*/
+static int getSafetyLevel(const u8 *z){
+ /* 123456789 123456789 */
+ static const char zText[] = "onoffalseyestruefull";
+ static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
+ static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
+ static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
+ int i, n;
+ if( isdigit(*z) ){
+ return atoi(z);
+ }
+ n = strlen(z);
+ for(i=0; i<sizeof(iLength); i++){
+ if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
+ return iValue[i];
+ }
+ }
+ return 1;
+}
+
+/*
+** Interpret the given string as a boolean value.
+*/
+static int getBoolean(const u8 *z){
+ return getSafetyLevel(z)&1;
+}
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** Interpret the given string as a temp db location. Return 1 for file
+** backed temporary databases, 2 for the Red-Black tree in memory database
+** and 0 to use the compile-time default.
+*/
+static int getTempStore(const char *z){
+ if( z[0]>='0' && z[0]<='2' ){
+ return z[0] - '0';
+ }else if( sqlite3StrICmp(z, "file")==0 ){
+ return 1;
+ }else if( sqlite3StrICmp(z, "memory")==0 ){
+ return 2;
+ }else{
+ return 0;
+ }
+}
+#endif /* SQLITE_PAGER_PRAGMAS */
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** Invalidate temp storage, either when the temp storage is changed
+** from default, or when 'file' and the temp_store_directory has changed
+*/
+static int invalidateTempStorage(Parse *pParse){
+ sqlite3 *db = pParse->db;
+ if( db->aDb[1].pBt!=0 ){
+ if( db->flags & SQLITE_InTrans ){
+ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
+ "from within a transaction");
+ return SQLITE_ERROR;
+ }
+ sqlite3BtreeClose(db->aDb[1].pBt);
+ db->aDb[1].pBt = 0;
+ sqlite3ResetInternalSchema(db, 0);
+ }
+ return SQLITE_OK;
+}
+#endif /* SQLITE_PAGER_PRAGMAS */
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+/*
+** If the TEMP database is open, close it and mark the database schema
+** as needing reloading. This must be done when using the TEMP_STORE
+** or DEFAULT_TEMP_STORE pragmas.
+*/
+static int changeTempStorage(Parse *pParse, const char *zStorageType){
+ int ts = getTempStore(zStorageType);
+ sqlite3 *db = pParse->db;
+ if( db->temp_store==ts ) return SQLITE_OK;
+ if( invalidateTempStorage( pParse ) != SQLITE_OK ){
+ return SQLITE_ERROR;
+ }
+ db->temp_store = ts;
+ return SQLITE_OK;
+}
+#endif /* SQLITE_PAGER_PRAGMAS */
+
+/*
+** Generate code to return a single integer value.
+*/
+static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ sqlite3VdbeAddOp(v, OP_Integer, value, 0);
+ if( pParse->explain==0 ){
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
+ }
+ sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+}
+
+#ifndef SQLITE_OMIT_FLAG_PRAGMAS
+/*
+** Check to see if zRight and zLeft refer to a pragma that queries
+** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
+** Also, implement the pragma.
+*/
+static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
+ static const struct sPragmaType {
+ const char *zName; /* Name of the pragma */
+ int mask; /* Mask for the db->flags value */
+ } aPragma[] = {
+ { "vdbe_trace", SQLITE_VdbeTrace },
+ { "sql_trace", SQLITE_SqlTrace },
+ { "vdbe_listing", SQLITE_VdbeListing },
+ { "full_column_names", SQLITE_FullColNames },
+ { "short_column_names", SQLITE_ShortColNames },
+ { "count_changes", SQLITE_CountRows },
+ { "empty_result_callbacks", SQLITE_NullCallback },
+ /* The following is VERY experimental */
+ { "writable_schema", SQLITE_WriteSchema },
+ { "omit_readlock", SQLITE_NoReadlock },
+ };
+ int i;
+ const struct sPragmaType *p;
+ for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
+ if( sqlite3StrICmp(zLeft, p->zName)==0 ){
+ sqlite3 *db = pParse->db;
+ Vdbe *v;
+ v = sqlite3GetVdbe(pParse);
+ if( v ){
+ if( zRight==0 ){
+ returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
+ }else{
+ if( getBoolean(zRight) ){
+ db->flags |= p->mask;
+ }else{
+ db->flags &= ~p->mask;
+ }
+ }
+ /* If one of these pragmas is executed, any prepared statements
+ ** need to be recompiled.
+ */
+ sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
+
+/*
+** Process a pragma statement.
+**
+** Pragmas are of this form:
+**
+** PRAGMA [database.]id [= value]
+**
+** The identifier might also be a string. The value is a string, and
+** identifier, or a number. If minusFlag is true, then the value is
+** a number that was preceded by a minus sign.
+**
+** If the left side is "database.id" then pId1 is the database name
+** and pId2 is the id. If the left side is just "id" then pId1 is the
+** id and pId2 is any empty string.
+*/
+void sqlite3Pragma(
+ Parse *pParse,
+ Token *pId1, /* First part of [database.]id field */
+ Token *pId2, /* Second part of [database.]id field, or NULL */
+ Token *pValue, /* Token for <value>, or NULL */
+ int minusFlag /* True if a '-' sign preceded <value> */
+){
+ char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
+ char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
+ const char *zDb = 0; /* The database name */
+ Token *pId; /* Pointer to <id> token */
+ int iDb; /* Database index for <database> */
+ sqlite3 *db = pParse->db;
+ Db *pDb;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return;
+
+ /* Interpret the [database.] part of the pragma statement. iDb is the
+ ** index of the database this pragma is being applied to in db.aDb[]. */
+ iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
+ if( iDb<0 ) return;
+ pDb = &db->aDb[iDb];
+
+ zLeft = sqlite3NameFromToken(pId);
+ if( !zLeft ) return;
+ if( minusFlag ){
+ zRight = sqlite3MPrintf("-%T", pValue);
+ }else{
+ zRight = sqlite3NameFromToken(pValue);
+ }
+
+ zDb = ((iDb>0)?pDb->zName:0);
+ if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
+ goto pragma_out;
+ }
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+ /*
+ ** PRAGMA [database.]default_cache_size
+ ** PRAGMA [database.]default_cache_size=N
+ **
+ ** The first form reports the current persistent setting for the
+ ** page cache size. The value returned is the maximum number of
+ ** pages in the page cache. The second form sets both the current
+ ** page cache size value and the persistent page cache size value
+ ** stored in the database file.
+ **
+ ** The default cache size is stored in meta-value 2 of page 1 of the
+ ** database file. The cache size is actually the absolute value of
+ ** this memory location. The sign of meta-value 2 determines the
+ ** synchronous setting. A negative value means synchronous is off
+ ** and a positive value means synchronous is on.
+ */
+ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
+ static const VdbeOpList getCacheSize[] = {
+ { OP_ReadCookie, 0, 2, 0}, /* 0 */
+ { OP_AbsValue, 0, 0, 0},
+ { OP_Dup, 0, 0, 0},
+ { OP_Integer, 0, 0, 0},
+ { OP_Ne, 0, 6, 0},
+ { OP_Integer, 0, 0, 0}, /* 5 */
+ { OP_Callback, 1, 0, 0},
+ };
+ int addr;
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ if( !zRight ){
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
+ addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
+ sqlite3VdbeChangeP1(v, addr, iDb);
+ sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
+ }else{
+ int size = atoi(zRight);
+ if( size<0 ) size = -size;
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3VdbeAddOp(v, OP_Integer, size, 0);
+ sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
+ addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
+ sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
+ sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
+ pDb->cache_size = size;
+ sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
+ }
+ }else
+
+ /*
+ ** PRAGMA [database.]page_size
+ ** PRAGMA [database.]page_size=N
+ **
+ ** The first form reports the current setting for the
+ ** database page size in bytes. The second form sets the
+ ** database page size value. The value can only be set if
+ ** the database has not yet been created.
+ */
+ if( sqlite3StrICmp(zLeft,"page_size")==0 ){
+ Btree *pBt = pDb->pBt;
+ if( !zRight ){
+ int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
+ returnSingleInt(pParse, "page_size", size);
+ }else{
+ sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1);
+ }
+ }else
+#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
+
+ /*
+ ** PRAGMA [database.]auto_vacuum
+ ** PRAGMA [database.]auto_vacuum=N
+ **
+ ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
+ */
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
+ Btree *pBt = pDb->pBt;
+ if( !zRight ){
+ int auto_vacuum =
+ pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM;
+ returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
+ }else{
+ sqlite3BtreeSetAutoVacuum(pBt, getBoolean(zRight));
+ }
+ }else
+#endif
+
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+ /*
+ ** PRAGMA [database.]cache_size
+ ** PRAGMA [database.]cache_size=N
+ **
+ ** The first form reports the current local setting for the
+ ** page cache size. The local setting can be different from
+ ** the persistent cache size value that is stored in the database
+ ** file itself. The value returned is the maximum number of
+ ** pages in the page cache. The second form sets the local
+ ** page cache size value. It does not change the persistent
+ ** cache size stored on the disk so the cache size will revert
+ ** to its default value when the database is closed and reopened.
+ ** N should be a positive integer.
+ */
+ if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ if( !zRight ){
+ returnSingleInt(pParse, "cache_size", pDb->cache_size);
+ }else{
+ int size = atoi(zRight);
+ if( size<0 ) size = -size;
+ pDb->cache_size = size;
+ sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
+ }
+ }else
+
+ /*
+ ** PRAGMA temp_store
+ ** PRAGMA temp_store = "default"|"memory"|"file"
+ **
+ ** Return or set the local value of the temp_store flag. Changing
+ ** the local value does not make changes to the disk file and the default
+ ** value will be restored the next time the database is opened.
+ **
+ ** Note that it is possible for the library compile-time options to
+ ** override this setting
+ */
+ if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
+ if( !zRight ){
+ returnSingleInt(pParse, "temp_store", db->temp_store);
+ }else{
+ changeTempStorage(pParse, zRight);
+ }
+ }else
+
+ /*
+ ** PRAGMA temp_store_directory
+ ** PRAGMA temp_store_directory = ""|"directory_name"
+ **
+ ** Return or set the local value of the temp_store_directory flag. Changing
+ ** the value sets a specific directory to be used for temporary files.
+ ** Setting to a null string reverts to the default temporary directory search.
+ ** If temporary directory is changed, then invalidateTempStorage.
+ **
+ */
+ if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
+ if( !zRight ){
+ if( sqlite3_temp_directory ){
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
+ sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+ }
+ }else{
+ if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){
+ sqlite3ErrorMsg(pParse, "not a writable directory");
+ goto pragma_out;
+ }
+ if( TEMP_STORE==0
+ || (TEMP_STORE==1 && db->temp_store<=1)
+ || (TEMP_STORE==2 && db->temp_store==1)
+ ){
+ invalidateTempStorage(pParse);
+ }
+ sqliteFree(sqlite3_temp_directory);
+ if( zRight[0] ){
+ sqlite3_temp_directory = zRight;
+ zRight = 0;
+ }else{
+ sqlite3_temp_directory = 0;
+ }
+ }
+ }else
+
+ /*
+ ** PRAGMA [database.]synchronous
+ ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
+ **
+ ** Return or set the local value of the synchronous flag. Changing
+ ** the local value does not make changes to the disk file and the
+ ** default value will be restored the next time the database is
+ ** opened.
+ */
+ if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ if( !zRight ){
+ returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
+ }else{
+ if( !db->autoCommit ){
+ sqlite3ErrorMsg(pParse,
+ "Safety level may not be changed inside a transaction");
+ }else{
+ pDb->safety_level = getSafetyLevel(zRight)+1;
+ sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
+ }
+ }
+ }else
+#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
+
+#ifndef SQLITE_OMIT_FLAG_PRAGMAS
+ if( flagPragma(pParse, zLeft, zRight) ){
+ /* The flagPragma() subroutine also generates any necessary code
+ ** there is nothing more to do here */
+ }else
+#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
+
+#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
+ /*
+ ** PRAGMA table_info(<table>)
+ **
+ ** Return a single row for each column of the named table. The columns of
+ ** the returned data set are:
+ **
+ ** cid: Column id (numbered from left to right, starting at 0)
+ ** name: Column name
+ ** type: Column declaration type.
+ ** notnull: True if 'NOT NULL' is part of column declaration
+ ** dflt_value: The default value for the column, if any.
+ */
+ if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
+ Table *pTab;
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ pTab = sqlite3FindTable(db, zRight, zDb);
+ if( pTab ){
+ int i;
+ sqlite3VdbeSetNumCols(v, 6);
+ sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
+ sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
+ sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
+ sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
+ sqlite3ViewGetColumnNames(pParse, pTab);
+ for(i=0; i<pTab->nCol; i++){
+ sqlite3VdbeAddOp(v, OP_Integer, i, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zName, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0,
+ pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
+ sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
+ sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
+ sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
+ }
+ }
+ }else
+
+ if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
+ Index *pIdx;
+ Table *pTab;
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ pIdx = sqlite3FindIndex(db, zRight, zDb);
+ if( pIdx ){
+ int i;
+ pTab = pIdx->pTable;
+ sqlite3VdbeSetNumCols(v, 3);
+ sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
+ for(i=0; i<pIdx->nColumn; i++){
+ int cnum = pIdx->aiColumn[i];
+ sqlite3VdbeAddOp(v, OP_Integer, i, 0);
+ sqlite3VdbeAddOp(v, OP_Integer, cnum, 0);
+ assert( pTab->nCol>cnum );
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0);
+ sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
+ }
+ }
+ }else
+
+ if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
+ Index *pIdx;
+ Table *pTab;
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ pTab = sqlite3FindTable(db, zRight, zDb);
+ if( pTab ){
+ v = sqlite3GetVdbe(pParse);
+ pIdx = pTab->pIndex;
+ if( pIdx ){
+ int i = 0;
+ sqlite3VdbeSetNumCols(v, 3);
+ sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
+ while(pIdx){
+ sqlite3VdbeAddOp(v, OP_Integer, i, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
+ sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
+ sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
+ ++i;
+ pIdx = pIdx->pNext;
+ }
+ }
+ }
+ }else
+
+ if( sqlite3StrICmp(zLeft, "database_list")==0 ){
+ int i;
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ sqlite3VdbeSetNumCols(v, 3);
+ sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt==0 ) continue;
+ assert( db->aDb[i].zName!=0 );
+ sqlite3VdbeAddOp(v, OP_Integer, i, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0,
+ sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
+ sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
+ }
+ }else
+
+ if( sqlite3StrICmp(zLeft, "collation_list")==0 ){
+ int i = 0;
+ HashElem *p;
+ sqlite3VdbeSetNumCols(v, 2);
+ sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
+ CollSeq *pColl = (CollSeq *)sqliteHashData(p);
+ sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0);
+ sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
+ }
+ }else
+#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
+
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
+ FKey *pFK;
+ Table *pTab;
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ pTab = sqlite3FindTable(db, zRight, zDb);
+ if( pTab ){
+ v = sqlite3GetVdbe(pParse);
+ pFK = pTab->pFKey;
+ if( pFK ){
+ int i = 0;
+ sqlite3VdbeSetNumCols(v, 5);
+ sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
+ sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
+ sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
+ while(pFK){
+ int j;
+ for(j=0; j<pFK->nCol; j++){
+ 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);
+ sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
+ }
+ ++i;
+ pFK = pFK->pNextFrom;
+ }
+ }
+ }
+ }else
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
+
+#ifndef NDEBUG
+ if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
+ extern void sqlite3ParserTrace(FILE*, char *);
+ if( getBoolean(zRight) ){
+ sqlite3ParserTrace(stdout, "parser: ");
+ }else{
+ sqlite3ParserTrace(0, 0);
+ }
+ }else
+#endif
+
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
+ if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
+ int i, j, addr;
+
+ /* Code that initializes the integrity check program. Set the
+ ** error count 0
+ */
+ static const VdbeOpList initCode[] = {
+ { OP_Integer, 0, 0, 0},
+ { OP_MemStore, 0, 1, 0},
+ };
+
+ /* Code that appears at the end of the integrity check. If no error
+ ** messages have been generated, output OK. Otherwise output the
+ ** error message
+ */
+ static const VdbeOpList endCode[] = {
+ { OP_MemLoad, 0, 0, 0},
+ { OP_Integer, 0, 0, 0},
+ { OP_Ne, 0, 0, 0}, /* 2 */
+ { OP_String8, 0, 0, "ok"},
+ { OP_Callback, 1, 0, 0},
+ };
+
+ /* Initialize the VDBE program */
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
+ sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);
+
+ /* Do an integrity check on each database file */
+ for(i=0; i<db->nDb; i++){
+ HashElem *x;
+ int cnt = 0;
+
+ if( OMIT_TEMPDB && i==1 ) continue;
+
+ sqlite3CodeVerifySchema(pParse, i);
+
+ /* Do an integrity check of the B-Tree
+ */
+ for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x);
+ Index *pIdx;
+ sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
+ cnt++;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
+ sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
+ cnt++;
+ }
+ }
+ assert( cnt>0 );
+ sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
+ addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
+ sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0,
+ sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
+ P3_DYNAMIC);
+ sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
+ sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+
+ /* Make sure all the indices are constructed correctly.
+ */
+ sqlite3CodeVerifySchema(pParse, i);
+ for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x);
+ Index *pIdx;
+ int loopTop;
+
+ if( pTab->pIndex==0 ) continue;
+ sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
+ sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);
+ loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
+ sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int jmp2;
+ static const VdbeOpList idxErr[] = {
+ { OP_MemIncr, 0, 0, 0},
+ { OP_String8, 0, 0, "rowid "},
+ { OP_Rowid, 1, 0, 0},
+ { OP_String8, 0, 0, " missing from index "},
+ { OP_String8, 0, 0, 0}, /* 4 */
+ { OP_Concat, 2, 0, 0},
+ { OP_Callback, 1, 0, 0},
+ };
+ sqlite3GenerateIndexKey(v, pIdx, 1);
+ jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
+ addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
+ sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
+ sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
+ }
+ sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
+ sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ static const VdbeOpList cntIdx[] = {
+ { OP_Integer, 0, 0, 0},
+ { OP_MemStore, 2, 1, 0},
+ { OP_Rewind, 0, 0, 0}, /* 2 */
+ { OP_MemIncr, 2, 0, 0},
+ { OP_Next, 0, 0, 0}, /* 4 */
+ { OP_MemLoad, 1, 0, 0},
+ { OP_MemLoad, 2, 0, 0},
+ { OP_Eq, 0, 0, 0}, /* 7 */
+ { OP_MemIncr, 0, 0, 0},
+ { OP_String8, 0, 0, "wrong # of entries in index "},
+ { OP_String8, 0, 0, 0}, /* 10 */
+ { OP_Concat, 0, 0, 0},
+ { OP_Callback, 1, 0, 0},
+ };
+ if( pIdx->tnum==0 ) continue;
+ addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
+ sqlite3VdbeChangeP1(v, addr+2, j+2);
+ sqlite3VdbeChangeP2(v, addr+2, addr+5);
+ sqlite3VdbeChangeP1(v, addr+4, j+2);
+ sqlite3VdbeChangeP2(v, addr+4, addr+3);
+ sqlite3VdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
+ sqlite3VdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
+ }
+ }
+ }
+ addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
+ sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
+ }else
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+
+#ifndef SQLITE_OMIT_UTF16
+ /*
+ ** PRAGMA encoding
+ ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
+ **
+ ** In it's first form, this pragma returns the encoding of the main
+ ** database. If the database is not initialized, it is initialized now.
+ **
+ ** The second form of this pragma is a no-op if the main database file
+ ** has not already been initialized. In this case it sets the default
+ ** encoding that will be used for the main database file if a new file
+ ** is created. If an existing main database file is opened, then the
+ ** default text encoding for the existing database is used.
+ **
+ ** In all cases new databases created using the ATTACH command are
+ ** created to use the same default text encoding as the main database. If
+ ** the main database has not been initialized and/or created when ATTACH
+ ** is executed, this is done before the ATTACH operation.
+ **
+ ** In the second form this pragma sets the text encoding to be used in
+ ** new database files created using this database handle. It is only
+ ** useful if invoked immediately after the main database i
+ */
+ if( sqlite3StrICmp(zLeft, "encoding")==0 ){
+ static struct EncName {
+ char *zName;
+ u8 enc;
+ } encnames[] = {
+ { "UTF-8", SQLITE_UTF8 },
+ { "UTF8", SQLITE_UTF8 },
+ { "UTF-16le", SQLITE_UTF16LE },
+ { "UTF16le", SQLITE_UTF16LE },
+ { "UTF-16be", SQLITE_UTF16BE },
+ { "UTF16be", SQLITE_UTF16BE },
+ { "UTF-16", 0 /* Filled in at run-time */ },
+ { "UTF16", 0 /* Filled in at run-time */ },
+ { 0, 0 }
+ };
+ struct EncName *pEnc;
+ encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
+ if( !zRight ){ /* "PRAGMA encoding" */
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
+ sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
+ if( pEnc->enc==pParse->db->enc ){
+ sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
+ break;
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+ }else{ /* "PRAGMA encoding = XXX" */
+ /* Only change the value of sqlite.enc if the database handle is not
+ ** initialized. If the main database exists, the new sqlite.enc value
+ ** will be overwritten when the schema is next loaded. If it does not
+ ** already exists, it will be created to use the new encoding value.
+ */
+ if( !(pParse->db->flags&SQLITE_Initialized) ){
+ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
+ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
+ pParse->db->enc = pEnc->enc;
+ break;
+ }
+ }
+ if( !pEnc->zName ){
+ sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
+ }
+ }
+ }
+ }else
+#endif /* SQLITE_OMIT_UTF16 */
+
+#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
+ /*
+ ** PRAGMA [database.]schema_version
+ ** PRAGMA [database.]schema_version = <integer>
+ **
+ ** PRAGMA [database.]user_version
+ ** PRAGMA [database.]user_version = <integer>
+ **
+ ** The pragma's schema_version and user_version are used to set or get
+ ** the value of the schema-version and user-version, respectively. Both
+ ** the schema-version and the user-version are 32-bit signed integers
+ ** stored in the database header.
+ **
+ ** The schema-cookie is usually only manipulated internally by SQLite. It
+ ** is incremented by SQLite whenever the database schema is modified (by
+ ** creating or dropping a table or index). The schema version is used by
+ ** SQLite each time a query is executed to ensure that the internal cache
+ ** of the schema used when compiling the SQL query matches the schema of
+ ** the database against which the compiled query is actually executed.
+ ** Subverting this mechanism by using "PRAGMA schema_version" to modify
+ ** the schema-version is potentially dangerous and may lead to program
+ ** crashes or database corruption. Use with caution!
+ **
+ ** The user-version is not used internally by SQLite. It may be used by
+ ** applications for any purpose.
+ */
+ if( sqlite3StrICmp(zLeft, "schema_version")==0 ||
+ sqlite3StrICmp(zLeft, "user_version")==0 ){
+
+ int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */
+ if( zLeft[0]=='s' || zLeft[0]=='S' ){
+ iCookie = 0;
+ }else{
+ iCookie = 5;
+ }
+
+ if( zRight ){
+ /* Write the specified cookie value */
+ static const VdbeOpList setCookie[] = {
+ { OP_Transaction, 0, 1, 0}, /* 0 */
+ { OP_Integer, 0, 0, 0}, /* 1 */
+ { OP_SetCookie, 0, 0, 0}, /* 2 */
+ };
+ int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
+ sqlite3VdbeChangeP1(v, addr, iDb);
+ sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
+ sqlite3VdbeChangeP1(v, addr+2, iDb);
+ sqlite3VdbeChangeP2(v, addr+2, iCookie);
+ }else{
+ /* Read the specified cookie value */
+ static const VdbeOpList readCookie[] = {
+ { OP_ReadCookie, 0, 0, 0}, /* 0 */
+ { OP_Callback, 1, 0, 0}
+ };
+ int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
+ sqlite3VdbeChangeP1(v, addr, iDb);
+ sqlite3VdbeChangeP2(v, addr, iCookie);
+ sqlite3VdbeSetNumCols(v, 1);
+ }
+ }
+#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
+
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ /*
+ ** Report the current state of file logs for all databases
+ */
+ if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
+ static const char *const azLockName[] = {
+ "unlocked", "shared", "reserved", "pending", "exclusive"
+ };
+ int i;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ sqlite3VdbeSetNumCols(v, 2);
+ sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt;
+ Pager *pPager;
+ if( db->aDb[i].zName==0 ) continue;
+ sqlite3VdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, P3_STATIC);
+ pBt = db->aDb[i].pBt;
+ if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
+ sqlite3VdbeOp3(v, OP_String, 0, 0, "closed", P3_STATIC);
+ }else{
+ int j = sqlite3pager_lockstate(pPager);
+ sqlite3VdbeOp3(v, OP_String, 0, 0,
+ (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);
+ }
+ sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
+ }
+ }else
+#endif
+
+#ifdef SQLITE_SSE
+ /*
+ ** Check to see if the sqlite_statements table exists. Create it
+ ** if it does not.
+ */
+ if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){
+ extern int sqlite3CreateStatementsTable(Parse*);
+ sqlite3CreateStatementsTable(pParse);
+ }else
+#endif
+
+ {}
+
+ if( v ){
+ /* Code an OP_Expire at the end of each PRAGMA program to cause
+ ** the VDBE implementing the pragma to expire. Most (all?) pragmas
+ ** are only valid for a single execution.
+ */
+ sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
+ }
+pragma_out:
+ sqliteFree(zLeft);
+ sqliteFree(zRight);
+}
+
+#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */
diff --git a/src/sqlite/prepare.c b/src/sqlite/prepare.c
new file mode 100644
index 0000000..0892fab
--- /dev/null
+++ b/src/sqlite/prepare.c
@@ -0,0 +1,529 @@
+/*
+** 2005 May 25
+**
+** 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 the implementation of the sqlite3_prepare()
+** interface, and routines that contribute to loading the database schema
+** from disk.
+**
+** $Id: prepare.c,v 1.1.1.1 2006/02/03 20:35:11 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+
+/*
+** Fill the InitData structure with an error message that indicates
+** that the database is corrupt.
+*/
+static void corruptSchema(InitData *pData, const char *zExtra){
+ if( !sqlite3_malloc_failed ){
+ sqlite3SetString(pData->pzErrMsg, "malformed database schema",
+ zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
+ }
+}
+
+/*
+** This is the callback routine for the code that initializes the
+** database. See sqlite3Init() below for additional information.
+** This routine is also called from the OP_ParseSchema opcode of the VDBE.
+**
+** Each callback contains the following information:
+**
+** argv[0] = name of thing being created
+** argv[1] = root page number for table or index. NULL for trigger or view.
+** argv[2] = SQL text for the CREATE statement.
+** argv[3] = "1" for temporary files, "0" for main database, "2" or more
+** for auxiliary database files.
+**
+*/
+int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
+ InitData *pData = (InitData*)pInit;
+ sqlite3 *db = pData->db;
+ int iDb;
+
+ assert( argc==4 );
+ if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
+ if( argv[1]==0 || argv[3]==0 ){
+ corruptSchema(pData, 0);
+ return 1;
+ }
+ iDb = atoi(argv[3]);
+ assert( iDb>=0 && iDb<db->nDb );
+ if( argv[2] && argv[2][0] ){
+ /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
+ ** But because db->init.busy is set to 1, no VDBE code is generated
+ ** or executed. All the parser does is build the internal data
+ ** structures that describe the table, index, or view.
+ */
+ char *zErr;
+ int rc;
+ assert( db->init.busy );
+ db->init.iDb = iDb;
+ db->init.newTnum = atoi(argv[1]);
+ rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
+ db->init.iDb = 0;
+ if( SQLITE_OK!=rc ){
+ corruptSchema(pData, zErr);
+ sqlite3_free(zErr);
+ return rc;
+ }
+ }else{
+ /* If the SQL column is blank it means this is an index that
+ ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
+ ** constraint for a CREATE TABLE. The index should have already
+ ** been created when we processed the CREATE TABLE. All we have
+ ** to do here is record the root page number for that index.
+ */
+ Index *pIndex;
+ pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
+ if( pIndex==0 || pIndex->tnum!=0 ){
+ /* This can occur if there exists an index on a TEMP table which
+ ** has the same name as another index on a permanent index. Since
+ ** the permanent table is hidden by the TEMP table, we can also
+ ** safely ignore the index on the permanent table.
+ */
+ /* Do Nothing */;
+ }else{
+ pIndex->tnum = atoi(argv[1]);
+ }
+ }
+ return 0;
+}
+
+/*
+** Attempt to read the database schema and initialize internal
+** data structures for a single database file. The index of the
+** database file is given by iDb. iDb==0 is used for the main
+** database. iDb==1 should never be used. iDb>=2 is used for
+** auxiliary databases. Return one of the SQLITE_ error codes to
+** indicate success or failure.
+*/
+static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
+ int rc;
+ BtCursor *curMain;
+ int size;
+ Table *pTab;
+ char const *azArg[5];
+ char zDbNum[30];
+ int meta[10];
+ InitData initData;
+ char const *zMasterSchema;
+ char const *zMasterName = SCHEMA_TABLE(iDb);
+
+ /*
+ ** The master database table has a structure like this
+ */
+ static const char master_schema[] =
+ "CREATE TABLE sqlite_master(\n"
+ " type text,\n"
+ " name text,\n"
+ " tbl_name text,\n"
+ " rootpage integer,\n"
+ " sql text\n"
+ ")"
+ ;
+#ifndef SQLITE_OMIT_TEMPDB
+ static const char temp_master_schema[] =
+ "CREATE TEMP TABLE sqlite_temp_master(\n"
+ " type text,\n"
+ " name text,\n"
+ " tbl_name text,\n"
+ " rootpage integer,\n"
+ " sql text\n"
+ ")"
+ ;
+#else
+ #define temp_master_schema 0
+#endif
+
+ assert( iDb>=0 && iDb<db->nDb );
+
+ /* zMasterSchema and zInitScript are set to point at the master schema
+ ** and initialisation script appropriate for the database being
+ ** initialised. zMasterName is the name of the master table.
+ */
+ if( !OMIT_TEMPDB && iDb==1 ){
+ zMasterSchema = temp_master_schema;
+ }else{
+ zMasterSchema = master_schema;
+ }
+ zMasterName = SCHEMA_TABLE(iDb);
+
+ /* Construct the schema tables. */
+ sqlite3SafetyOff(db);
+ azArg[0] = zMasterName;
+ azArg[1] = "1";
+ azArg[2] = zMasterSchema;
+ sprintf(zDbNum, "%d", iDb);
+ azArg[3] = zDbNum;
+ azArg[4] = 0;
+ initData.db = db;
+ initData.pzErrMsg = pzErrMsg;
+ rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
+ if( rc!=SQLITE_OK ){
+ sqlite3SafetyOn(db);
+ return rc;
+ }
+ pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
+ if( pTab ){
+ pTab->readOnly = 1;
+ }
+ sqlite3SafetyOn(db);
+
+ /* Create a cursor to hold the database open
+ */
+ if( db->aDb[iDb].pBt==0 ){
+ if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
+ return SQLITE_OK;
+ }
+ rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
+ if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
+ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
+ return rc;
+ }
+
+ /* Get the database meta information.
+ **
+ ** Meta values are as follows:
+ ** meta[0] Schema cookie. Changes with each schema change.
+ ** meta[1] File format of schema layer.
+ ** meta[2] Size of the page cache.
+ ** meta[3] Use freelist if 0. Autovacuum if greater than zero.
+ ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
+ ** meta[5] The user cookie. Used by the application.
+ ** meta[6]
+ ** meta[7]
+ ** meta[8]
+ ** meta[9]
+ **
+ ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
+ ** the possible values of meta[4].
+ */
+ if( rc==SQLITE_OK ){
+ int i;
+ for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
+ rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, (u32 *)&meta[i]);
+ }
+ if( rc ){
+ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
+ sqlite3BtreeCloseCursor(curMain);
+ return rc;
+ }
+ }else{
+ memset(meta, 0, sizeof(meta));
+ }
+ db->aDb[iDb].schema_cookie = meta[0];
+
+ /* If opening a non-empty database, check the text encoding. For the
+ ** main database, set sqlite3.enc to the encoding of the main database.
+ ** For an attached db, it is an error if the encoding is not the same
+ ** as sqlite3.enc.
+ */
+ if( meta[4] ){ /* text encoding */
+ if( iDb==0 ){
+ /* If opening the main database, set db->enc. */
+ db->enc = (u8)meta[4];
+ db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0);
+ }else{
+ /* If opening an attached database, the encoding much match db->enc */
+ if( meta[4]!=db->enc ){
+ sqlite3BtreeCloseCursor(curMain);
+ sqlite3SetString(pzErrMsg, "attached databases must use the same"
+ " text encoding as main database", (char*)0);
+ return SQLITE_ERROR;
+ }
+ }
+ }
+
+ size = meta[2];
+ if( size==0 ){ size = MAX_PAGES; }
+ db->aDb[iDb].cache_size = size;
+
+ if( iDb==0 ){
+ db->file_format = meta[1];
+ if( db->file_format==0 ){
+ /* This happens if the database was initially empty */
+ db->file_format = 1;
+ }
+
+ if( db->file_format==2 || db->file_format==3 ){
+ /* File format 2 is treated exactly as file format 1. New
+ ** databases are created with file format 1.
+ */
+ db->file_format = 1;
+ }
+ }
+
+ /*
+ ** file_format==1 Version 3.0.0.
+ ** file_format==2 Version 3.1.3.
+ ** file_format==3 Version 3.1.4.
+ **
+ ** Version 3.0 can only use files with file_format==1. Version 3.1.3
+ ** can read and write files with file_format==1 or file_format==2.
+ ** Version 3.1.4 can read and write file formats 1, 2 and 3.
+ */
+ if( meta[1]>3 ){
+ sqlite3BtreeCloseCursor(curMain);
+ sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
+ return SQLITE_ERROR;
+ }
+
+ sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
+
+ /* Read the schema information out of the schema tables
+ */
+ assert( db->init.busy );
+ if( rc==SQLITE_EMPTY ){
+ /* For an empty database, there is nothing to read */
+ rc = SQLITE_OK;
+ }else{
+ char *zSql;
+ zSql = sqlite3MPrintf(
+ "SELECT name, rootpage, sql, '%s' FROM '%q'.%s",
+ zDbNum, db->aDb[iDb].zName, zMasterName);
+ sqlite3SafetyOff(db);
+ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+ sqlite3SafetyOn(db);
+ sqliteFree(zSql);
+ sqlite3BtreeCloseCursor(curMain);
+ }
+ if( sqlite3_malloc_failed ){
+ sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
+ rc = SQLITE_NOMEM;
+ sqlite3ResetInternalSchema(db, 0);
+ }
+ if( rc==SQLITE_OK ){
+ DbSetProperty(db, iDb, DB_SchemaLoaded);
+ }else{
+ sqlite3ResetInternalSchema(db, iDb);
+ }
+ return rc;
+}
+
+/*
+** Initialize all database files - the main database file, the file
+** used to store temporary tables, and any additional database files
+** created using ATTACH statements. Return a success code. If an
+** error occurs, write an error message into *pzErrMsg.
+**
+** After the database is initialized, the SQLITE_Initialized
+** bit is set in the flags field of the sqlite structure.
+*/
+int sqlite3Init(sqlite3 *db, char **pzErrMsg){
+ int i, rc;
+
+ if( db->init.busy ) return SQLITE_OK;
+ assert( (db->flags & SQLITE_Initialized)==0 );
+ rc = SQLITE_OK;
+ db->init.busy = 1;
+ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+ if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
+ rc = sqlite3InitOne(db, i, pzErrMsg);
+ if( rc ){
+ sqlite3ResetInternalSchema(db, i);
+ }
+ }
+
+ /* Once all the other databases have been initialised, load the schema
+ ** for the TEMP database. This is loaded last, as the TEMP database
+ ** schema may contain references to objects in other databases.
+ */
+#ifndef SQLITE_OMIT_TEMPDB
+ if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
+ rc = sqlite3InitOne(db, 1, pzErrMsg);
+ if( rc ){
+ sqlite3ResetInternalSchema(db, 1);
+ }
+ }
+#endif
+
+ db->init.busy = 0;
+ if( rc==SQLITE_OK ){
+ db->flags |= SQLITE_Initialized;
+ sqlite3CommitInternalChanges(db);
+ }
+
+ if( rc!=SQLITE_OK ){
+ db->flags &= ~SQLITE_Initialized;
+ }
+ return rc;
+}
+
+/*
+** This routine is a no-op if the database schema is already initialised.
+** Otherwise, the schema is loaded. An error code is returned.
+*/
+int sqlite3ReadSchema(Parse *pParse){
+ int rc = SQLITE_OK;
+ sqlite3 *db = pParse->db;
+ if( !db->init.busy ){
+ if( (db->flags & SQLITE_Initialized)==0 ){
+ rc = sqlite3Init(db, &pParse->zErrMsg);
+ }
+ }
+ assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy );
+ if( rc!=SQLITE_OK ){
+ pParse->rc = rc;
+ pParse->nErr++;
+ }
+ return rc;
+}
+
+
+/*
+** Check schema cookies in all databases. If any cookie is out
+** of date, return 0. If all schema cookies are current, return 1.
+*/
+static int schemaIsValid(sqlite3 *db){
+ int iDb;
+ int rc;
+ BtCursor *curTemp;
+ int cookie;
+ int allOk = 1;
+
+ for(iDb=0; allOk && iDb<db->nDb; iDb++){
+ Btree *pBt;
+ pBt = db->aDb[iDb].pBt;
+ if( pBt==0 ) continue;
+ rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
+ if( rc==SQLITE_OK && cookie!=db->aDb[iDb].schema_cookie ){
+ allOk = 0;
+ }
+ sqlite3BtreeCloseCursor(curTemp);
+ }
+ }
+ return allOk;
+}
+
+/*
+** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
+*/
+int sqlite3_prepare(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char** pzTail /* OUT: End of parsed string */
+){
+ Parse sParse;
+ char *zErrMsg = 0;
+ int rc = SQLITE_OK;
+
+ if( sqlite3_malloc_failed ){
+ return SQLITE_NOMEM;
+ }
+
+ assert( ppStmt );
+ *ppStmt = 0;
+ if( sqlite3SafetyOn(db) ){
+ return SQLITE_MISUSE;
+ }
+
+ memset(&sParse, 0, sizeof(sParse));
+ sParse.db = db;
+ sqlite3RunParser(&sParse, zSql, &zErrMsg);
+
+ if( sqlite3_malloc_failed ){
+ rc = SQLITE_NOMEM;
+ sqlite3RollbackAll(db);
+ sqlite3ResetInternalSchema(db, 0);
+ db->flags &= ~SQLITE_InTrans;
+ goto prepare_out;
+ }
+ if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
+ if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
+ sParse.rc = SQLITE_SCHEMA;
+ }
+ if( sParse.rc==SQLITE_SCHEMA ){
+ sqlite3ResetInternalSchema(db, 0);
+ }
+ if( pzTail ) *pzTail = sParse.zTail;
+ rc = sParse.rc;
+
+#ifndef SQLITE_OMIT_EXPLAIN
+ if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
+ sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
+ }
+#endif
+
+prepare_out:
+ if( sqlite3SafetyOff(db) ){
+ rc = SQLITE_MISUSE;
+ }
+ if( rc==SQLITE_OK ){
+ *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
+ }else if( sParse.pVdbe ){
+ sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
+ }
+
+ if( zErrMsg ){
+ sqlite3Error(db, rc, "%s", zErrMsg);
+ sqliteFree(zErrMsg);
+ }else{
+ sqlite3Error(db, rc, 0);
+ }
+ return rc;
+}
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
+*/
+int sqlite3_prepare16(
+ sqlite3 *db, /* Database handle. */
+ const void *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const void **pzTail /* OUT: End of parsed string */
+){
+ /* This function currently works by first transforming the UTF-16
+ ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
+ ** tricky bit is figuring out the pointer to return in *pzTail.
+ */
+ char const *zSql8 = 0;
+ char const *zTail8 = 0;
+ int rc;
+ sqlite3_value *pTmp;
+
+ if( sqlite3SafetyCheck(db) ){
+ return SQLITE_MISUSE;
+ }
+ pTmp = sqlite3GetTransientValue(db);
+ sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
+ zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
+ if( !zSql8 ){
+ sqlite3Error(db, SQLITE_NOMEM, 0);
+ return SQLITE_NOMEM;
+ }
+ rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);
+
+ if( zTail8 && pzTail ){
+ /* If sqlite3_prepare returns a tail pointer, we calculate the
+ ** equivalent pointer into the UTF-16 string by counting the unicode
+ ** characters between zSql8 and zTail8, and then returning a pointer
+ ** the same number of characters into the UTF-16 string.
+ */
+ int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
+ *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
+ }
+
+ return rc;
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
diff --git a/src/sqlite/printf.c b/src/sqlite/printf.c
new file mode 100644
index 0000000..6e70077
--- /dev/null
+++ b/src/sqlite/printf.c
@@ -0,0 +1,831 @@
+/*
+** The "printf" code that follows dates from the 1980's. It is in
+** the public domain. The original comments are included here for
+** completeness. They are very out-of-date but might be useful as
+** an historical reference. Most of the "enhancements" have been backed
+** out so that the functionality is now the same as standard printf().
+**
+**************************************************************************
+**
+** The following modules is an enhanced replacement for the "printf" subroutines
+** found in the standard C library. The following enhancements are
+** supported:
+**
+** + Additional functions. The standard set of "printf" functions
+** includes printf, fprintf, sprintf, vprintf, vfprintf, and
+** vsprintf. This module adds the following:
+**
+** * snprintf -- Works like sprintf, but has an extra argument
+** which is the size of the buffer written to.
+**
+** * mprintf -- Similar to sprintf. Writes output to memory
+** obtained from malloc.
+**
+** * xprintf -- Calls a function to dispose of output.
+**
+** * nprintf -- No output, but returns the number of characters
+** that would have been output by printf.
+**
+** * A v- version (ex: vsnprintf) of every function is also
+** supplied.
+**
+** + A few extensions to the formatting notation are supported:
+**
+** * The "=" flag (similar to "-") causes the output to be
+** be centered in the appropriately sized field.
+**
+** * The %b field outputs an integer in binary notation.
+**
+** * The %c field now accepts a precision. The character output
+** is repeated by the number of times the precision specifies.
+**
+** * The %' field works like %c, but takes as its character the
+** next character of the format string, instead of the next
+** argument. For example, printf("%.78'-") prints 78 minus
+** signs, the same as printf("%.78c",'-').
+**
+** + When compiled using GCC on a SPARC, this version of printf is
+** faster than the library printf for SUN OS 4.1.
+**
+** + All functions are fully reentrant.
+**
+*/
+#include "sqliteInt.h"
+
+/*
+** Conversion types fall into various categories as defined by the
+** following enumeration.
+*/
+#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
+#define etFLOAT 2 /* Floating point. %f */
+#define etEXP 3 /* Exponentional notation. %e and %E */
+#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
+#define etSIZE 5 /* Return number of characters processed so far. %n */
+#define etSTRING 6 /* Strings. %s */
+#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
+#define etPERCENT 8 /* Percent symbol. %% */
+#define etCHARX 9 /* Characters. %c */
+#define etERROR 10 /* Used to indicate no such conversion type */
+/* The rest are extensions, not normally found in printf() */
+#define etCHARLIT 11 /* Literal characters. %' */
+#define etSQLESCAPE 12 /* Strings with '\'' doubled. %q */
+#define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
+ NULL pointers replaced by SQL NULL. %Q */
+#define etTOKEN 14 /* a pointer to a Token structure */
+#define etSRCLIST 15 /* a pointer to a SrcList */
+#define etPOINTER 16 /* The %p conversion */
+
+
+/*
+** An "etByte" is an 8-bit unsigned value.
+*/
+typedef unsigned char etByte;
+
+/*
+** Each builtin conversion character (ex: the 'd' in "%d") is described
+** by an instance of the following structure
+*/
+typedef struct et_info { /* Information about each format field */
+ char fmttype; /* The format field code letter */
+ etByte base; /* The base for radix conversion */
+ etByte flags; /* One or more of FLAG_ constants below */
+ etByte type; /* Conversion paradigm */
+ etByte charset; /* Offset into aDigits[] of the digits string */
+ etByte prefix; /* Offset into aPrefix[] of the prefix string */
+} et_info;
+
+/*
+** Allowed values for et_info.flags
+*/
+#define FLAG_SIGNED 1 /* True if the value to convert is signed */
+#define FLAG_INTERN 2 /* True if for internal use only */
+#define FLAG_STRING 4 /* Allow infinity precision */
+
+
+/*
+** The following table is searched linearly, so it is good to put the
+** most frequently used conversion types first.
+*/
+static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
+static const char aPrefix[] = "-x0\000X0";
+static const et_info fmtinfo[] = {
+ { 'd', 10, 1, etRADIX, 0, 0 },
+ { 's', 0, 4, etSTRING, 0, 0 },
+ { 'z', 0, 6, etDYNSTRING, 0, 0 },
+ { 'q', 0, 4, etSQLESCAPE, 0, 0 },
+ { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
+ { 'c', 0, 0, etCHARX, 0, 0 },
+ { 'o', 8, 0, etRADIX, 0, 2 },
+ { 'u', 10, 0, etRADIX, 0, 0 },
+ { 'x', 16, 0, etRADIX, 16, 1 },
+ { 'X', 16, 0, etRADIX, 0, 4 },
+ { '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 },
+ { '%', 0, 0, etPERCENT, 0, 0 },
+ { 'p', 16, 0, etPOINTER, 0, 1 },
+ { 'T', 0, 2, etTOKEN, 0, 0 },
+ { 'S', 0, 2, etSRCLIST, 0, 0 },
+};
+#define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
+
+/*
+** If NOFLOATINGPOINT is defined, then none of the floating point
+** conversions will work.
+*/
+#ifndef etNOFLOATINGPOINT
+/*
+** "*val" is a double such that 0.1 <= *val < 10.0
+** Return the ascii code for the leading digit of *val, then
+** multiply "*val" by 10.0 to renormalize.
+**
+** Example:
+** input: *val = 3.14159
+** output: *val = 1.4159 function return = '3'
+**
+** The counter *cnt is incremented each time. After counter exceeds
+** 16 (the number of significant digits in a 64-bit float) '0' is
+** always returned.
+*/
+static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
+ int digit;
+ LONGDOUBLE_TYPE d;
+ if( (*cnt)++ >= 16 ) return '0';
+ digit = (int)*val;
+ d = digit;
+ digit += '0';
+ *val = (*val - d)*10.0;
+ return digit;
+}
+#endif
+
+#define etBUFSIZE 1000 /* Size of the output buffer */
+
+/*
+** The root program. All variations call this core.
+**
+** INPUTS:
+** func This is a pointer to a function taking three arguments
+** 1. A pointer to anything. Same as the "arg" parameter.
+** 2. A pointer to the list of characters to be output
+** (Note, this list is NOT null terminated.)
+** 3. An integer number of characters to be output.
+** (Note: This number might be zero.)
+**
+** arg This is the pointer to anything which will be passed as the
+** first argument to "func". Use it for whatever you like.
+**
+** fmt This is the format string, as in the usual print.
+**
+** ap This is a pointer to a list of arguments. Same as in
+** vfprint.
+**
+** OUTPUTS:
+** The return value is the total number of characters sent to
+** the function "func". Returns -1 on a error.
+**
+** Note that the order in which automatic variables are declared below
+** seems to make a big difference in determining how fast this beast
+** will run.
+*/
+static int vxprintf(
+ void (*func)(void*,const char*,int), /* Consumer of text */
+ void *arg, /* First argument to the consumer */
+ int useExtended, /* Allow extended %-conversions */
+ const char *fmt, /* Format string */
+ va_list ap /* arguments */
+){
+ int c; /* Next character in the format string */
+ char *bufpt; /* Pointer to the conversion buffer */
+ int precision; /* Precision of the current field */
+ int length; /* Length of the field */
+ int idx; /* A general purpose loop counter */
+ int count; /* Total number of characters output */
+ int width; /* Width of the current field */
+ etByte flag_leftjustify; /* True if "-" flag is present */
+ 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_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 */
+ UINT64_TYPE longvalue; /* Value for integer types */
+ LONGDOUBLE_TYPE realvalue; /* Value for real types */
+ const et_info *infop; /* Pointer to the appropriate info structure */
+ char buf[etBUFSIZE]; /* Conversion buffer */
+ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
+ etByte errorflag = 0; /* True if an error is encountered */
+ etByte xtype; /* Conversion paradigm */
+ char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
+ static const char spaces[] =
+ " ";
+#define etSPACESIZE (sizeof(spaces)-1)
+#ifndef etNOFLOATINGPOINT
+ int exp; /* 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 */
+ etByte flag_exp; /* True to force display of the exponent */
+ int nsd; /* Number of significant digits returned */
+#endif
+
+ func(arg,"",0);
+ count = length = 0;
+ bufpt = 0;
+ for(; (c=(*fmt))!=0; ++fmt){
+ if( c!='%' ){
+ int amt;
+ bufpt = (char *)fmt;
+ amt = 1;
+ while( (c=(*++fmt))!='%' && c!=0 ) amt++;
+ (*func)(arg,bufpt,amt);
+ count += amt;
+ if( c==0 ) break;
+ }
+ if( (c=(*++fmt))==0 ){
+ errorflag = 1;
+ (*func)(arg,"%",1);
+ count++;
+ break;
+ }
+ /* Find out what flags are present */
+ flag_leftjustify = flag_plussign = flag_blanksign =
+ flag_alternateform = flag_zeropad = 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;
+ }
+ }while( c==0 && (c=(*++fmt))!=0 );
+ /* Get the field width */
+ width = 0;
+ if( c=='*' ){
+ width = va_arg(ap,int);
+ if( width<0 ){
+ flag_leftjustify = 1;
+ width = -width;
+ }
+ c = *++fmt;
+ }else{
+ while( c>='0' && c<='9' ){
+ width = width*10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ if( width > etBUFSIZE-10 ){
+ width = etBUFSIZE-10;
+ }
+ /* Get the precision */
+ if( c=='.' ){
+ precision = 0;
+ c = *++fmt;
+ if( c=='*' ){
+ precision = va_arg(ap,int);
+ if( precision<0 ) precision = -precision;
+ c = *++fmt;
+ }else{
+ while( c>='0' && c<='9' ){
+ precision = precision*10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ }else{
+ precision = -1;
+ }
+ /* Get the conversion type modifier */
+ if( c=='l' ){
+ flag_long = 1;
+ c = *++fmt;
+ if( c=='l' ){
+ flag_longlong = 1;
+ c = *++fmt;
+ }else{
+ flag_longlong = 0;
+ }
+ }else{
+ flag_long = flag_longlong = 0;
+ }
+ /* Fetch the info entry for the field */
+ infop = 0;
+ xtype = etERROR;
+ for(idx=0; idx<etNINFO; idx++){
+ if( c==fmtinfo[idx].fmttype ){
+ infop = &fmtinfo[idx];
+ if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
+ xtype = infop->type;
+ }
+ break;
+ }
+ }
+ zExtra = 0;
+
+ /* Limit the precision to prevent overflowing buf[] during conversion */
+ if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
+ precision = etBUFSIZE-40;
+ }
+
+ /*
+ ** At this point, variables are initialized as follows:
+ **
+ ** flag_alternateform 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.
+ ** flag_zeropad TRUE if the width began with 0.
+ ** flag_long TRUE if the letter 'l' (ell) prefixed
+ ** the conversion character.
+ ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
+ ** the conversion character.
+ ** flag_blanksign TRUE if a ' ' is present.
+ ** width The specified field width. This is
+ ** always non-negative. Zero is the default.
+ ** precision The specified precision. The default
+ ** is -1.
+ ** xtype The class of the conversion.
+ ** infop Pointer to the appropriate info struct.
+ */
+ switch( xtype ){
+ case etPOINTER:
+ flag_longlong = sizeof(char*)==sizeof(i64);
+ flag_long = sizeof(char*)==sizeof(long int);
+ /* Fall through into the next case */
+ case etRADIX:
+ if( infop->flags & FLAG_SIGNED ){
+ i64 v;
+ if( flag_longlong ) v = va_arg(ap,i64);
+ else if( flag_long ) v = va_arg(ap,long int);
+ else v = va_arg(ap,int);
+ if( v<0 ){
+ longvalue = -v;
+ prefix = '-';
+ }else{
+ longvalue = v;
+ if( flag_plussign ) prefix = '+';
+ else if( flag_blanksign ) prefix = ' ';
+ else prefix = 0;
+ }
+ }else{
+ if( flag_longlong ) longvalue = va_arg(ap,u64);
+ else if( flag_long ) longvalue = va_arg(ap,unsigned long int);
+ else longvalue = va_arg(ap,unsigned int);
+ prefix = 0;
+ }
+ if( longvalue==0 ) flag_alternateform = 0;
+ if( flag_zeropad && precision<width-(prefix!=0) ){
+ precision = width-(prefix!=0);
+ }
+ bufpt = &buf[etBUFSIZE-1];
+ {
+ register const char *cset; /* Use registers for speed */
+ register int base;
+ cset = &aDigits[infop->charset];
+ base = infop->base;
+ do{ /* Convert to ascii */
+ *(--bufpt) = cset[longvalue%base];
+ longvalue = longvalue/base;
+ }while( longvalue>0 );
+ }
+ length = &buf[etBUFSIZE-1]-bufpt;
+ for(idx=precision-length; idx>0; idx--){
+ *(--bufpt) = '0'; /* Zero pad */
+ }
+ if( prefix ) *(--bufpt) = prefix; /* Add sign */
+ if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
+ const char *pre;
+ char x;
+ pre = &aPrefix[infop->prefix];
+ if( *bufpt!=pre[0] ){
+ for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
+ }
+ }
+ length = &buf[etBUFSIZE-1]-bufpt;
+ break;
+ case etFLOAT:
+ case etEXP:
+ case etGENERIC:
+ realvalue = va_arg(ap,double);
+#ifndef etNOFLOATINGPOINT
+ if( precision<0 ) precision = 6; /* Set default precision */
+ if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
+ if( realvalue<0.0 ){
+ realvalue = -realvalue;
+ prefix = '-';
+ }else{
+ if( flag_plussign ) prefix = '+';
+ else if( flag_blanksign ) prefix = ' ';
+ else prefix = 0;
+ }
+ if( infop->type==etGENERIC && precision>0 ) precision--;
+ rounder = 0.0;
+#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);
+#else
+ /* 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;
+ /* 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<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
+ while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
+ if( exp>350 || exp<-350 ){
+ bufpt = "NaN";
+ length = 3;
+ break;
+ }
+ }
+ bufpt = buf;
+ /*
+ ** If the field type is etGENERIC, then convert to either etEXP
+ ** or etFLOAT, as appropriate.
+ */
+ flag_exp = xtype==etEXP;
+ if( xtype!=etFLOAT ){
+ realvalue += rounder;
+ if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
+ }
+ if( xtype==etGENERIC ){
+ flag_rtz = !flag_alternateform;
+ if( exp<-4 || exp>precision ){
+ xtype = etEXP;
+ }else{
+ precision = precision - exp;
+ xtype = etFLOAT;
+ }
+ }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[].
+ */
+ nsd = 0;
+ if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
+ flag_dp = (precision>0 || 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';
+ }
+ 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;
+ }
+ 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;
+ }
+ 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 */
+ }
+ }
+ /* 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. */
+ length = bufpt-buf;
+ bufpt = buf;
+
+ /* Special case: Add leading zeros if the flag_zeropad flag is
+ ** set and we are not left justified */
+ if( flag_zeropad && !flag_leftjustify && length < width){
+ int i;
+ int nPad = width - length;
+ for(i=width; i>=nPad; i--){
+ bufpt[i] = bufpt[i-nPad];
+ }
+ i = prefix!=0;
+ while( nPad-- ) bufpt[i++] = '0';
+ length = width;
+ }
+#endif
+ break;
+ case etSIZE:
+ *(va_arg(ap,int*)) = count;
+ length = width = 0;
+ break;
+ case etPERCENT:
+ buf[0] = '%';
+ bufpt = buf;
+ length = 1;
+ break;
+ case etCHARLIT:
+ case etCHARX:
+ c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
+ if( precision>=0 ){
+ for(idx=1; idx<precision; idx++) buf[idx] = c;
+ length = precision;
+ }else{
+ length =1;
+ }
+ bufpt = buf;
+ break;
+ case etSTRING:
+ case etDYNSTRING:
+ bufpt = va_arg(ap,char*);
+ if( bufpt==0 ){
+ bufpt = "";
+ }else if( xtype==etDYNSTRING ){
+ zExtra = bufpt;
+ }
+ length = strlen(bufpt);
+ if( precision>=0 && precision<length ) length = precision;
+ break;
+ case etSQLESCAPE:
+ case etSQLESCAPE2:
+ {
+ int i, j, n, c, isnull;
+ int needQuote;
+ char *arg = va_arg(ap,char*);
+ isnull = arg==0;
+ if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
+ for(i=n=0; (c=arg[i])!=0; i++){
+ if( c=='\'' ) n++;
+ }
+ needQuote = !isnull && xtype==etSQLESCAPE2;
+ n += i + 1 + needQuote*2;
+ if( n>etBUFSIZE ){
+ 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 && precision<length ) length = precision;
+ }
+ break;
+ case etTOKEN: {
+ Token *pToken = va_arg(ap, Token*);
+ if( pToken && pToken->z ){
+ (*func)(arg, pToken->z, pToken->n);
+ }
+ length = width = 0;
+ break;
+ }
+ case etSRCLIST: {
+ SrcList *pSrc = va_arg(ap, SrcList*);
+ int k = va_arg(ap, int);
+ struct SrcList_item *pItem = &pSrc->a[k];
+ assert( k>=0 && k<pSrc->nSrc );
+ if( pItem->zDatabase && pItem->zDatabase[0] ){
+ (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
+ (*func)(arg, ".", 1);
+ }
+ (*func)(arg, pItem->zName, strlen(pItem->zName));
+ length = width = 0;
+ break;
+ }
+ case etERROR:
+ buf[0] = '%';
+ buf[1] = c;
+ errorflag = 0;
+ idx = 1+(c!=0);
+ (*func)(arg,"%",idx);
+ count += idx;
+ if( c==0 ) fmt--;
+ break;
+ }/* End switch over the format type */
+ /*
+ ** The text of the conversion is pointed to by "bufpt" and is
+ ** "length" characters long. The field width is "width". Do
+ ** the output.
+ */
+ if( !flag_leftjustify ){
+ register int nspace;
+ nspace = width-length;
+ if( nspace>0 ){
+ count += nspace;
+ while( nspace>=etSPACESIZE ){
+ (*func)(arg,spaces,etSPACESIZE);
+ nspace -= etSPACESIZE;
+ }
+ if( nspace>0 ) (*func)(arg,spaces,nspace);
+ }
+ }
+ if( length>0 ){
+ (*func)(arg,bufpt,length);
+ count += length;
+ }
+ if( flag_leftjustify ){
+ register int nspace;
+ nspace = width-length;
+ if( nspace>0 ){
+ count += nspace;
+ while( nspace>=etSPACESIZE ){
+ (*func)(arg,spaces,etSPACESIZE);
+ nspace -= etSPACESIZE;
+ }
+ if( nspace>0 ) (*func)(arg,spaces,nspace);
+ }
+ }
+ if( zExtra ){
+ sqliteFree(zExtra);
+ }
+ }/* End for loop over the format string */
+ return errorflag ? -1 : count;
+} /* End of function */
+
+
+/* This structure is used to store state information about the
+** write to memory that is currently in progress.
+*/
+struct sgMprintf {
+ char *zBase; /* A base allocation */
+ char *zText; /* The string collected so far */
+ int nChar; /* Length of the string so far */
+ int nTotal; /* Output size if unconstrained */
+ int nAlloc; /* Amount of space allocated in zText */
+ void *(*xRealloc)(void*,int); /* Function used to realloc memory */
+};
+
+/*
+** This function implements the callback from vxprintf.
+**
+** This routine add nNewChar characters of text in zNewText to
+** the sgMprintf structure pointed to by "arg".
+*/
+static void mout(void *arg, const char *zNewText, int nNewChar){
+ struct sgMprintf *pM = (struct sgMprintf*)arg;
+ pM->nTotal += nNewChar;
+ if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
+ if( pM->xRealloc==0 ){
+ nNewChar = pM->nAlloc - pM->nChar - 1;
+ }else{
+ pM->nAlloc = pM->nChar + nNewChar*2 + 1;
+ if( pM->zText==pM->zBase ){
+ pM->zText = pM->xRealloc(0, pM->nAlloc);
+ if( pM->zText && pM->nChar ){
+ memcpy(pM->zText, pM->zBase, pM->nChar);
+ }
+ }else{
+ pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
+ }
+ }
+ }
+ if( pM->zText ){
+ if( nNewChar>0 ){
+ memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
+ pM->nChar += nNewChar;
+ }
+ pM->zText[pM->nChar] = 0;
+ }
+}
+
+/*
+** This routine is a wrapper around xprintf() that invokes mout() as
+** the consumer.
+*/
+static char *base_vprintf(
+ void *(*xRealloc)(void*,int), /* Routine to realloc memory. May be NULL */
+ int useInternal, /* Use internal %-conversions if true */
+ char *zInitBuf, /* Initially write here, before mallocing */
+ int nInitBuf, /* Size of zInitBuf[] */
+ const char *zFormat, /* format string */
+ va_list ap /* arguments */
+){
+ struct sgMprintf sM;
+ sM.zBase = sM.zText = zInitBuf;
+ sM.nChar = sM.nTotal = 0;
+ sM.nAlloc = nInitBuf;
+ sM.xRealloc = xRealloc;
+ vxprintf(mout, &sM, useInternal, zFormat, ap);
+ if( xRealloc ){
+ if( sM.zText==sM.zBase ){
+ sM.zText = xRealloc(0, sM.nChar+1);
+ if( sM.zText ){
+ memcpy(sM.zText, sM.zBase, sM.nChar+1);
+ }
+ }else if( sM.nAlloc>sM.nChar+10 ){
+ sM.zText = xRealloc(sM.zText, sM.nChar+1);
+ }
+ }
+ return sM.zText;
+}
+
+/*
+** Realloc that is a real function, not a macro.
+*/
+static void *printf_realloc(void *old, int size){
+ return sqliteRealloc(old,size);
+}
+
+/*
+** Print into memory obtained from sqliteMalloc(). Use the internal
+** %-conversion extensions.
+*/
+char *sqlite3VMPrintf(const char *zFormat, va_list ap){
+ char zBase[1000];
+ return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
+}
+
+/*
+** Print into memory obtained from sqliteMalloc(). Use the internal
+** %-conversion extensions.
+*/
+char *sqlite3MPrintf(const char *zFormat, ...){
+ va_list ap;
+ char *z;
+ char zBase[1000];
+ va_start(ap, zFormat);
+ z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
+ va_end(ap);
+ return z;
+}
+
+/*
+** Print into memory obtained from malloc(). Do not use the internal
+** %-conversion extensions. This routine is for use by external users.
+*/
+char *sqlite3_mprintf(const char *zFormat, ...){
+ va_list ap;
+ char *z;
+ char zBuf[200];
+
+ va_start(ap,zFormat);
+ z = base_vprintf((void*(*)(void*,int))realloc, 0,
+ zBuf, sizeof(zBuf), zFormat, ap);
+ va_end(ap);
+ return z;
+}
+
+/* This is the varargs version of sqlite3_mprintf.
+*/
+char *sqlite3_vmprintf(const char *zFormat, va_list ap){
+ char zBuf[200];
+ return base_vprintf((void*(*)(void*,int))realloc, 0,
+ zBuf, sizeof(zBuf), zFormat, ap);
+}
+
+/*
+** sqlite3_snprintf() works like snprintf() except that it ignores the
+** current locale settings. This is important for SQLite because we
+** are not able to use a "," as the decimal point in place of "." as
+** specified by some locales.
+*/
+char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
+ char *z;
+ va_list ap;
+
+ va_start(ap,zFormat);
+ z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
+ va_end(ap);
+ return z;
+}
+
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+/*
+** A version of printf() that understands %lld. Used for debugging.
+** The printf() built into some versions of windows does not understand %lld
+** and segfaults if you give it a long long int.
+*/
+void sqlite3DebugPrintf(const char *zFormat, ...){
+ extern int getpid(void);
+ va_list ap;
+ char zBuf[500];
+ va_start(ap, zFormat);
+ base_vprintf(0, 0, zBuf, sizeof(zBuf), zFormat, ap);
+ va_end(ap);
+ fprintf(stdout,"%d: %s", getpid(), zBuf);
+ fflush(stdout);
+}
+#endif
diff --git a/src/sqlite/random.c b/src/sqlite/random.c
new file mode 100644
index 0000000..fe1ac02
--- /dev/null
+++ b/src/sqlite/random.c
@@ -0,0 +1,100 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code to implement a pseudo-random number
+** generator (PRNG) for SQLite.
+**
+** Random numbers are used by some of the database backends in order
+** to generate random integer keys for tables or random filenames.
+**
+** $Id: random.c,v 1.1.1.1 2006/02/03 20:35:12 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+
+
+/*
+** Get a single 8-bit random value from the RC4 PRNG. The Mutex
+** must be held while executing this routine.
+**
+** Why not just use a library random generator like lrand48() for this?
+** Because the OP_NewRowid opcode in the VDBE depends on having a very
+** good source of random numbers. The lrand48() library function may
+** well be good enough. But maybe not. Or maybe lrand48() has some
+** subtle problems on some systems that could cause problems. It is hard
+** to know. To minimize the risk of problems due to bad lrand48()
+** implementations, SQLite uses this random number generator based
+** on RC4, which we know works very well.
+**
+** (Later): Actually, OP_NewRowid does not depend on a good source of
+** randomness any more. But we will leave this code in all the same.
+*/
+static int randomByte(){
+ unsigned char t;
+
+ /* All threads share a single random number generator.
+ ** This structure is the current state of the generator.
+ */
+ static struct {
+ unsigned char isInit; /* True if initialized */
+ unsigned char i, j; /* State variables */
+ unsigned char s[256]; /* State variables */
+ } prng;
+
+ /* Initialize the state of the random number generator once,
+ ** the first time this routine is called. The seed value does
+ ** not need to contain a lot of randomness since we are not
+ ** trying to do secure encryption or anything like that...
+ **
+ ** Nothing in this file or anywhere else in SQLite does any kind of
+ ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
+ ** number generator) not as an encryption device.
+ */
+ if( !prng.isInit ){
+ int i;
+ char k[256];
+ prng.j = 0;
+ prng.i = 0;
+ sqlite3OsRandomSeed(k);
+ for(i=0; i<256; i++){
+ prng.s[i] = i;
+ }
+ for(i=0; i<256; i++){
+ prng.j += prng.s[i] + k[i];
+ t = prng.s[prng.j];
+ prng.s[prng.j] = prng.s[i];
+ prng.s[i] = t;
+ }
+ prng.isInit = 1;
+ }
+
+ /* Generate and return single random byte
+ */
+ prng.i++;
+ t = prng.s[prng.i];
+ prng.j += t;
+ prng.s[prng.i] = prng.s[prng.j];
+ prng.s[prng.j] = t;
+ t += prng.s[prng.i];
+ return prng.s[t];
+}
+
+/*
+** Return N random bytes.
+*/
+void sqlite3Randomness(int N, void *pBuf){
+ unsigned char *zBuf = pBuf;
+ sqlite3OsEnterMutex();
+ while( N-- ){
+ *(zBuf++) = randomByte();
+ }
+ sqlite3OsLeaveMutex();
+}
diff --git a/src/sqlite/select.c b/src/sqlite/select.c
new file mode 100644
index 0000000..7f30ef0
--- /dev/null
+++ b/src/sqlite/select.c
@@ -0,0 +1,2868 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** to handle SELECT statements in SQLite.
+**
+** $Id: select.c,v 1.1.1.1 2006/02/03 20:35:14 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+
+
+/*
+** Allocate a new Select structure and return a pointer to that
+** structure.
+*/
+Select *sqlite3SelectNew(
+ ExprList *pEList, /* which columns to include in the result */
+ SrcList *pSrc, /* the FROM clause -- which tables to scan */
+ Expr *pWhere, /* the WHERE clause */
+ ExprList *pGroupBy, /* the GROUP BY clause */
+ Expr *pHaving, /* the HAVING clause */
+ ExprList *pOrderBy, /* the ORDER BY clause */
+ int isDistinct, /* true if the DISTINCT keyword is present */
+ Expr *pLimit, /* LIMIT value. NULL means not used */
+ Expr *pOffset /* OFFSET value. NULL means no offset */
+){
+ Select *pNew;
+ pNew = sqliteMalloc( sizeof(*pNew) );
+ assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */
+ if( pNew==0 ){
+ sqlite3ExprListDelete(pEList);
+ sqlite3SrcListDelete(pSrc);
+ sqlite3ExprDelete(pWhere);
+ sqlite3ExprListDelete(pGroupBy);
+ sqlite3ExprDelete(pHaving);
+ sqlite3ExprListDelete(pOrderBy);
+ sqlite3ExprDelete(pLimit);
+ sqlite3ExprDelete(pOffset);
+ }else{
+ if( pEList==0 ){
+ pEList = sqlite3ExprListAppend(0, sqlite3Expr(TK_ALL,0,0,0), 0);
+ }
+ pNew->pEList = pEList;
+ pNew->pSrc = pSrc;
+ pNew->pWhere = pWhere;
+ pNew->pGroupBy = pGroupBy;
+ pNew->pHaving = pHaving;
+ pNew->pOrderBy = pOrderBy;
+ pNew->isDistinct = isDistinct;
+ pNew->op = TK_SELECT;
+ pNew->pLimit = pLimit;
+ pNew->pOffset = pOffset;
+ pNew->iLimit = -1;
+ pNew->iOffset = -1;
+ }
+ return pNew;
+}
+
+/*
+** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
+** type of join. Return an integer constant that expresses that type
+** in terms of the following bit values:
+**
+** JT_INNER
+** JT_OUTER
+** JT_NATURAL
+** JT_LEFT
+** JT_RIGHT
+**
+** A full outer join is the combination of JT_LEFT and JT_RIGHT.
+**
+** If an illegal or unsupported join type is seen, then still return
+** a join type, but put an error in the pParse structure.
+*/
+int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
+ int jointype = 0;
+ Token *apAll[3];
+ Token *p;
+ static const struct {
+ const char *zKeyword;
+ u8 nChar;
+ u8 code;
+ } keywords[] = {
+ { "natural", 7, JT_NATURAL },
+ { "left", 4, JT_LEFT|JT_OUTER },
+ { "right", 5, JT_RIGHT|JT_OUTER },
+ { "full", 4, JT_LEFT|JT_RIGHT|JT_OUTER },
+ { "outer", 5, JT_OUTER },
+ { "inner", 5, JT_INNER },
+ { "cross", 5, JT_INNER },
+ };
+ int i, j;
+ apAll[0] = pA;
+ apAll[1] = pB;
+ apAll[2] = pC;
+ for(i=0; i<3 && apAll[i]; i++){
+ p = apAll[i];
+ for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
+ if( p->n==keywords[j].nChar
+ && sqlite3StrNICmp(p->z, keywords[j].zKeyword, p->n)==0 ){
+ jointype |= keywords[j].code;
+ break;
+ }
+ }
+ if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
+ jointype |= JT_ERROR;
+ break;
+ }
+ }
+ if(
+ (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
+ (jointype & JT_ERROR)!=0
+ ){
+ const char *zSp1 = " ";
+ const char *zSp2 = " ";
+ if( pB==0 ){ zSp1++; }
+ if( pC==0 ){ zSp2++; }
+ sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
+ "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC);
+ jointype = JT_INNER;
+ }else if( jointype & JT_RIGHT ){
+ sqlite3ErrorMsg(pParse,
+ "RIGHT and FULL OUTER JOINs are not currently supported");
+ jointype = JT_INNER;
+ }
+ return jointype;
+}
+
+/*
+** Return the index of a column in a table. Return -1 if the column
+** is not contained in the table.
+*/
+static int columnIndex(Table *pTab, const char *zCol){
+ int i;
+ for(i=0; i<pTab->nCol; i++){
+ if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
+ }
+ return -1;
+}
+
+/*
+** Set the value of a token to a '\000'-terminated string.
+*/
+static void setToken(Token *p, const char *z){
+ p->z = z;
+ p->n = strlen(z);
+ p->dyn = 0;
+}
+
+
+/*
+** Add a term to the WHERE expression in *ppExpr that requires the
+** zCol column to be equal in the two tables pTab1 and pTab2.
+*/
+static void addWhereTerm(
+ const char *zCol, /* Name of the column */
+ const Table *pTab1, /* First table */
+ const char *zAlias1, /* Alias for first table. May be NULL */
+ const Table *pTab2, /* Second table */
+ const char *zAlias2, /* Alias for second table. May be NULL */
+ Expr **ppExpr /* Add the equality term to this expression */
+){
+ Token dummy;
+ 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);
+ if( zAlias1==0 ){
+ zAlias1 = pTab1->zName;
+ }
+ setToken(&dummy, zAlias1);
+ pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy);
+ if( zAlias2==0 ){
+ zAlias2 = pTab2->zName;
+ }
+ setToken(&dummy, zAlias2);
+ pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy);
+ pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0);
+ pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0);
+ pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0);
+ ExprSetProperty(pE, EP_FromJoin);
+ *ppExpr = sqlite3ExprAnd(*ppExpr, pE);
+}
+
+/*
+** Set the EP_FromJoin property on all terms of the given expression.
+**
+** The EP_FromJoin property is used on terms of an expression to tell
+** the LEFT OUTER JOIN processing logic that this term is part of the
+** join restriction specified in the ON or USING clause and not a part
+** of the more general WHERE clause. These terms are moved over to the
+** WHERE clause during join processing but we need to remember that they
+** originated in the ON or USING clause.
+*/
+static void setJoinExpr(Expr *p){
+ while( p ){
+ ExprSetProperty(p, EP_FromJoin);
+ setJoinExpr(p->pLeft);
+ p = p->pRight;
+ }
+}
+
+/*
+** This routine processes the join information for a SELECT statement.
+** ON and USING clauses are converted into extra terms of the WHERE clause.
+** NATURAL joins also create extra WHERE clause terms.
+**
+** The terms of a FROM clause are contained in the Select.pSrc structure.
+** The left most table is the first entry in Select.pSrc. The right-most
+** table is the last entry. The join operator is held in the entry to
+** the left. Thus entry 0 contains the join operator for the join between
+** entries 0 and 1. Any ON or USING clauses associated with the join are
+** also attached to the left entry.
+**
+** This routine returns the number of errors encountered.
+*/
+static int sqliteProcessJoin(Parse *pParse, Select *p){
+ SrcList *pSrc; /* All tables in the FROM clause */
+ int i, j; /* Loop counters */
+ struct SrcList_item *pLeft; /* Left table being joined */
+ struct SrcList_item *pRight; /* Right table being joined */
+
+ pSrc = p->pSrc;
+ pLeft = &pSrc->a[0];
+ pRight = &pLeft[1];
+ for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
+ Table *pLeftTab = pLeft->pTab;
+ Table *pRightTab = pRight->pTab;
+
+ if( pLeftTab==0 || pRightTab==0 ) continue;
+
+ /* When the NATURAL keyword is present, add WHERE clause terms for
+ ** every column that the two tables have in common.
+ */
+ if( pLeft->jointype & JT_NATURAL ){
+ if( pLeft->pOn || pLeft->pUsing ){
+ sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
+ "an ON or USING clause", 0);
+ return 1;
+ }
+ for(j=0; j<pLeftTab->nCol; j++){
+ char *zName = pLeftTab->aCol[j].zName;
+ if( columnIndex(pRightTab, zName)>=0 ){
+ addWhereTerm(zName, pLeftTab, pLeft->zAlias,
+ pRightTab, pRight->zAlias, &p->pWhere);
+ }
+ }
+ }
+
+ /* Disallow both ON and USING clauses in the same join
+ */
+ if( pLeft->pOn && pLeft->pUsing ){
+ sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
+ "clauses in the same join");
+ return 1;
+ }
+
+ /* Add the ON clause to the end of the WHERE clause, connected by
+ ** an AND operator.
+ */
+ if( pLeft->pOn ){
+ setJoinExpr(pLeft->pOn);
+ p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn);
+ pLeft->pOn = 0;
+ }
+
+ /* Create extra terms on the WHERE clause for each column named
+ ** in the USING clause. Example: If the two tables to be joined are
+ ** A and B and the USING clause names X, Y, and Z, then add this
+ ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
+ ** Report an error if any column mentioned in the USING clause is
+ ** not contained in both tables to be joined.
+ */
+ if( pLeft->pUsing ){
+ IdList *pList = pLeft->pUsing;
+ for(j=0; j<pList->nId; j++){
+ char *zName = pList->a[j].zName;
+ if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
+ sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
+ "not present in both tables", zName);
+ return 1;
+ }
+ addWhereTerm(zName, pLeftTab, pLeft->zAlias,
+ pRightTab, pRight->zAlias, &p->pWhere);
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Delete the given Select structure and all of its substructures.
+*/
+void sqlite3SelectDelete(Select *p){
+ if( p==0 ) return;
+ sqlite3ExprListDelete(p->pEList);
+ sqlite3SrcListDelete(p->pSrc);
+ sqlite3ExprDelete(p->pWhere);
+ sqlite3ExprListDelete(p->pGroupBy);
+ sqlite3ExprDelete(p->pHaving);
+ sqlite3ExprListDelete(p->pOrderBy);
+ sqlite3SelectDelete(p->pPrior);
+ sqlite3ExprDelete(p->pLimit);
+ sqlite3ExprDelete(p->pOffset);
+ sqliteFree(p);
+}
+
+/*
+** Insert code into "v" that will push the record on the top of the
+** stack into the sorter.
+*/
+static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
+ int i;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr);
+ }
+ sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0);
+ sqlite3VdbeAddOp(v, OP_SortInsert, 0, 0);
+}
+
+/*
+** Add code to implement the OFFSET and LIMIT
+*/
+static void codeLimiter(
+ Vdbe *v, /* Generate code into this VM */
+ Select *p, /* The SELECT statement being coded */
+ int iContinue, /* Jump here to skip the current record */
+ int iBreak, /* Jump here to end the loop */
+ int nPop /* Number of times to pop stack when jumping */
+){
+ if( p->iOffset>=0 ){
+ int addr = sqlite3VdbeCurrentAddr(v) + 3;
+ if( nPop>0 ) addr++;
+ sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, 0);
+ sqlite3VdbeAddOp(v, OP_IfMemPos, p->iOffset, addr);
+ if( nPop>0 ){
+ sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
+ }
+ sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
+ VdbeComment((v, "# skip OFFSET records"));
+ }
+ if( p->iLimit>=0 ){
+ sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
+ VdbeComment((v, "# exit when LIMIT reached"));
+ }
+}
+
+/*
+** This routine generates the code for the inside of the inner loop
+** of a SELECT.
+**
+** If srcTab and nColumn are both zero, then the pEList expressions
+** are evaluated in order to get the data for this row. If nColumn>0
+** then data is pulled from srcTab and pEList is used only to get the
+** datatypes for each column.
+*/
+static int selectInnerLoop(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The complete select statement being coded */
+ ExprList *pEList, /* List of values being extracted */
+ int srcTab, /* Pull data from this table */
+ int nColumn, /* Number of columns in the source table */
+ ExprList *pOrderBy, /* If not NULL, sort results using this key */
+ int distinct, /* If >=0, make sure results are distinct */
+ int eDest, /* How to dispose of the results */
+ int iParm, /* An argument to the disposal method */
+ int iContinue, /* Jump here to continue with next row */
+ int iBreak, /* Jump here to break out of the inner loop */
+ char *aff /* affinity string if eDest is SRT_Union */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ int hasDistinct; /* True if the DISTINCT keyword is present */
+
+ if( v==0 ) return 0;
+ assert( pEList!=0 );
+
+ /* If there was a LIMIT clause on the SELECT statement, then do the check
+ ** to see if this row should be output.
+ */
+ hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
+ if( pOrderBy==0 && !hasDistinct ){
+ codeLimiter(v, p, iContinue, iBreak, 0);
+ }
+
+ /* Pull the requested columns.
+ */
+ if( nColumn>0 ){
+ for(i=0; i<nColumn; i++){
+ sqlite3VdbeAddOp(v, OP_Column, srcTab, i);
+ }
+ }else{
+ nColumn = pEList->nExpr;
+ for(i=0; i<pEList->nExpr; i++){
+ sqlite3ExprCode(pParse, pEList->a[i].pExpr);
+ }
+ }
+
+ /* If the DISTINCT keyword was present on the SELECT statement
+ ** and this row has been seen before, then do not make this row
+ ** part of the result.
+ */
+ if( hasDistinct ){
+#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_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
+ VdbeComment((v, "# skip indistinct records"));
+ sqlite3VdbeAddOp(v, OP_IdxInsert, distinct, 0);
+ if( pOrderBy==0 ){
+ codeLimiter(v, p, iContinue, iBreak, nColumn);
+ }
+ }
+
+ switch( eDest ){
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+ /* In this mode, write each query result to the key of the temporary
+ ** table iParm.
+ */
+ case SRT_Union: {
+ sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
+ sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
+ sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);
+ break;
+ }
+
+ /* Construct a record from the query result, but instead of
+ ** saving that record, use it as a key to delete elements from
+ ** the temporary table iParm.
+ */
+ case SRT_Except: {
+ int addr;
+ addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
+ sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
+ sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
+ sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
+ break;
+ }
+#endif
+
+ /* Store the result as data using a unique key.
+ */
+ case SRT_Table:
+ case SRT_TempTable: {
+ sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ if( pOrderBy ){
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
+ sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
+ }
+ break;
+ }
+
+#ifndef SQLITE_OMIT_SUBQUERY
+ /* If we are creating a set for an "expr IN (SELECT ...)" construct,
+ ** then there should be a single item on the stack. Write this
+ ** item into the set table with bogus data.
+ */
+ case SRT_Set: {
+ int addr1 = sqlite3VdbeCurrentAddr(v);
+ int addr2;
+
+ assert( nColumn==1 );
+ sqlite3VdbeAddOp(v, OP_NotNull, -1, addr1+3);
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
+ if( pOrderBy ){
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ char aff = (iParm>>16)&0xFF;
+ aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
+ sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
+ sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
+ }
+ sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v));
+ break;
+ }
+
+ /* If this is a scalar select that is part of an expression, then
+ ** store the results in the appropriate memory cell and break out
+ ** of the scan loop.
+ */
+ case SRT_Exists:
+ case SRT_Mem: {
+ assert( nColumn==1 );
+ if( pOrderBy ){
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, iBreak);
+ }
+ break;
+ }
+#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
+
+ /* Send the data to the callback function.
+ */
+ case SRT_Callback:
+ case SRT_Sorter: {
+ if( pOrderBy ){
+ sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ assert( eDest==SRT_Callback );
+ 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
+ ** user-defined functions that have side effects. We do not care
+ ** about the actual results of the select.
+ */
+ default: {
+ assert( eDest==SRT_Discard );
+ sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
+ break;
+ }
+#endif
+ }
+ return 0;
+}
+
+/*
+** If the inner loop was generated using a non-null pOrderBy argument,
+** then the results were placed in a sorter. After the loop is terminated
+** we need to run the sorter and output the results. The following
+** routine generates the code needed to do that.
+*/
+static void generateSortTail(
+ Parse *pParse, /* The parsing context */
+ Select *p, /* The SELECT statement */
+ Vdbe *v, /* Generate code into this VDBE */
+ int nColumn, /* Number of columns of data */
+ int eDest, /* Write the sorted results here */
+ int iParm /* Optional parameter associated with eDest */
+){
+ int end1 = sqlite3VdbeMakeLabel(v);
+ int end2 = sqlite3VdbeMakeLabel(v);
+ int addr;
+ KeyInfo *pInfo;
+ ExprList *pOrderBy;
+ int nCol, i;
+ sqlite3 *db = pParse->db;
+
+ if( eDest==SRT_Sorter ) return;
+ pOrderBy = p->pOrderBy;
+ nCol = pOrderBy->nExpr;
+ pInfo = sqliteMalloc( sizeof(*pInfo) + nCol*(sizeof(CollSeq*)+1) );
+ if( pInfo==0 ) return;
+ pInfo->aSortOrder = (char*)&pInfo->aColl[nCol];
+ pInfo->nField = nCol;
+ for(i=0; i<nCol; i++){
+ /* If a collation sequence was specified explicity, then it
+ ** is stored in pOrderBy->a[i].zName. Otherwise, use the default
+ ** collation type for the expression.
+ */
+ pInfo->aColl[i] = sqlite3ExprCollSeq(pParse, pOrderBy->a[i].pExpr);
+ if( !pInfo->aColl[i] ){
+ pInfo->aColl[i] = db->pDfltColl;
+ }
+ pInfo->aSortOrder[i] = pOrderBy->a[i].sortOrder;
+ }
+ sqlite3VdbeOp3(v, OP_Sort, 0, 0, (char*)pInfo, P3_KEYINFO_HANDOFF);
+ addr = sqlite3VdbeAddOp(v, OP_SortNext, 0, end1);
+ codeLimiter(v, p, addr, end2, 1);
+ switch( eDest ){
+ case SRT_Table:
+ case SRT_TempTable: {
+ sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
+ sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
+ break;
+ }
+#ifndef SQLITE_OMIT_SUBQUERY
+ case SRT_Set: {
+ assert( nColumn==1 );
+ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
+ sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
+ break;
+ }
+ case SRT_Exists:
+ case SRT_Mem: {
+ assert( nColumn==1 );
+ sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, end1);
+ break;
+ }
+#endif
+ case SRT_Callback:
+ case SRT_Subroutine: {
+ int i;
+ sqlite3VdbeAddOp(v, OP_Integer, p->pEList->nExpr, 0);
+ sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
+ for(i=0; i<nColumn; i++){
+ sqlite3VdbeAddOp(v, OP_Column, -1-i, i);
+ }
+ if( eDest==SRT_Callback ){
+ sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
+ }
+ sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
+ break;
+ }
+ default: {
+ /* Do nothing */
+ break;
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
+ sqlite3VdbeResolveLabel(v, end2);
+ sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+ sqlite3VdbeResolveLabel(v, end1);
+ sqlite3VdbeAddOp(v, OP_SortReset, 0, 0);
+}
+
+/*
+** Return a pointer to a string containing the 'declaration type' of the
+** expression pExpr. The string may be treated as static by the caller.
+**
+** If the declaration type is the exact datatype definition extracted from
+** the original CREATE TABLE statement if the expression is a column.
+**
+** The declaration type for an expression is either TEXT, NUMERIC or ANY.
+** The declaration type for a ROWID field is INTEGER.
+*/
+static const char *columnType(NameContext *pNC, Expr *pExpr){
+ char const *zType;
+ int j;
+ if( pExpr==0 || pNC->pSrcList==0 ) return 0;
+
+ /* The TK_AS operator can only occur in ORDER BY, GROUP BY, HAVING,
+ ** and LIMIT clauses. But pExpr originates in the result set of a
+ ** SELECT. So pExpr can never contain an AS operator.
+ */
+ assert( pExpr->op!=TK_AS );
+
+ switch( pExpr->op ){
+ case TK_COLUMN: {
+ Table *pTab = 0;
+ int iCol = pExpr->iColumn;
+ while( pNC && !pTab ){
+ SrcList *pTabList = pNC->pSrcList;
+ for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
+ if( j<pTabList->nSrc ){
+ pTab = pTabList->a[j].pTab;
+ }else{
+ pNC = pNC->pNext;
+ }
+ }
+ if( pTab==0 ){
+ /* FIX ME:
+ ** This can occurs if you have something like "SELECT new.x;" inside
+ ** a trigger. In other words, if you reference the special "new"
+ ** table in the result set of a select. We do not have a good way
+ ** to find the actual table type, so call it "TEXT". This is really
+ ** something of a bug, but I do not know how to fix it.
+ **
+ ** This code does not produce the correct answer - it just prevents
+ ** a segfault. See ticket #1229.
+ */
+ zType = "TEXT";
+ break;
+ }
+ assert( pTab );
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+ if( iCol<0 ){
+ zType = "INTEGER";
+ }else{
+ zType = pTab->aCol[iCol].zType;
+ }
+ break;
+ }
+#ifndef SQLITE_OMIT_SUBQUERY
+ case TK_SELECT: {
+ NameContext sNC;
+ Select *pS = pExpr->pSelect;
+ sNC.pSrcList = pExpr->pSelect->pSrc;
+ sNC.pNext = pNC;
+ zType = columnType(&sNC, pS->pEList->a[0].pExpr);
+ break;
+ }
+#endif
+ default:
+ zType = 0;
+ }
+
+ return zType;
+}
+
+/*
+** Generate code that will tell the VDBE the declaration types of columns
+** in the result set.
+*/
+static void generateColumnTypes(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* List of tables */
+ ExprList *pEList /* Expressions defining the result set */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ NameContext sNC;
+ sNC.pSrcList = pTabList;
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *p = pEList->a[i].pExpr;
+ const char *zType = columnType(&sNC, p);
+ if( zType==0 ) continue;
+ /* The vdbe must make it's own copy of the column-type, in case the
+ ** schema is reset before this virtual machine is deleted.
+ */
+ sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, strlen(zType));
+ }
+}
+
+/*
+** Generate code that will tell the VDBE the names of columns
+** in the result set. This information is used to provide the
+** azCol[] values in the callback.
+*/
+static void generateColumnNames(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* List of tables */
+ ExprList *pEList /* Expressions defining the result set */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i, j;
+ sqlite3 *db = pParse->db;
+ int fullNames, shortNames;
+
+#ifndef SQLITE_OMIT_EXPLAIN
+ /* If this is an EXPLAIN, skip this step */
+ if( pParse->explain ){
+ return;
+ }
+#endif
+
+ assert( v!=0 );
+ if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;
+ pParse->colNamesSet = 1;
+ fullNames = (db->flags & SQLITE_FullColNames)!=0;
+ shortNames = (db->flags & SQLITE_ShortColNames)!=0;
+ sqlite3VdbeSetNumCols(v, pEList->nExpr);
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *p;
+ p = pEList->a[i].pExpr;
+ if( p==0 ) continue;
+ if( pEList->a[i].zName ){
+ char *zName = pEList->a[i].zName;
+ sqlite3VdbeSetColName(v, i, zName, strlen(zName));
+ continue;
+ }
+ if( p->op==TK_COLUMN && pTabList ){
+ Table *pTab;
+ char *zCol;
+ int iCol = p->iColumn;
+ for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
+ assert( j<pTabList->nSrc );
+ pTab = pTabList->a[j].pTab;
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+ if( iCol<0 ){
+ zCol = "rowid";
+ }else{
+ zCol = pTab->aCol[iCol].zName;
+ }
+ if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
+ sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
+ }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
+ char *zName = 0;
+ char *zTab;
+
+ zTab = pTabList->a[j].zAlias;
+ if( fullNames || zTab==0 ) zTab = pTab->zName;
+ sqlite3SetString(&zName, zTab, ".", zCol, 0);
+ sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
+ }else{
+ sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
+ }
+ }else if( p->span.z && p->span.z[0] ){
+ sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
+ /* sqlite3VdbeCompressSpace(v, addr); */
+ }else{
+ char zName[30];
+ assert( p->op!=TK_COLUMN || pTabList==0 );
+ sprintf(zName, "column%d", i+1);
+ sqlite3VdbeSetColName(v, i, zName, 0);
+ }
+ }
+ generateColumnTypes(pParse, pTabList, pEList);
+}
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+/*
+** Name of the connection operator, used for error messages.
+*/
+static const char *selectOpName(int id){
+ char *z;
+ switch( id ){
+ case TK_ALL: z = "UNION ALL"; break;
+ case TK_INTERSECT: z = "INTERSECT"; break;
+ case TK_EXCEPT: z = "EXCEPT"; break;
+ default: z = "UNION"; break;
+ }
+ return z;
+}
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
+
+/*
+** Forward declaration
+*/
+static int prepSelectStmt(Parse*, Select*);
+
+/*
+** Given a SELECT statement, generate a Table structure that describes
+** the result set of that SELECT.
+*/
+Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
+ Table *pTab;
+ int i, j;
+ ExprList *pEList;
+ Column *aCol, *pCol;
+
+ if( prepSelectStmt(pParse, pSelect) ){
+ return 0;
+ }
+ if( sqlite3SelectResolve(pParse, pSelect, 0) ){
+ return 0;
+ }
+ pTab = sqliteMalloc( sizeof(Table) );
+ if( pTab==0 ){
+ return 0;
+ }
+ pTab->nRef = 1;
+ pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0;
+ pEList = pSelect->pEList;
+ pTab->nCol = pEList->nExpr;
+ assert( pTab->nCol>0 );
+ pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
+ for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
+ Expr *p, *pR;
+ char *zType;
+ char *zName;
+ char *zBasename;
+ int cnt;
+ NameContext sNC;
+
+ /* Get an appropriate name for the column
+ */
+ p = pEList->a[i].pExpr;
+ assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
+ if( (zName = pEList->a[i].zName)!=0 ){
+ /* If the column contains an "AS <name>" phrase, use <name> as the name */
+ zName = sqliteStrDup(zName);
+ }else if( p->op==TK_DOT
+ && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
+ /* For columns of the from A.B use B as the name */
+ zName = sqlite3MPrintf("%T", &pR->token);
+ }else if( p->span.z && p->span.z[0] ){
+ /* Use the original text of the column expression as its name */
+ zName = sqlite3MPrintf("%T", &p->span);
+ }else{
+ /* If all else fails, make up a name */
+ zName = sqlite3MPrintf("column%d", i+1);
+ }
+ sqlite3Dequote(zName);
+ if( sqlite3_malloc_failed ){
+ sqliteFree(zName);
+ sqlite3DeleteTable(0, pTab);
+ return 0;
+ }
+
+ /* Make sure the column name is unique. If the name is not unique,
+ ** append a integer to the name so that it becomes unique.
+ */
+ zBasename = zName;
+ for(j=cnt=0; j<i; j++){
+ if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
+ zName = sqlite3MPrintf("%s:%d", zBasename, ++cnt);
+ j = -1;
+ if( zName==0 ) break;
+ }
+ }
+ if( zBasename!=zName ){
+ sqliteFree(zBasename);
+ }
+ pCol->zName = zName;
+
+ /* Get the typename, type affinity, and collating sequence for the
+ ** column.
+ */
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pSrcList = pSelect->pSrc;
+ zType = sqliteStrDup(columnType(&sNC, p));
+ pCol->zType = zType;
+ pCol->affinity = sqlite3ExprAffinity(p);
+ pCol->pColl = sqlite3ExprCollSeq(pParse, p);
+ if( !pCol->pColl ){
+ pCol->pColl = pParse->db->pDfltColl;
+ }
+ }
+ pTab->iPKey = -1;
+ return pTab;
+}
+
+/*
+** Prepare a SELECT statement for processing by doing the following
+** things:
+**
+** (1) Make sure VDBE cursor numbers have been assigned to every
+** element of the FROM clause.
+**
+** (2) Fill in the pTabList->a[].pTab fields in the SrcList that
+** defines FROM clause. When views appear in the FROM clause,
+** fill pTabList->a[].pSelect with a copy of the SELECT statement
+** that implements the view. A copy is made of the view's SELECT
+** statement so that we can freely modify or delete that statement
+** without worrying about messing up the presistent representation
+** of the view.
+**
+** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword
+** on joins and the ON and USING clause of joins.
+**
+** (4) Scan the list of columns in the result set (pEList) looking
+** for instances of the "*" operator or the TABLE.* operator.
+** If found, expand each "*" to be every column in every table
+** and TABLE.* to be every column in TABLE.
+**
+** Return 0 on success. If there are problems, leave an error message
+** in pParse and return non-zero.
+*/
+static int prepSelectStmt(Parse *pParse, Select *p){
+ int i, j, k, rc;
+ SrcList *pTabList;
+ ExprList *pEList;
+ Table *pTab;
+ struct SrcList_item *pFrom;
+
+ if( p==0 || p->pSrc==0 || sqlite3_malloc_failed ) return 1;
+ pTabList = p->pSrc;
+ pEList = p->pEList;
+
+ /* Make sure cursor numbers have been assigned to all entries in
+ ** the FROM clause of the SELECT statement.
+ */
+ sqlite3SrcListAssignCursors(pParse, p->pSrc);
+
+ /* Look up every table named in the FROM clause of the select. If
+ ** an entry of the FROM clause is a subquery instead of a table or view,
+ ** then create a transient table structure to describe the subquery.
+ */
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ if( pFrom->pTab!=0 ){
+ /* This statement has already been prepared. There is no need
+ ** to go further. */
+ assert( i==0 );
+ return 0;
+ }
+ if( pFrom->zName==0 ){
+#ifndef SQLITE_OMIT_SUBQUERY
+ /* A sub-query in the FROM clause of a SELECT */
+ assert( pFrom->pSelect!=0 );
+ if( pFrom->zAlias==0 ){
+ pFrom->zAlias =
+ sqlite3MPrintf("sqlite_subquery_%p_", (void*)pFrom->pSelect);
+ }
+ assert( pFrom->pTab==0 );
+ pFrom->pTab = pTab =
+ sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect);
+ if( pTab==0 ){
+ return 1;
+ }
+ /* The isTransient flag indicates that the Table structure has been
+ ** dynamically allocated and may be freed at any time. In other words,
+ ** pTab is not pointing to a persistent table structure that defines
+ ** part of the schema. */
+ pTab->isTransient = 1;
+#endif
+ }else{
+ /* An ordinary table or view name in the FROM clause */
+ assert( pFrom->pTab==0 );
+ pFrom->pTab = pTab =
+ sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase);
+ if( pTab==0 ){
+ return 1;
+ }
+ pTab->nRef++;
+#ifndef SQLITE_OMIT_VIEW
+ if( pTab->pSelect ){
+ /* We reach here if the named table is a really a view */
+ if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+ return 1;
+ }
+ /* If pFrom->pSelect!=0 it means we are dealing with a
+ ** view within a view. The SELECT structure has already been
+ ** copied by the outer view so we can skip the copy step here
+ ** in the inner view.
+ */
+ if( pFrom->pSelect==0 ){
+ pFrom->pSelect = sqlite3SelectDup(pTab->pSelect);
+ }
+ }
+#endif
+ }
+ }
+
+ /* Process NATURAL keywords, and ON and USING clauses of joins.
+ */
+ if( sqliteProcessJoin(pParse, p) ) return 1;
+
+ /* For every "*" that occurs in the column list, insert the names of
+ ** all columns in all tables. And for every TABLE.* insert the names
+ ** of all columns in TABLE. The parser inserted a special expression
+ ** with the TK_ALL operator for each "*" that it found in the column list.
+ ** The following code just has to locate the TK_ALL expressions and expand
+ ** each one to the list of all columns in all tables.
+ **
+ ** The first loop just checks to see if there are any "*" operators
+ ** that need expanding.
+ */
+ for(k=0; k<pEList->nExpr; k++){
+ Expr *pE = pEList->a[k].pExpr;
+ if( pE->op==TK_ALL ) break;
+ if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
+ && pE->pLeft && pE->pLeft->op==TK_ID ) break;
+ }
+ rc = 0;
+ if( k<pEList->nExpr ){
+ /*
+ ** If we get here it means the result set contains one or more "*"
+ ** operators that need to be expanded. Loop through each expression
+ ** in the result set and expand them one by one.
+ */
+ struct ExprList_item *a = pEList->a;
+ ExprList *pNew = 0;
+ int flags = pParse->db->flags;
+ int longNames = (flags & SQLITE_FullColNames)!=0 &&
+ (flags & SQLITE_ShortColNames)==0;
+
+ for(k=0; k<pEList->nExpr; k++){
+ Expr *pE = a[k].pExpr;
+ if( pE->op!=TK_ALL &&
+ (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
+ /* This particular expression does not need to be expanded.
+ */
+ pNew = sqlite3ExprListAppend(pNew, a[k].pExpr, 0);
+ pNew->a[pNew->nExpr-1].zName = a[k].zName;
+ a[k].pExpr = 0;
+ a[k].zName = 0;
+ }else{
+ /* This expression is a "*" or a "TABLE.*" and needs to be
+ ** expanded. */
+ int tableSeen = 0; /* Set to 1 when TABLE matches */
+ char *zTName; /* text of name of TABLE */
+ if( pE->op==TK_DOT && pE->pLeft ){
+ zTName = sqlite3NameFromToken(&pE->pLeft->token);
+ }else{
+ zTName = 0;
+ }
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab = pFrom->pTab;
+ char *zTabName = pFrom->zAlias;
+ if( zTabName==0 || zTabName[0]==0 ){
+ zTabName = pTab->zName;
+ }
+ if( zTName && (zTabName==0 || zTabName[0]==0 ||
+ sqlite3StrICmp(zTName, zTabName)!=0) ){
+ continue;
+ }
+ tableSeen = 1;
+ for(j=0; j<pTab->nCol; j++){
+ Expr *pExpr, *pLeft, *pRight;
+ char *zName = pTab->aCol[j].zName;
+
+ if( i>0 ){
+ struct SrcList_item *pLeft = &pTabList->a[i-1];
+ if( (pLeft->jointype & JT_NATURAL)!=0 &&
+ columnIndex(pLeft->pTab, zName)>=0 ){
+ /* In a NATURAL join, omit the join columns from the
+ ** table on the right */
+ continue;
+ }
+ if( sqlite3IdListIndex(pLeft->pUsing, zName)>=0 ){
+ /* In a join with a USING clause, omit columns in the
+ ** using clause from the table on the right. */
+ continue;
+ }
+ }
+ pRight = sqlite3Expr(TK_ID, 0, 0, 0);
+ if( pRight==0 ) break;
+ setToken(&pRight->token, zName);
+ if( zTabName && (longNames || pTabList->nSrc>1) ){
+ pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
+ pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0);
+ if( pExpr==0 ) break;
+ setToken(&pLeft->token, zTabName);
+ setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName));
+ pExpr->span.dyn = 1;
+ pExpr->token.z = 0;
+ pExpr->token.n = 0;
+ pExpr->token.dyn = 0;
+ }else{
+ pExpr = pRight;
+ pExpr->span = pExpr->token;
+ }
+ if( longNames ){
+ pNew = sqlite3ExprListAppend(pNew, pExpr, &pExpr->span);
+ }else{
+ pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token);
+ }
+ }
+ }
+ if( !tableSeen ){
+ if( zTName ){
+ sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
+ }else{
+ sqlite3ErrorMsg(pParse, "no tables specified");
+ }
+ rc = 1;
+ }
+ sqliteFree(zTName);
+ }
+ }
+ sqlite3ExprListDelete(pEList);
+ p->pEList = pNew;
+ }
+ return rc;
+}
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+/*
+** This routine associates entries in an ORDER BY expression list with
+** columns in a result. For each ORDER BY expression, the opcode of
+** the top-level node is changed to TK_COLUMN and the iColumn value of
+** the top-level node is filled in with column number and the iTable
+** value of the top-level node is filled with iTable parameter.
+**
+** If there are prior SELECT clauses, they are processed first. A match
+** in an earlier SELECT takes precedence over a later SELECT.
+**
+** Any entry that does not match is flagged as an error. The number
+** of errors is returned.
+*/
+static int matchOrderbyToColumn(
+ Parse *pParse, /* A place to leave error messages */
+ Select *pSelect, /* Match to result columns of this SELECT */
+ ExprList *pOrderBy, /* The ORDER BY values to match against columns */
+ int iTable, /* Insert this value in iTable */
+ int mustComplete /* If TRUE all ORDER BYs must match */
+){
+ int nErr = 0;
+ int i, j;
+ ExprList *pEList;
+
+ if( pSelect==0 || pOrderBy==0 ) return 1;
+ if( mustComplete ){
+ for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; }
+ }
+ if( prepSelectStmt(pParse, pSelect) ){
+ return 1;
+ }
+ if( pSelect->pPrior ){
+ if( matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){
+ return 1;
+ }
+ }
+ pEList = pSelect->pEList;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ Expr *pE = pOrderBy->a[i].pExpr;
+ int iCol = -1;
+ if( pOrderBy->a[i].done ) continue;
+ if( sqlite3ExprIsInteger(pE, &iCol) ){
+ if( iCol<=0 || iCol>pEList->nExpr ){
+ sqlite3ErrorMsg(pParse,
+ "ORDER BY position %d should be between 1 and %d",
+ iCol, pEList->nExpr);
+ nErr++;
+ break;
+ }
+ if( !mustComplete ) continue;
+ iCol--;
+ }
+ for(j=0; iCol<0 && j<pEList->nExpr; j++){
+ if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
+ char *zName, *zLabel;
+ zName = pEList->a[j].zName;
+ zLabel = sqlite3NameFromToken(&pE->token);
+ assert( zLabel!=0 );
+ if( sqlite3StrICmp(zName, zLabel)==0 ){
+ iCol = j;
+ }
+ sqliteFree(zLabel);
+ }
+ if( iCol<0 && sqlite3ExprCompare(pE, pEList->a[j].pExpr) ){
+ iCol = j;
+ }
+ }
+ if( iCol>=0 ){
+ pE->op = TK_COLUMN;
+ pE->iColumn = iCol;
+ pE->iTable = iTable;
+ pE->iAgg = -1;
+ pOrderBy->a[i].done = 1;
+ }
+ if( iCol<0 && mustComplete ){
+ sqlite3ErrorMsg(pParse,
+ "ORDER BY term number %d does not match any result column", i+1);
+ nErr++;
+ break;
+ }
+ }
+ return nErr;
+}
+#endif /* #ifndef SQLITE_OMIT_COMPOUND_SELECT */
+
+/*
+** Get a VDBE for the given parser context. Create a new one if necessary.
+** If an error occurs, return NULL and leave a message in pParse.
+*/
+Vdbe *sqlite3GetVdbe(Parse *pParse){
+ Vdbe *v = pParse->pVdbe;
+ if( v==0 ){
+ v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
+ }
+ return v;
+}
+
+/*
+** Compute the iLimit and iOffset fields of the SELECT based on the
+** pLimit and pOffset expressions. nLimit and nOffset hold the expressions
+** that appear in the original SQL statement after the LIMIT and OFFSET
+** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
+** are the integer memory register numbers for counters used to compute
+** the limit and offset. If there is no limit and/or offset, then
+** iLimit and iOffset are negative.
+**
+** This routine changes the values if iLimit and iOffset only if
+** a limit or offset is defined by nLimit and nOffset. iLimit and
+** iOffset should have been preset to appropriate default values
+** (usually but not always -1) prior to calling this routine.
+** Only if nLimit>=0 or nOffset>0 do the limit registers get
+** redefined. The UNION ALL operator uses this property to force
+** the reuse of the same limit and offset registers across multiple
+** SELECT statements.
+*/
+static void computeLimitRegisters(Parse *pParse, Select *p){
+ /*
+ ** "LIMIT -1" always shows all rows. There is some
+ ** contraversy about what the correct behavior should be.
+ ** The current implementation interprets "LIMIT 0" to mean
+ ** no rows.
+ */
+ if( p->pLimit ){
+ int iMem = pParse->nMem++;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return;
+ sqlite3ExprCode(pParse, p->pLimit);
+ sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
+ VdbeComment((v, "# LIMIT counter"));
+ p->iLimit = iMem;
+ }
+ if( p->pOffset ){
+ int iMem = pParse->nMem++;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return;
+ sqlite3ExprCode(pParse, p->pOffset);
+ sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
+ VdbeComment((v, "# OFFSET counter"));
+ p->iOffset = iMem;
+ }
+}
+
+/*
+** Generate VDBE instructions that will open a transient table that
+** will be used for an index or to store keyed results for a compound
+** select. In other words, open a transient table that needs a
+** KeyInfo structure. The number of columns in the KeyInfo is determined
+** by the result set of the SELECT statement in the second argument.
+**
+** Specifically, this routine is called to open an index table for
+** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not
+** UNION ALL).
+**
+** The value returned is the address of the OP_OpenTemp instruction.
+*/
+static int openTempIndex(Parse *pParse, Select *p, int iTab){
+ KeyInfo *pKeyInfo;
+ int nColumn;
+ sqlite3 *db = pParse->db;
+ int i;
+ Vdbe *v = pParse->pVdbe;
+ int addr;
+
+ if( prepSelectStmt(pParse, p) ){
+ return 0;
+ }
+ nColumn = p->pEList->nExpr;
+ pKeyInfo = sqliteMalloc( sizeof(*pKeyInfo)+nColumn*sizeof(CollSeq*) );
+ if( pKeyInfo==0 ) return 0;
+ pKeyInfo->enc = db->enc;
+ pKeyInfo->nField = nColumn;
+ for(i=0; i<nColumn; i++){
+ pKeyInfo->aColl[i] = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr);
+ if( !pKeyInfo->aColl[i] ){
+ pKeyInfo->aColl[i] = db->pDfltColl;
+ }
+ }
+ addr = sqlite3VdbeOp3(v, OP_OpenTemp, 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.
+*/
+static int multiSelectOpenTempAddr(Select *p, int addr){
+ IdList *pList = *p->ppOpenTemp = sqlite3IdListAppend(*p->ppOpenTemp, 0);
+ if( pList==0 ){
+ return SQLITE_NOMEM;
+ }
+ pList->a[pList->nId-1].idx = addr;
+ return SQLITE_OK;
+}
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+/*
+** Return the appropriate collating sequence for the iCol-th column of
+** the result set for the compound-select statement "p". Return NULL if
+** the column has no default collating sequence.
+**
+** The collating sequence for the compound select is taken from the
+** left-most term of the select that has a collating sequence.
+*/
+static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
+ CollSeq *pRet;
+ if( p->pPrior ){
+ pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
+ }else{
+ pRet = 0;
+ }
+ if( pRet==0 ){
+ pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
+ }
+ return pRet;
+}
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+/*
+** This routine is called to process a query that is really the union
+** or intersection of two or more separate queries.
+**
+** "p" points to the right-most of the two queries. the query on the
+** left is p->pPrior. The left query could also be a compound query
+** in which case this routine will be called recursively.
+**
+** The results of the total query are to be written into a destination
+** of type eDest with parameter iParm.
+**
+** Example 1: Consider a three-way compound SQL statement.
+**
+** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
+**
+** This statement is parsed up as follows:
+**
+** SELECT c FROM t3
+** |
+** `-----> SELECT b FROM t2
+** |
+** `------> SELECT a FROM t1
+**
+** The arrows in the diagram above represent the Select.pPrior pointer.
+** So if this routine is called with p equal to the t3 query, then
+** pPrior will be the t2 query. p->op will be TK_UNION in this case.
+**
+** Notice that because of the way SQLite parses compound SELECTs, the
+** individual selects always group from left to right.
+*/
+static int multiSelect(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The right-most of SELECTs to be coded */
+ int eDest, /* \___ Store query results as specified */
+ int iParm, /* / by these two parameters. */
+ char *aff /* If eDest is SRT_Union, the affinity string */
+){
+ 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 */
+ int aAddr[5]; /* Addresses of SetNumColumns operators */
+ int nAddr = 0; /* Number used */
+ int nCol; /* Number of columns in the result set */
+
+ /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
+ ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
+ */
+ if( p==0 || p->pPrior==0 ){
+ rc = 1;
+ goto multi_select_end;
+ }
+ pPrior = p->pPrior;
+ if( pPrior->pOrderBy ){
+ sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
+ selectOpName(p->op));
+ rc = 1;
+ goto multi_select_end;
+ }
+ if( pPrior->pLimit ){
+ sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
+ selectOpName(p->op));
+ rc = 1;
+ goto multi_select_end;
+ }
+
+ /* Make sure we have a valid query engine. If not, create a new one.
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ){
+ rc = 1;
+ goto multi_select_end;
+ }
+
+ /* 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
+ ** pointer to pPrior, the next statement to our left.
+ */
+ if( p->ppOpenTemp==0 ){
+ p->ppOpenTemp = &pOpenTemp;
+ }
+ pPrior->ppOpenTemp = p->ppOpenTemp;
+
+ /* Create the destination temporary table if necessary
+ */
+ if( eDest==SRT_TempTable ){
+ assert( p->pEList );
+ sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
+ assert( nAddr==0 );
+ aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 0);
+ eDest = SRT_Table;
+ }
+
+ /* Generate code for the left and right SELECT statements.
+ */
+ switch( p->op ){
+ case TK_ALL: {
+ if( p->pOrderBy==0 ){
+ assert( !pPrior->pLimit );
+ pPrior->pLimit = p->pLimit;
+ pPrior->pOffset = p->pOffset;
+ rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff);
+ if( rc ){
+ goto multi_select_end;
+ }
+ p->pPrior = 0;
+ p->iLimit = pPrior->iLimit;
+ p->iOffset = pPrior->iOffset;
+ p->pLimit = 0;
+ p->pOffset = 0;
+ rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
+ p->pPrior = pPrior;
+ if( rc ){
+ goto multi_select_end;
+ }
+ break;
+ }
+ /* For UNION ALL ... ORDER BY fall through to the next case */
+ }
+ case TK_EXCEPT:
+ case TK_UNION: {
+ int unionTab; /* Cursor number of the temporary table holding result */
+ int op = 0; /* One of the SRT_ operations to apply to self */
+ int priorOp; /* The SRT_ operation to apply to prior selects */
+ Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
+ ExprList *pOrderBy; /* The ORDER BY clause for the right SELECT */
+ int addr;
+
+ priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
+ if( eDest==priorOp && p->pOrderBy==0 && !p->pLimit && !p->pOffset ){
+ /* We can reuse a temporary table generated by a SELECT to our
+ ** right.
+ */
+ unionTab = iParm;
+ }else{
+ /* We will need to create our own temporary table to hold the
+ ** intermediate results.
+ */
+ unionTab = pParse->nTab++;
+ if( p->pOrderBy
+ && matchOrderbyToColumn(pParse, p, p->pOrderBy, unionTab, 1) ){
+ rc = 1;
+ goto multi_select_end;
+ }
+ addr = sqlite3VdbeAddOp(v, OP_OpenTemp, unionTab, 0);
+ if( p->op!=TK_ALL ){
+ rc = multiSelectOpenTempAddr(p, addr);
+ if( rc!=SQLITE_OK ){
+ goto multi_select_end;
+ }
+ }
+ assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
+ aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, unionTab, 0);
+ assert( p->pEList );
+ }
+
+ /* Code the SELECT statements to our left
+ */
+ assert( !pPrior->pOrderBy );
+ rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff);
+ if( rc ){
+ goto multi_select_end;
+ }
+
+ /* Code the current SELECT statement
+ */
+ switch( p->op ){
+ case TK_EXCEPT: op = SRT_Except; break;
+ case TK_UNION: op = SRT_Union; break;
+ case TK_ALL: op = SRT_Table; break;
+ }
+ p->pPrior = 0;
+ pOrderBy = p->pOrderBy;
+ p->pOrderBy = 0;
+ pLimit = p->pLimit;
+ p->pLimit = 0;
+ pOffset = p->pOffset;
+ p->pOffset = 0;
+ rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff);
+ p->pPrior = pPrior;
+ p->pOrderBy = pOrderBy;
+ sqlite3ExprDelete(p->pLimit);
+ p->pLimit = pLimit;
+ p->pOffset = pOffset;
+ p->iLimit = -1;
+ p->iOffset = -1;
+ if( rc ){
+ goto multi_select_end;
+ }
+
+
+ /* Convert the data in the temporary table into whatever form
+ ** it is that we currently need.
+ */
+ if( eDest!=priorOp || unionTab!=iParm ){
+ int iCont, iBreak, iStart;
+ assert( p->pEList );
+ if( eDest==SRT_Callback ){
+ generateColumnNames(pParse, 0, p->pEList);
+ }
+ iBreak = sqlite3VdbeMakeLabel(v);
+ iCont = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
+ computeLimitRegisters(pParse, p);
+ iStart = sqlite3VdbeCurrentAddr(v);
+ rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
+ p->pOrderBy, -1, eDest, iParm,
+ iCont, iBreak, 0);
+ if( rc ){
+ rc = 1;
+ goto multi_select_end;
+ }
+ sqlite3VdbeResolveLabel(v, iCont);
+ sqlite3VdbeAddOp(v, OP_Next, unionTab, iStart);
+ sqlite3VdbeResolveLabel(v, iBreak);
+ sqlite3VdbeAddOp(v, OP_Close, unionTab, 0);
+ }
+ break;
+ }
+ case TK_INTERSECT: {
+ int tab1, tab2;
+ int iCont, iBreak, iStart;
+ Expr *pLimit, *pOffset;
+ int addr;
+
+ /* INTERSECT is different from the others since it requires
+ ** two temporary tables. Hence it has its own case. Begin
+ ** by allocating the tables we will need.
+ */
+ tab1 = pParse->nTab++;
+ tab2 = pParse->nTab++;
+ if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
+ rc = 1;
+ goto multi_select_end;
+ }
+
+ addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab1, 0);
+ rc = multiSelectOpenTempAddr(p, addr);
+ if( rc!=SQLITE_OK ){
+ goto multi_select_end;
+ }
+ assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
+ aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab1, 0);
+ assert( p->pEList );
+
+ /* Code the SELECTs to our left into temporary table "tab1".
+ */
+ rc = sqlite3Select(pParse, pPrior, SRT_Union, tab1, 0, 0, 0, aff);
+ if( rc ){
+ goto multi_select_end;
+ }
+
+ /* Code the current SELECT into temporary table "tab2"
+ */
+ addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab2, 0);
+ rc = multiSelectOpenTempAddr(p, addr);
+ if( rc!=SQLITE_OK ){
+ goto multi_select_end;
+ }
+ assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
+ aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab2, 0);
+ p->pPrior = 0;
+ pLimit = p->pLimit;
+ p->pLimit = 0;
+ pOffset = p->pOffset;
+ p->pOffset = 0;
+ rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff);
+ p->pPrior = pPrior;
+ sqlite3ExprDelete(p->pLimit);
+ p->pLimit = pLimit;
+ p->pOffset = pOffset;
+ if( rc ){
+ goto multi_select_end;
+ }
+
+ /* Generate code to take the intersection of the two temporary
+ ** tables.
+ */
+ assert( p->pEList );
+ if( eDest==SRT_Callback ){
+ generateColumnNames(pParse, 0, p->pEList);
+ }
+ iBreak = sqlite3VdbeMakeLabel(v);
+ iCont = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
+ computeLimitRegisters(pParse, p);
+ iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0);
+ sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
+ rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
+ p->pOrderBy, -1, eDest, iParm,
+ iCont, iBreak, 0);
+ if( rc ){
+ rc = 1;
+ goto multi_select_end;
+ }
+ sqlite3VdbeResolveLabel(v, iCont);
+ sqlite3VdbeAddOp(v, OP_Next, tab1, iStart);
+ sqlite3VdbeResolveLabel(v, iBreak);
+ sqlite3VdbeAddOp(v, OP_Close, tab2, 0);
+ sqlite3VdbeAddOp(v, OP_Close, tab1, 0);
+ break;
+ }
+ }
+
+ /* Make sure all SELECTs in the statement have the same number of elements
+ ** in their result sets.
+ */
+ assert( p->pEList && pPrior->pEList );
+ if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
+ sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
+ " do not have the same number of result columns", selectOpName(p->op));
+ rc = 1;
+ goto multi_select_end;
+ }
+
+ /* Set the number of columns in temporary tables
+ */
+ nCol = p->pEList->nExpr;
+ while( nAddr>0 ){
+ nAddr--;
+ sqlite3VdbeChangeP2(v, aAddr[nAddr], nCol);
+ }
+
+ /* Compute collating sequences used by either the ORDER BY clause or
+ ** by any temporary tables needed to implement the compound select.
+ ** Attach the KeyInfo structure to all temporary tables. Invoke the
+ ** ORDER BY processing if there is an ORDER BY clause.
+ **
+ ** This section is run by the right-most SELECT statement only.
+ ** SELECT statements to the left always skip this part. The right-most
+ ** 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) ){
+ int i; /* Loop counter */
+ KeyInfo *pKeyInfo; /* Collating sequence for the result set */
+
+ assert( p->ppOpenTemp == &pOpenTemp );
+ pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*sizeof(CollSeq*));
+ if( !pKeyInfo ){
+ rc = SQLITE_NOMEM;
+ goto multi_select_end;
+ }
+
+ pKeyInfo->enc = pParse->db->enc;
+ pKeyInfo->nField = nCol;
+
+ for(i=0; i<nCol; i++){
+ pKeyInfo->aColl[i] = multiSelectCollSeq(pParse, p, i);
+ if( !pKeyInfo->aColl[i] ){
+ pKeyInfo->aColl[i] = pParse->db->pDfltColl;
+ }
+ }
+
+ for(i=0; pOpenTemp && i<pOpenTemp->nId; i++){
+ int p3type = (i==0?P3_KEYINFO_HANDOFF:P3_KEYINFO);
+ int addr = pOpenTemp->a[i].idx;
+ sqlite3VdbeChangeP3(v, addr, (char *)pKeyInfo, p3type);
+ }
+
+ if( p->pOrderBy ){
+ struct ExprList_item *pOrderByTerm = p->pOrderBy->a;
+ for(i=0; i<p->pOrderBy->nExpr; i++, pOrderByTerm++){
+ Expr *pExpr = pOrderByTerm->pExpr;
+ char *zName = pOrderByTerm->zName;
+ assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );
+ /* assert( !pExpr->pColl ); */
+ if( zName ){
+ pExpr->pColl = sqlite3LocateCollSeq(pParse, zName, -1);
+ }else{
+ pExpr->pColl = pKeyInfo->aColl[pExpr->iColumn];
+ }
+ }
+ generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm);
+ }
+
+ if( !pOpenTemp ){
+ /* This happens for UNION ALL ... ORDER BY */
+ sqliteFree(pKeyInfo);
+ }
+ }
+
+multi_select_end:
+ if( pOpenTemp ){
+ sqlite3IdListDelete(pOpenTemp);
+ }
+ p->ppOpenTemp = 0;
+ return rc;
+}
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
+
+#ifndef SQLITE_OMIT_VIEW
+/*
+** Scan through the expression pExpr. Replace every reference to
+** a column in table number iTable with a copy of the iColumn-th
+** entry in pEList. (But leave references to the ROWID column
+** unchanged.)
+**
+** This routine is part of the flattening procedure. A subquery
+** whose result set is defined by pEList appears as entry in the
+** FROM clause of a SELECT such that the VDBE cursor assigned to that
+** FORM clause entry is iTable. This routine make the necessary
+** changes to pExpr so that it refers directly to the source table
+** of the subquery rather the result set of the subquery.
+*/
+static void substExprList(ExprList*,int,ExprList*); /* Forward Decl */
+static void substSelect(Select *, int, ExprList *); /* Forward Decl */
+static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){
+ if( pExpr==0 ) return;
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
+ if( pExpr->iColumn<0 ){
+ pExpr->op = TK_NULL;
+ }else{
+ Expr *pNew;
+ assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
+ assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 );
+ pNew = pEList->a[pExpr->iColumn].pExpr;
+ assert( pNew!=0 );
+ pExpr->op = pNew->op;
+ assert( pExpr->pLeft==0 );
+ pExpr->pLeft = sqlite3ExprDup(pNew->pLeft);
+ assert( pExpr->pRight==0 );
+ pExpr->pRight = sqlite3ExprDup(pNew->pRight);
+ assert( pExpr->pList==0 );
+ pExpr->pList = sqlite3ExprListDup(pNew->pList);
+ pExpr->iTable = pNew->iTable;
+ pExpr->iColumn = pNew->iColumn;
+ pExpr->iAgg = pNew->iAgg;
+ sqlite3TokenCopy(&pExpr->token, &pNew->token);
+ sqlite3TokenCopy(&pExpr->span, &pNew->span);
+ pExpr->pSelect = sqlite3SelectDup(pNew->pSelect);
+ pExpr->flags = pNew->flags;
+ }
+ }else{
+ substExpr(pExpr->pLeft, iTable, pEList);
+ substExpr(pExpr->pRight, iTable, pEList);
+ substSelect(pExpr->pSelect, iTable, pEList);
+ substExprList(pExpr->pList, iTable, pEList);
+ }
+}
+static void substExprList(ExprList *pList, int iTable, ExprList *pEList){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nExpr; i++){
+ substExpr(pList->a[i].pExpr, iTable, pEList);
+ }
+}
+static void substSelect(Select *p, int iTable, ExprList *pEList){
+ if( !p ) return;
+ substExprList(p->pEList, iTable, pEList);
+ substExprList(p->pGroupBy, iTable, pEList);
+ substExprList(p->pOrderBy, iTable, pEList);
+ substExpr(p->pHaving, iTable, pEList);
+ substExpr(p->pWhere, iTable, pEList);
+}
+#endif /* !defined(SQLITE_OMIT_VIEW) */
+
+#ifndef SQLITE_OMIT_VIEW
+/*
+** This routine attempts to flatten subqueries in order to speed
+** execution. It returns 1 if it makes changes and 0 if no flattening
+** occurs.
+**
+** To understand the concept of flattening, consider the following
+** query:
+**
+** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
+**
+** The default way of implementing this query is to execute the
+** subquery first and store the results in a temporary table, then
+** run the outer query on that temporary table. This requires two
+** passes over the data. Furthermore, because the temporary table
+** has no indices, the WHERE clause on the outer query cannot be
+** optimized.
+**
+** This routine attempts to rewrite queries such as the above into
+** a single flat select, like this:
+**
+** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
+**
+** The code generated for this simpification gives the same result
+** but only has to scan the data once. And because indices might
+** exist on the table t1, a complete scan of the data might be
+** avoided.
+**
+** Flattening is only attempted if all of the following are true:
+**
+** (1) The subquery and the outer query do not both use aggregates.
+**
+** (2) The subquery is not an aggregate or the outer query is not a join.
+**
+** (3) The subquery is not the right operand of a left outer join, or
+** the subquery is not itself a join. (Ticket #306)
+**
+** (4) The subquery is not DISTINCT or the outer query is not a join.
+**
+** (5) The subquery is not DISTINCT or the outer query does not use
+** aggregates.
+**
+** (6) The subquery does not use aggregates or the outer query is not
+** DISTINCT.
+**
+** (7) The subquery has a FROM clause.
+**
+** (8) The subquery does not use LIMIT or the outer query is not a join.
+**
+** (9) The subquery does not use LIMIT or the outer query does not use
+** aggregates.
+**
+** (10) The subquery does not use aggregates or the outer query does not
+** use LIMIT.
+**
+** (11) The subquery and the outer query do not both have ORDER BY clauses.
+**
+** (12) The subquery is not the right term of a LEFT OUTER JOIN or the
+** subquery has no WHERE clause. (added by ticket #350)
+**
+** In this routine, the "p" parameter is a pointer to the outer query.
+** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
+** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
+**
+** If flattening is not attempted, this routine is a no-op and returns 0.
+** If flattening is attempted this routine returns 1.
+**
+** All of the expression analysis must occur on both the outer query and
+** the subquery before this routine runs.
+*/
+static int flattenSubquery(
+ Parse *pParse, /* The parsing context */
+ Select *p, /* The parent or outer SELECT statement */
+ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
+ int isAgg, /* True if outer SELECT uses aggregate functions */
+ int subqueryIsAgg /* True if the subquery uses aggregate functions */
+){
+ Select *pSub; /* The inner query or "subquery" */
+ SrcList *pSrc; /* The FROM clause of the outer query */
+ SrcList *pSubSrc; /* The FROM clause of the subquery */
+ ExprList *pList; /* The result set of the outer query */
+ int iParent; /* VDBE cursor number of the pSub result set temp table */
+ int i; /* Loop counter */
+ Expr *pWhere; /* The WHERE clause */
+ struct SrcList_item *pSubitem; /* The subquery */
+
+ /* Check to see if flattening is permitted. Return 0 if not.
+ */
+ if( p==0 ) return 0;
+ pSrc = p->pSrc;
+ assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
+ pSubitem = &pSrc->a[iFrom];
+ pSub = pSubitem->pSelect;
+ assert( pSub!=0 );
+ if( isAgg && subqueryIsAgg ) return 0;
+ if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
+ pSubSrc = pSub->pSrc;
+ assert( pSubSrc );
+ if( (pSub->pLimit && p->pLimit) || pSub->pOffset ||
+ (pSub->pLimit && isAgg) ) return 0;
+ if( pSubSrc->nSrc==0 ) return 0;
+ if( pSub->isDistinct && (pSrc->nSrc>1 || isAgg) ){
+ return 0;
+ }
+ if( p->isDistinct && subqueryIsAgg ) return 0;
+ if( p->pOrderBy && pSub->pOrderBy ) return 0;
+
+ /* Restriction 3: If the subquery is a join, make sure the subquery is
+ ** not used as the right operand of an outer join. Examples of why this
+ ** is not allowed:
+ **
+ ** t1 LEFT OUTER JOIN (t2 JOIN t3)
+ **
+ ** If we flatten the above, we would get
+ **
+ ** (t1 LEFT OUTER JOIN t2) JOIN t3
+ **
+ ** which is not at all the same thing.
+ */
+ if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){
+ return 0;
+ }
+
+ /* Restriction 12: If the subquery is the right operand of a left outer
+ ** join, make sure the subquery has no WHERE clause.
+ ** An examples of why this is not allowed:
+ **
+ ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
+ **
+ ** If we flatten the above, we would get
+ **
+ ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
+ **
+ ** But the t2.x>0 test will always fail on a NULL row of t2, which
+ ** effectively converts the OUTER JOIN into an INNER JOIN.
+ */
+ if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0
+ && pSub->pWhere!=0 ){
+ return 0;
+ }
+
+ /* If we reach this point, it means flattening is permitted for the
+ ** iFrom-th entry of the FROM clause in the outer query.
+ */
+
+ /* Move all of the FROM elements of the subquery into the
+ ** the FROM clause of the outer query. Before doing this, remember
+ ** the cursor number for the original outer query FROM element in
+ ** iParent. The iParent cursor will never be used. Subsequent code
+ ** will scan expressions looking for iParent references and replace
+ ** those references with expressions that resolve to the subquery FROM
+ ** elements we are now copying in.
+ */
+ iParent = pSubitem->iCursor;
+ {
+ int nSubSrc = pSubSrc->nSrc;
+ int jointype = pSubitem->jointype;
+
+ sqlite3DeleteTable(0, pSubitem->pTab);
+ sqliteFree(pSubitem->zDatabase);
+ sqliteFree(pSubitem->zName);
+ sqliteFree(pSubitem->zAlias);
+ if( nSubSrc>1 ){
+ int extra = nSubSrc - 1;
+ for(i=1; i<nSubSrc; i++){
+ pSrc = sqlite3SrcListAppend(pSrc, 0, 0);
+ }
+ p->pSrc = pSrc;
+ for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
+ pSrc->a[i] = pSrc->a[i-extra];
+ }
+ }
+ for(i=0; i<nSubSrc; i++){
+ pSrc->a[i+iFrom] = pSubSrc->a[i];
+ memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
+ }
+ pSrc->a[iFrom+nSubSrc-1].jointype = jointype;
+ }
+
+ /* Now begin substituting subquery result set expressions for
+ ** references to the iParent in the outer query.
+ **
+ ** Example:
+ **
+ ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
+ ** \ \_____________ subquery __________/ /
+ ** \_____________________ outer query ______________________________/
+ **
+ ** We look at every expression in the outer query and every place we see
+ ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
+ */
+ substExprList(p->pEList, iParent, pSub->pEList);
+ pList = p->pEList;
+ for(i=0; i<pList->nExpr; i++){
+ Expr *pExpr;
+ if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
+ pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
+ }
+ }
+ if( isAgg ){
+ substExprList(p->pGroupBy, iParent, pSub->pEList);
+ substExpr(p->pHaving, iParent, pSub->pEList);
+ }
+ if( pSub->pOrderBy ){
+ assert( p->pOrderBy==0 );
+ p->pOrderBy = pSub->pOrderBy;
+ pSub->pOrderBy = 0;
+ }else if( p->pOrderBy ){
+ substExprList(p->pOrderBy, iParent, pSub->pEList);
+ }
+ if( pSub->pWhere ){
+ pWhere = sqlite3ExprDup(pSub->pWhere);
+ }else{
+ pWhere = 0;
+ }
+ if( subqueryIsAgg ){
+ assert( p->pHaving==0 );
+ p->pHaving = p->pWhere;
+ p->pWhere = pWhere;
+ substExpr(p->pHaving, iParent, pSub->pEList);
+ p->pHaving = sqlite3ExprAnd(p->pHaving, sqlite3ExprDup(pSub->pHaving));
+ assert( p->pGroupBy==0 );
+ p->pGroupBy = sqlite3ExprListDup(pSub->pGroupBy);
+ }else{
+ substExpr(p->pWhere, iParent, pSub->pEList);
+ p->pWhere = sqlite3ExprAnd(p->pWhere, pWhere);
+ }
+
+ /* The flattened query is distinct if either the inner or the
+ ** outer query is distinct.
+ */
+ p->isDistinct = p->isDistinct || pSub->isDistinct;
+
+ /*
+ ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
+ */
+ if( pSub->pLimit ){
+ p->pLimit = pSub->pLimit;
+ pSub->pLimit = 0;
+ }
+
+ /* Finially, delete what is left of the subquery and return
+ ** success.
+ */
+ sqlite3SelectDelete(pSub);
+ return 1;
+}
+#endif /* SQLITE_OMIT_VIEW */
+
+/*
+** Analyze the SELECT statement passed in as an argument to see if it
+** is a simple min() or max() query. If it is and this query can be
+** satisfied using a single seek to the beginning or end of an index,
+** then generate the code for this SELECT and return 1. If this is not a
+** simple min() or max() query, then return 0;
+**
+** A simply min() or max() query looks like this:
+**
+** SELECT min(a) FROM table;
+** SELECT max(a) FROM table;
+**
+** The query may have only a single table in its FROM argument. There
+** can be no GROUP BY or HAVING or WHERE clauses. The result set must
+** be the min() or max() of a single column of the table. The column
+** in the min() or max() function must be indexed.
+**
+** The parameters to this routine are the same as for sqlite3Select().
+** See the header comment on that routine for additional information.
+*/
+static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
+ Expr *pExpr;
+ int iCol;
+ Table *pTab;
+ Index *pIdx;
+ int base;
+ Vdbe *v;
+ int seekOp;
+ int cont;
+ ExprList *pEList, *pList, eList;
+ struct ExprList_item eListItem;
+ SrcList *pSrc;
+
+ /* Check to see if this query is a simple min() or max() query. Return
+ ** zero if it is not.
+ */
+ if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
+ pSrc = p->pSrc;
+ if( pSrc->nSrc!=1 ) return 0;
+ pEList = p->pEList;
+ if( pEList->nExpr!=1 ) return 0;
+ pExpr = pEList->a[0].pExpr;
+ if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
+ pList = pExpr->pList;
+ if( pList==0 || pList->nExpr!=1 ) return 0;
+ if( pExpr->token.n!=3 ) return 0;
+ if( sqlite3StrNICmp(pExpr->token.z,"min",3)==0 ){
+ seekOp = OP_Rewind;
+ }else if( sqlite3StrNICmp(pExpr->token.z,"max",3)==0 ){
+ seekOp = OP_Last;
+ }else{
+ return 0;
+ }
+ pExpr = pList->a[0].pExpr;
+ if( pExpr->op!=TK_COLUMN ) return 0;
+ iCol = pExpr->iColumn;
+ pTab = pSrc->a[0].pTab;
+
+ /* If we get to here, it means the query is of the correct form.
+ ** Check to make sure we have an index and make pIdx point to the
+ ** appropriate index. If the min() or max() is on an INTEGER PRIMARY
+ ** key column, no index is necessary so set pIdx to NULL. If no
+ ** usable index is found, return 0.
+ */
+ if( iCol<0 ){
+ pIdx = 0;
+ }else{
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ assert( pIdx->nColumn>=1 );
+ if( pIdx->aiColumn[0]==iCol && pIdx->keyInfo.aColl[0]==pColl ) break;
+ }
+ if( pIdx==0 ) return 0;
+ }
+
+ /* Identify column types if we will be using the callback. This
+ ** step is skipped if the output is going to a table or a memory cell.
+ ** The column names have already been generated in the calling function.
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) return 0;
+
+ /* 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_SetNumColumns, iParm, 1);
+ }
+
+ /* Generating code to find the min or the max. Basically all we have
+ ** to do is find the first or the last entry in the chosen index. If
+ ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
+ ** or last entry in the main table.
+ */
+ sqlite3CodeVerifySchema(pParse, pTab->iDb);
+ base = pSrc->a[0].iCursor;
+ computeLimitRegisters(pParse, p);
+ if( pSrc->a[0].pSelect==0 ){
+ sqlite3OpenTableForReading(v, base, pTab);
+ }
+ cont = sqlite3VdbeMakeLabel(v);
+ if( pIdx==0 ){
+ sqlite3VdbeAddOp(v, seekOp, base, 0);
+ }else{
+ /* Even though the cursor used to open the index here is closed
+ ** as soon as a single value has been read from it, allocate it
+ ** using (pParse->nTab++) to prevent the cursor id from being
+ ** reused. This is important for statements of the form
+ ** "INSERT INTO x SELECT max() FROM x".
+ */
+ int iIdx;
+ iIdx = pParse->nTab++;
+ sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
+ (char*)&pIdx->keyInfo, P3_KEYINFO);
+ if( seekOp==OP_Rewind ){
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
+ seekOp = OP_MoveGt;
+ }
+ sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
+ sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0);
+ sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
+ sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
+ }
+ eList.nExpr = 1;
+ memset(&eListItem, 0, sizeof(eListItem));
+ eList.a = &eListItem;
+ eList.a[0].pExpr = pExpr;
+ selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont, 0);
+ sqlite3VdbeResolveLabel(v, cont);
+ sqlite3VdbeAddOp(v, OP_Close, base, 0);
+
+ return 1;
+}
+
+/*
+** Analyze and ORDER BY or GROUP BY clause in a SELECT statement. Return
+** the number of errors seen.
+**
+** An ORDER BY or GROUP BY is a list of expressions. If any expression
+** is an integer constant, then that expression is replaced by the
+** corresponding entry in the result set.
+*/
+static int processOrderGroupBy(
+ NameContext *pNC, /* Name context of the SELECT statement. */
+ ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */
+ const char *zType /* Either "ORDER" or "GROUP", as appropriate */
+){
+ int i;
+ ExprList *pEList = pNC->pEList; /* The result set of the SELECT */
+ Parse *pParse = pNC->pParse; /* The result set of the SELECT */
+ assert( pEList );
+
+ if( pOrderBy==0 ) return 0;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ int iCol;
+ Expr *pE = pOrderBy->a[i].pExpr;
+ if( sqlite3ExprIsInteger(pE, &iCol) ){
+ if( iCol>0 && iCol<=pEList->nExpr ){
+ sqlite3ExprDelete(pE);
+ pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
+ }else{
+ sqlite3ErrorMsg(pParse,
+ "%s BY column number %d out of range - should be "
+ "between 1 and %d", zType, iCol, pEList->nExpr);
+ return 1;
+ }
+ }
+ if( sqlite3ExprResolveNames(pNC, pE) ){
+ return 1;
+ }
+ if( sqlite3ExprIsConstant(pE) ){
+ sqlite3ErrorMsg(pParse,
+ "%s BY terms must not be non-integer constants", zType);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** This routine resolves any names used in the result set of the
+** supplied SELECT statement. If the SELECT statement being resolved
+** is a sub-select, then pOuterNC is a pointer to the NameContext
+** of the parent SELECT.
+*/
+int sqlite3SelectResolve(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The SELECT statement being coded. */
+ NameContext *pOuterNC /* The outer name context. May be NULL. */
+){
+ ExprList *pEList; /* Result set. */
+ int i; /* For-loop variable used in multiple places */
+ NameContext sNC; /* Local name-context */
+
+ /* If this routine has run before, return immediately. */
+ if( p->isResolved ){
+ assert( !pOuterNC );
+ return SQLITE_OK;
+ }
+ p->isResolved = 1;
+
+ /* If there have already been errors, do nothing. */
+ if( pParse->nErr>0 ){
+ return SQLITE_ERROR;
+ }
+
+ /* Prepare the select statement. This call will allocate all cursors
+ ** required to handle the tables and subqueries in the FROM clause.
+ */
+ if( prepSelectStmt(pParse, p) ){
+ return SQLITE_ERROR;
+ }
+
+ /* Resolve the expressions in the LIMIT and OFFSET clauses. These
+ ** are not allowed to refer to any names, so pass an empty NameContext.
+ */
+ sNC.pParse = pParse;
+ sNC.hasAgg = 0;
+ sNC.nErr = 0;
+ sNC.nRef = 0;
+ sNC.pEList = 0;
+ sNC.allowAgg = 0;
+ sNC.pSrcList = 0;
+ sNC.pNext = 0;
+ if( sqlite3ExprResolveNames(&sNC, p->pLimit) ||
+ sqlite3ExprResolveNames(&sNC, p->pOffset) ){
+ return SQLITE_ERROR;
+ }
+
+ /* Set up the local name-context to pass to ExprResolveNames() to
+ ** resolve the expression-list.
+ */
+ sNC.allowAgg = 1;
+ sNC.pSrcList = p->pSrc;
+ sNC.pNext = pOuterNC;
+
+ /* NameContext.nDepth stores the depth of recursion for this query. For
+ ** an outer query (e.g. SELECT * FROM sqlite_master) this is 1. For
+ ** a subquery it is 2. For a subquery of a subquery, 3. And so on.
+ ** Parse.nMaxDepth is the maximum depth for any subquery resolved so
+ ** far. This is used to determine the number of aggregate contexts
+ ** required at runtime.
+ */
+ sNC.nDepth = (pOuterNC?pOuterNC->nDepth+1:1);
+ if( sNC.nDepth>pParse->nMaxDepth ){
+ pParse->nMaxDepth = sNC.nDepth;
+ }
+
+ /* Resolve names in the result set. */
+ pEList = p->pEList;
+ if( !pEList ) return SQLITE_ERROR;
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *pX = pEList->a[i].pExpr;
+ if( sqlite3ExprResolveNames(&sNC, pX) ){
+ return SQLITE_ERROR;
+ }
+ }
+
+ /* If there are no aggregate functions in the result-set, and no GROUP BY
+ ** expression, do not allow aggregates in any of the other expressions.
+ */
+ assert( !p->isAgg );
+ if( p->pGroupBy || sNC.hasAgg ){
+ p->isAgg = 1;
+ }else{
+ sNC.allowAgg = 0;
+ }
+
+ /* If a HAVING clause is present, then there must be a GROUP BY clause.
+ */
+ if( p->pHaving && !p->pGroupBy ){
+ sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
+ return SQLITE_ERROR;
+ }
+
+ /* Add the expression list to the name-context before parsing the
+ ** other expressions in the SELECT statement. This is so that
+ ** expressions in the WHERE clause (etc.) can refer to expressions by
+ ** aliases in the result set.
+ **
+ ** Minor point: If this is the case, then the expression will be
+ ** re-evaluated for each reference to it.
+ */
+ sNC.pEList = p->pEList;
+ if( sqlite3ExprResolveNames(&sNC, p->pWhere) ||
+ sqlite3ExprResolveNames(&sNC, p->pHaving) ||
+ processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") ||
+ processOrderGroupBy(&sNC, p->pGroupBy, "GROUP")
+ ){
+ return SQLITE_ERROR;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** An instance of the following struct is used by sqlite3Select()
+** to save aggregate related information from the Parse object
+** at the start of each call and to restore it at the end. See
+** saveAggregateInfo() and restoreAggregateInfo().
+*/
+struct AggregateInfo {
+ int nAgg;
+ AggExpr *aAgg;
+};
+typedef struct AggregateInfo AggregateInfo;
+
+/*
+** Copy aggregate related information from the Parse structure
+** into the AggregateInfo structure. Zero the aggregate related
+** values in the Parse struct.
+*/
+static void saveAggregateInfo(Parse *pParse, AggregateInfo *pInfo){
+ pInfo->aAgg = pParse->aAgg;
+ pInfo->nAgg = pParse->nAgg;
+ pParse->aAgg = 0;
+ pParse->nAgg = 0;
+}
+
+/*
+** Copy aggregate related information from the AggregateInfo struct
+** back into the Parse structure. The aggregate related information
+** currently stored in the Parse structure is deleted.
+*/
+static void restoreAggregateInfo(Parse *pParse, AggregateInfo *pInfo){
+ sqliteFree(pParse->aAgg);
+ pParse->aAgg = pInfo->aAgg;
+ pParse->nAgg = pInfo->nAgg;
+}
+
+/*
+** Generate code for the given SELECT statement.
+**
+** The results are distributed in various ways depending on the
+** value of eDest and iParm.
+**
+** eDest Value Result
+** ------------ -------------------------------------------
+** SRT_Callback Invoke the callback for each row of the result.
+**
+** SRT_Mem Store first result in memory cell iParm
+**
+** SRT_Set Store results as keys of table iParm.
+**
+** SRT_Union Store results as a key in a temporary table iParm
+**
+** SRT_Except Remove results from the temporary table iParm.
+**
+** SRT_Table Store results in temporary table iParm
+**
+** The table above is incomplete. Additional eDist value have be added
+** since this comment was written. See the selectInnerLoop() function for
+** a complete listing of the allowed values of eDest and their meanings.
+**
+** This routine returns the number of errors. If any errors are
+** encountered, then an appropriate error message is left in
+** pParse->zErrMsg.
+**
+** This routine does NOT free the Select structure passed in. The
+** calling function needs to do that.
+**
+** The pParent, parentTab, and *pParentAgg fields are filled in if this
+** SELECT is a subquery. This routine may try to combine this SELECT
+** with its parent to form a single flat query. In so doing, it might
+** change the parent query from a non-aggregate to an aggregate query.
+** For that reason, the pParentAgg flag is passed as a pointer, so it
+** can be changed.
+**
+** Example 1: The meaning of the pParent parameter.
+**
+** SELECT * FROM t1 JOIN (SELECT x, count(*) FROM t2) JOIN t3;
+** \ \_______ subquery _______/ /
+** \ /
+** \____________________ outer query ___________________/
+**
+** This routine is called for the outer query first. For that call,
+** pParent will be NULL. During the processing of the outer query, this
+** routine is called recursively to handle the subquery. For the recursive
+** call, pParent will point to the outer query. Because the subquery is
+** the second element in a three-way join, the parentTab parameter will
+** be 1 (the 2nd value of a 0-indexed array.)
+*/
+int sqlite3Select(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The SELECT statement being coded. */
+ int eDest, /* How to dispose of the results */
+ int iParm, /* A parameter used by the eDest disposal method */
+ Select *pParent, /* Another SELECT for which this is a sub-query */
+ int parentTab, /* Index in pParent->pSrc of this query */
+ int *pParentAgg, /* True if pParent uses aggregate functions */
+ char *aff /* If eDest is SRT_Union, the affinity string */
+){
+ int i;
+ WhereInfo *pWInfo;
+ Vdbe *v;
+ int isAgg; /* True for select lists like "count(*)" */
+ ExprList *pEList; /* List of columns to extract. */
+ SrcList *pTabList; /* List of tables to select from */
+ Expr *pWhere; /* The WHERE clause. May be NULL */
+ ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
+ ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
+ Expr *pHaving; /* The HAVING clause. May be NULL */
+ int isDistinct; /* True if the DISTINCT keyword is present */
+ int distinct; /* Table to use for the distinct set */
+ int rc = 1; /* Value to return from this function */
+ AggregateInfo sAggInfo;
+
+ if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1;
+ if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+ /* If there is are a sequence of queries, do the earlier ones first.
+ */
+ if( p->pPrior ){
+ return multiSelect(pParse, p, eDest, iParm, aff);
+ }
+#endif
+
+ saveAggregateInfo(pParse, &sAggInfo);
+ pOrderBy = p->pOrderBy;
+ if( eDest==SRT_Union || eDest==SRT_Except || eDest==SRT_Discard ){
+ p->pOrderBy = 0;
+ }
+ if( sqlite3SelectResolve(pParse, p, 0) ){
+ goto select_end;
+ }
+ p->pOrderBy = pOrderBy;
+
+ /* Make local copies of the parameters for this query.
+ */
+ pTabList = p->pSrc;
+ pWhere = p->pWhere;
+ pGroupBy = p->pGroupBy;
+ pHaving = p->pHaving;
+ isAgg = p->isAgg;
+ isDistinct = p->isDistinct;
+ pEList = p->pEList;
+ if( pEList==0 ) goto select_end;
+
+ /*
+ ** Do not even attempt to generate any code if we have already seen
+ ** errors before this routine starts.
+ */
+ if( pParse->nErr>0 ) goto select_end;
+
+ /* If writing to memory or generating a set
+ ** only a single column may be output.
+ */
+ assert( eDest!=SRT_Exists || pEList->nExpr==1 );
+#ifndef SQLITE_OMIT_SUBQUERY
+ if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
+ sqlite3ErrorMsg(pParse, "only a single result allowed for "
+ "a SELECT that is part of an expression");
+ goto select_end;
+ }
+#endif
+
+ /* ORDER BY is ignored for some destinations.
+ */
+ switch( eDest ){
+ case SRT_Union:
+ case SRT_Except:
+ case SRT_Discard:
+ pOrderBy = 0;
+ break;
+ default:
+ break;
+ }
+
+ /* Begin generating code.
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto select_end;
+
+ /* Identify column names if we will be using them in a callback. This
+ ** step is skipped if the output is going to some other destination.
+ */
+ if( eDest==SRT_Callback ){
+ generateColumnNames(pParse, pTabList, pEList);
+ }
+
+ /* Generate code for all sub-queries in the FROM clause
+ */
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ for(i=0; i<pTabList->nSrc; i++){
+ const char *zSavedAuthContext = 0;
+ int needRestoreContext;
+
+ if( pTabList->a[i].pSelect==0 ) continue;
+ if( pTabList->a[i].zName!=0 ){
+ zSavedAuthContext = pParse->zAuthContext;
+ pParse->zAuthContext = pTabList->a[i].zName;
+ needRestoreContext = 1;
+ }else{
+ needRestoreContext = 0;
+ }
+ sqlite3Select(pParse, pTabList->a[i].pSelect, SRT_TempTable,
+ pTabList->a[i].iCursor, p, i, &isAgg, 0);
+ if( needRestoreContext ){
+ pParse->zAuthContext = zSavedAuthContext;
+ }
+ pTabList = p->pSrc;
+ pWhere = p->pWhere;
+ if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
+ pOrderBy = p->pOrderBy;
+ }
+ pGroupBy = p->pGroupBy;
+ pHaving = p->pHaving;
+ isDistinct = p->isDistinct;
+ }
+#endif
+
+ /* Check for the special case of a min() or max() function by itself
+ ** in the result set.
+ */
+ if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
+ rc = 0;
+ goto select_end;
+ }
+
+ /* Check to see if this is a subquery that can be "flattened" into its parent.
+ ** If flattening is a possiblity, do so and return immediately.
+ */
+#ifndef SQLITE_OMIT_VIEW
+ if( pParent && pParentAgg &&
+ flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
+ if( isAgg ) *pParentAgg = 1;
+ goto select_end;
+ }
+#endif
+
+ /* If there is an ORDER BY clause, resolve any collation sequences
+ ** names that have been explicitly specified.
+ */
+ if( pOrderBy ){
+ for(i=0; i<pOrderBy->nExpr; i++){
+ if( pOrderBy->a[i].zName ){
+ pOrderBy->a[i].pExpr->pColl =
+ sqlite3LocateCollSeq(pParse, pOrderBy->a[i].zName, -1);
+ }
+ }
+ if( pParse->nErr ){
+ goto select_end;
+ }
+ }
+
+ /* Set the limiter.
+ */
+ computeLimitRegisters(pParse, p);
+
+ /* 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_SetNumColumns, iParm, pEList->nExpr);
+ }
+
+ /* Do an analysis of aggregate expressions.
+ */
+ if( isAgg || pGroupBy ){
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ sNC.pSrcList = pTabList;
+
+ assert( pParse->nAgg==0 );
+ isAgg = 1;
+ for(i=0; i<pEList->nExpr; i++){
+ if( sqlite3ExprAnalyzeAggregates(&sNC, pEList->a[i].pExpr) ){
+ goto select_end;
+ }
+ }
+ if( pGroupBy ){
+ for(i=0; i<pGroupBy->nExpr; i++){
+ if( sqlite3ExprAnalyzeAggregates(&sNC, pGroupBy->a[i].pExpr) ){
+ goto select_end;
+ }
+ }
+ }
+ if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){
+ goto select_end;
+ }
+ if( pOrderBy ){
+ for(i=0; i<pOrderBy->nExpr; i++){
+ if( sqlite3ExprAnalyzeAggregates(&sNC, pOrderBy->a[i].pExpr) ){
+ goto select_end;
+ }
+ }
+ }
+ }
+
+ /* Reset the aggregator
+ */
+ if( isAgg ){
+ int addr = sqlite3VdbeAddOp(v, OP_AggReset, (pGroupBy?0:1), pParse->nAgg);
+ for(i=0; i<pParse->nAgg; i++){
+ FuncDef *pFunc;
+ if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
+ int nExpr = 0;
+#ifdef SQLITE_SSE
+ Expr *pAggExpr = pParse->aAgg[i].pExpr;
+ if( pAggExpr && pAggExpr->pList ){
+ nExpr = pAggExpr->pList->nExpr;
+ }
+#endif
+ sqlite3VdbeOp3(v, OP_AggInit, nExpr, i, (char*)pFunc, P3_FUNCDEF);
+ }
+ }
+ if( pGroupBy ){
+ int sz = sizeof(KeyInfo) + pGroupBy->nExpr*sizeof(CollSeq*);
+ KeyInfo *pKey = (KeyInfo *)sqliteMalloc(sz);
+ if( 0==pKey ){
+ goto select_end;
+ }
+ pKey->enc = pParse->db->enc;
+ pKey->nField = pGroupBy->nExpr;
+ for(i=0; i<pGroupBy->nExpr; i++){
+ pKey->aColl[i] = sqlite3ExprCollSeq(pParse, pGroupBy->a[i].pExpr);
+ if( !pKey->aColl[i] ){
+ pKey->aColl[i] = pParse->db->pDfltColl;
+ }
+ }
+ sqlite3VdbeChangeP3(v, addr, (char *)pKey, P3_KEYINFO_HANDOFF);
+ }
+ }
+
+ /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
+ */
+ if( eDest==SRT_Mem || eDest==SRT_Exists ){
+ sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_Null : OP_Integer, 0, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
+ }
+
+ /* Open a temporary table to use for the distinct set.
+ */
+ if( isDistinct ){
+ distinct = pParse->nTab++;
+ openTempIndex(pParse, p, distinct);
+ }else{
+ distinct = -1;
+ }
+
+ /* Begin the database scan
+ */
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,
+ pGroupBy ? 0 : &pOrderBy);
+ if( pWInfo==0 ) goto select_end;
+
+ /* Use the standard inner loop if we are not dealing with
+ ** aggregates
+ */
+ if( !isAgg ){
+ if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
+ iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){
+ goto select_end;
+ }
+ }
+
+ /* If we are dealing with aggregates, then do the special aggregate
+ ** processing.
+ */
+ else{
+ AggExpr *pAgg;
+ int lbl1 = 0;
+ pParse->fillAgg = 1;
+ if( pGroupBy ){
+ for(i=0; i<pGroupBy->nExpr; i++){
+ sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr);
+ }
+ /* 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);
+ lbl1 = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_AggFocus, 0, lbl1);
+ }
+ for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
+ if( pAgg->isAgg ) continue;
+ sqlite3ExprCode(pParse, pAgg->pExpr);
+ sqlite3VdbeAddOp(v, OP_AggSet, 0, i);
+ }
+ pParse->fillAgg = 0;
+ if( lbl1<0 ){
+ sqlite3VdbeResolveLabel(v, lbl1);
+ }
+ for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
+ Expr *pE;
+ int nExpr;
+ FuncDef *pDef;
+ if( !pAgg->isAgg ) continue;
+ assert( pAgg->pFunc!=0 );
+ assert( pAgg->pFunc->xStep!=0 );
+ pDef = pAgg->pFunc;
+ pE = pAgg->pExpr;
+ assert( pE!=0 );
+ assert( pE->op==TK_AGG_FUNCTION );
+ nExpr = sqlite3ExprCodeExprList(pParse, pE->pList);
+ sqlite3VdbeAddOp(v, OP_Integer, i, 0);
+ if( pDef->needCollSeq ){
+ CollSeq *pColl = 0;
+ int j;
+ for(j=0; !pColl && j<nExpr; j++){
+ pColl = sqlite3ExprCollSeq(pParse, pE->pList->a[j].pExpr);
+ }
+ if( !pColl ) pColl = pParse->db->pDfltColl;
+ sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
+ }
+ sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_FUNCDEF);
+ }
+ }
+
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+
+ /* If we are processing aggregates, we need to set up a second loop
+ ** over all of the aggregate values and process them.
+ */
+ if( isAgg ){
+ int endagg = sqlite3VdbeMakeLabel(v);
+ int startagg;
+ startagg = sqlite3VdbeAddOp(v, OP_AggNext, 0, endagg);
+ if( pHaving ){
+ sqlite3ExprIfFalse(pParse, pHaving, startagg, 1);
+ }
+ if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
+ iParm, startagg, endagg, aff) ){
+ goto select_end;
+ }
+ sqlite3VdbeAddOp(v, OP_Goto, 0, startagg);
+ sqlite3VdbeResolveLabel(v, endagg);
+ sqlite3VdbeAddOp(v, OP_Noop, 0, 0);
+ }
+
+ /* If there is an ORDER BY clause, then we need to sort the results
+ ** and send them to the callback one by one.
+ */
+ if( pOrderBy ){
+ generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
+ }
+
+#ifndef SQLITE_OMIT_SUBQUERY
+ /* If this was a subquery, we have now converted the subquery into a
+ ** temporary table. So delete the subquery structure from the parent
+ ** to prevent this subquery from being evaluated again and to force the
+ ** the use of the temporary table.
+ */
+ if( pParent ){
+ assert( pParent->pSrc->nSrc>parentTab );
+ assert( pParent->pSrc->a[parentTab].pSelect==p );
+ sqlite3SelectDelete(p);
+ pParent->pSrc->a[parentTab].pSelect = 0;
+ }
+#endif
+
+ /* The SELECT was successfully coded. Set the return code to 0
+ ** to indicate no errors.
+ */
+ rc = 0;
+
+ /* Control jumps to here if an error is encountered above, or upon
+ ** successful coding of the SELECT.
+ */
+select_end:
+ restoreAggregateInfo(pParse, &sAggInfo);
+ return rc;
+}
diff --git a/src/sqlite/sqlite3.h b/src/sqlite/sqlite3.h
new file mode 100644
index 0000000..1a87067
--- /dev/null
+++ b/src/sqlite/sqlite3.h
@@ -0,0 +1,1267 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the interface that the SQLite library
+** presents to client programs.
+**
+** @(#) $Id: sqlite3.h,v 1.1.1.1 2006/02/03 20:35:12 hoganrobert Exp $
+*/
+#ifndef _SQLITE3_H_
+#define _SQLITE3_H_
+#include <stdarg.h> /* Needed for the definition of va_list */
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** The version of the SQLite library.
+*/
+#ifdef SQLITE_VERSION
+# undef SQLITE_VERSION
+#endif
+#define SQLITE_VERSION "3.2.2"
+
+/*
+** The format of the version string is "X.Y.Z<trailing string>", where
+** X is the major version number, Y is the minor version number and Z
+** is the release number. The trailing string is often "alpha" or "beta".
+** For example "3.1.1beta".
+**
+** The SQLITE_VERSION_NUMBER is an integer with the value
+** (X*100000 + Y*1000 + Z). For example, for version "3.1.1beta",
+** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using
+** version 3.1.1 or greater at compile time, programs may use the test
+** (SQLITE_VERSION_NUMBER>=3001001).
+*/
+#ifdef SQLITE_VERSION_NUMBER
+# undef SQLITE_VERSION_NUMBER
+#endif
+#define SQLITE_VERSION_NUMBER 3002002
+
+/*
+** The version string is also compiled into the library so that a program
+** can check to make sure that the lib*.a file and the *.h file are from
+** the same version. The sqlite3_libversion() function returns a pointer
+** to the sqlite3_version variable - useful in DLLs which cannot access
+** global variables.
+*/
+extern const char sqlite3_version[];
+const char *sqlite3_libversion(void);
+
+/*
+** Return the value of the SQLITE_VERSION_NUMBER macro when the
+** library was compiled.
+*/
+int sqlite3_libversion_number(void);
+
+/*
+** Each open sqlite database is represented by an instance of the
+** following opaque structure.
+*/
+typedef struct sqlite3 sqlite3;
+
+
+/*
+** Some compilers do not support the "long long" datatype. So we have
+** to do a typedef that for 64-bit integers that depends on what compiler
+** is being used.
+*/
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+ typedef __int64 sqlite_int64;
+ typedef unsigned __int64 sqlite_uint64;
+#else
+ typedef long long int sqlite_int64;
+ typedef unsigned long long int sqlite_uint64;
+#endif
+
+
+/*
+** A function to close the database.
+**
+** Call this function with a pointer to a structure that was previously
+** returned from sqlite3_open() and the corresponding database will by closed.
+**
+** All SQL statements prepared using sqlite3_prepare() or
+** sqlite3_prepare16() must be deallocated using sqlite3_finalize() before
+** this routine is called. Otherwise, SQLITE_BUSY is returned and the
+** database connection remains open.
+*/
+int sqlite3_close(sqlite3 *);
+
+/*
+** The type for a callback function.
+*/
+typedef int (*sqlite3_callback)(void*,int,char**, char**);
+
+/*
+** A function to executes one or more statements of SQL.
+**
+** If one or more of the SQL statements are queries, then
+** the callback function specified by the 3rd parameter is
+** invoked once for each row of the query result. This callback
+** should normally return 0. If the callback returns a non-zero
+** value then the query is aborted, all subsequent SQL statements
+** are skipped and the sqlite3_exec() function returns the SQLITE_ABORT.
+**
+** The 4th parameter is an arbitrary pointer that is passed
+** to the callback function as its first parameter.
+**
+** The 2nd parameter to the callback function is the number of
+** columns in the query result. The 3rd parameter to the callback
+** is an array of strings holding the values for each column.
+** The 4th parameter to the callback is an array of strings holding
+** the names of each column.
+**
+** The callback function may be NULL, even for queries. A NULL
+** callback is not an error. It just means that no callback
+** will be invoked.
+**
+** If an error occurs while parsing or evaluating the SQL (but
+** not while executing the callback) then an appropriate error
+** message is written into memory obtained from malloc() and
+** *errmsg is made to point to that message. The calling function
+** is responsible for freeing the memory that holds the error
+** message. Use sqlite3_free() for this. If errmsg==NULL,
+** then no error message is ever written.
+**
+** The return value is is SQLITE_OK if there are no errors and
+** some other return code if there is an error. The particular
+** return value depends on the type of error.
+**
+** If the query could not be executed because a database file is
+** locked or busy, then this function returns SQLITE_BUSY. (This
+** behavior can be modified somewhat using the sqlite3_busy_handler()
+** and sqlite3_busy_timeout() functions below.)
+*/
+int sqlite3_exec(
+ sqlite3*, /* An open database */
+ const char *sql, /* SQL to be executed */
+ sqlite3_callback, /* Callback function */
+ void *, /* 1st argument to callback function */
+ char **errmsg /* Error msg written here */
+);
+
+/*
+** Return values for sqlite3_exec() and sqlite3_step()
+*/
+#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_PERM 3 /* Access permission denied */
+#define SQLITE_ABORT 4 /* Callback routine requested an abort */
+#define SQLITE_BUSY 5 /* The database file is locked */
+#define SQLITE_LOCKED 6 /* A table in the database is locked */
+#define SQLITE_NOMEM 7 /* A malloc() failed */
+#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
+#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_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_CONSTRAINT 19 /* Abort due to contraint violation */
+#define SQLITE_MISMATCH 20 /* Data type mismatch */
+#define SQLITE_MISUSE 21 /* Library used incorrectly */
+#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
+#define SQLITE_AUTH 23 /* Authorization denied */
+#define SQLITE_FORMAT 24 /* Auxiliary database format error */
+#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
+#define SQLITE_NOTADB 26 /* File opened that is not a database file */
+#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
+#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
+
+/*
+** Each entry in an SQLite table has a unique integer key. (The key is
+** the value of the INTEGER PRIMARY KEY column if there is such a column,
+** otherwise the key is generated at random. The unique key is always
+** available as the ROWID, OID, or _ROWID_ column.) The following routine
+** returns the integer key of the most recent insert in the database.
+**
+** This function is similar to the mysql_insert_id() function from MySQL.
+*/
+sqlite_int64 sqlite3_last_insert_rowid(sqlite3*);
+
+/*
+** This function returns the number of database rows that were changed
+** (or inserted or deleted) by the most recent called sqlite3_exec().
+**
+** All changes are counted, even if they were later undone by a
+** ROLLBACK or ABORT. Except, changes associated with creating and
+** dropping tables are not counted.
+**
+** If a callback invokes sqlite3_exec() recursively, then the changes
+** in the inner, recursive call are counted together with the changes
+** in the outer call.
+**
+** SQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table. (This is much faster than going
+** through and deleting individual elements form the table.) Because of
+** this optimization, the change count for "DELETE FROM table" will be
+** zero regardless of the number of elements that were originally in the
+** table. To get an accurate count of the number of rows deleted, use
+** "DELETE FROM table WHERE 1" instead.
+*/
+int sqlite3_changes(sqlite3*);
+
+/*
+** This function returns the number of database rows that have been
+** modified by INSERT, UPDATE or DELETE statements since the database handle
+** was opened. This includes UPDATE, INSERT and DELETE statements executed
+** as part of trigger programs. All changes are counted as soon as the
+** statement that makes them is completed (when the statement handle is
+** passed to sqlite3_reset() or sqlite_finalise()).
+**
+** SQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table. (This is much faster than going
+** through and deleting individual elements form the table.) Because of
+** this optimization, the change count for "DELETE FROM table" will be
+** zero regardless of the number of elements that were originally in the
+** table. To get an accurate count of the number of rows deleted, use
+** "DELETE FROM table WHERE 1" instead.
+*/
+int sqlite3_total_changes(sqlite3*);
+
+/* This function causes any pending database operation to abort and
+** return at its earliest opportunity. This routine is typically
+** called in response to a user action such as pressing "Cancel"
+** or Ctrl-C where the user wants a long query operation to halt
+** immediately.
+*/
+void sqlite3_interrupt(sqlite3*);
+
+
+/* These functions return true if the given input string comprises
+** one or more complete SQL statements. For the sqlite3_complete() call,
+** the parameter must be a nul-terminated UTF-8 string. For
+** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string
+** is required.
+**
+** The algorithm is simple. If the last token other than spaces
+** and comments is a semicolon, then return true. otherwise return
+** false.
+*/
+int sqlite3_complete(const char *sql);
+int sqlite3_complete16(const void *sql);
+
+/*
+** This routine identifies a callback function that is invoked
+** whenever an attempt is made to open a database table that is
+** currently locked by another process or thread. If the busy callback
+** is NULL, then sqlite3_exec() returns SQLITE_BUSY immediately if
+** it finds a locked table. If the busy callback is not NULL, then
+** sqlite3_exec() invokes the callback with three arguments. The
+** second argument is the name of the locked table and the third
+** argument is the number of times the table has been busy. If the
+** busy callback returns 0, then sqlite3_exec() immediately returns
+** SQLITE_BUSY. If the callback returns non-zero, then sqlite3_exec()
+** tries to open the table again and the cycle repeats.
+**
+** The default busy callback is NULL.
+**
+** Sqlite is re-entrant, so the busy handler may start a new query.
+** (It is not clear why anyone would every want to do this, but it
+** is allowed, in theory.) But the busy handler may not close the
+** database. Closing the database from a busy handler will delete
+** data structures out from under the executing query and will
+** probably result in a coredump.
+*/
+int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
+
+/*
+** This routine sets a busy handler that sleeps for a while when a
+** table is locked. The handler will sleep multiple times until
+** at least "ms" milleseconds of sleeping have been done. After
+** "ms" milleseconds of sleeping, the handler returns 0 which
+** causes sqlite3_exec() to return SQLITE_BUSY.
+**
+** Calling this routine with an argument less than or equal to zero
+** turns off all busy handlers.
+*/
+int sqlite3_busy_timeout(sqlite3*, int ms);
+
+/*
+** This next routine is really just a wrapper around sqlite3_exec().
+** Instead of invoking a user-supplied callback for each row of the
+** result, this routine remembers each row of the result in memory
+** obtained from malloc(), then returns all of the result after the
+** query has finished.
+**
+** As an example, suppose the query result where this table:
+**
+** Name | Age
+** -----------------------
+** Alice | 43
+** Bob | 28
+** Cindy | 21
+**
+** If the 3rd argument were &azResult then after the function returns
+** azResult will contain the following data:
+**
+** azResult[0] = "Name";
+** azResult[1] = "Age";
+** azResult[2] = "Alice";
+** azResult[3] = "43";
+** azResult[4] = "Bob";
+** azResult[5] = "28";
+** azResult[6] = "Cindy";
+** azResult[7] = "21";
+**
+** Notice that there is an extra row of data containing the column
+** headers. But the *nrow return value is still 3. *ncolumn is
+** set to 2. In general, the number of values inserted into azResult
+** will be ((*nrow) + 1)*(*ncolumn).
+**
+** After the calling function has finished using the result, it should
+** pass the result data pointer to sqlite3_free_table() in order to
+** release the memory that was malloc-ed. Because of the way the
+** malloc() happens, the calling function must not try to call
+** free() directly. Only sqlite3_free_table() is able to release
+** the memory properly and safely.
+**
+** The return value of this routine is the same as from sqlite3_exec().
+*/
+int sqlite3_get_table(
+ sqlite3*, /* An open database */
+ const char *sql, /* SQL to be executed */
+ char ***resultp, /* Result written to a char *[] that this points to */
+ int *nrow, /* Number of result rows written here */
+ int *ncolumn, /* Number of result columns written here */
+ char **errmsg /* Error msg written here */
+);
+
+/*
+** Call this routine to free the memory that sqlite3_get_table() allocated.
+*/
+void sqlite3_free_table(char **result);
+
+/*
+** The following routines are variants of the "sprintf()" from the
+** standard C library. The resulting string is written into memory
+** obtained from malloc() so that there is never a possiblity of buffer
+** overflow. These routines also implement some additional formatting
+** options that are useful for constructing SQL statements.
+**
+** The strings returned by these routines should be freed by calling
+** sqlite3_free().
+**
+** All of the usual printf formatting options apply. In addition, there
+** is a "%q" option. %q works like %s in that it substitutes a null-terminated
+** string from the argument list. But %q also doubles every '\'' character.
+** %q is designed for use inside a string literal. By doubling each '\''
+** character it escapes that character and allows it to be inserted into
+** the string.
+**
+** For example, so some string variable contains text as follows:
+**
+** char *zText = "It's a happy day!";
+**
+** We can use this text in an SQL statement as follows:
+**
+** sqlite3_exec_printf(db, "INSERT INTO table VALUES('%q')",
+** callback1, 0, 0, zText);
+**
+** Because the %q format string is used, the '\'' character in zText
+** is escaped and the SQL generated is as follows:
+**
+** INSERT INTO table1 VALUES('It''s a happy day!')
+**
+** This is correct. Had we used %s instead of %q, the generated SQL
+** would have looked like this:
+**
+** INSERT INTO table1 VALUES('It's a happy day!');
+**
+** This second example is an SQL syntax error. As a general rule you
+** should always use %q instead of %s when inserting text into a string
+** literal.
+*/
+char *sqlite3_mprintf(const char*,...);
+char *sqlite3_vmprintf(const char*, va_list);
+void sqlite3_free(char *z);
+char *sqlite3_snprintf(int,char*,const char*, ...);
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+/*
+** This routine registers a callback with the SQLite library. The
+** callback is invoked (at compile-time, not at run-time) for each
+** attempt to access a column of a table in the database. The callback
+** returns SQLITE_OK if access is allowed, SQLITE_DENY if the entire
+** SQL statement should be aborted with an error and SQLITE_IGNORE
+** if the column should be treated as a NULL value.
+*/
+int sqlite3_set_authorizer(
+ sqlite3*,
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+ void *pUserData
+);
+#endif
+
+/*
+** The second parameter to the access authorization function above will
+** be one of the values below. These values signify what kind of operation
+** is to be authorized. The 3rd and 4th parameters to the authorization
+** function will be parameters or NULL depending on which of the following
+** codes is used as the second parameter. The 5th parameter is the name
+** of the database ("main", "temp", etc.) if applicable. The 6th parameter
+** is the name of the inner-most trigger or view that is responsible for
+** the access attempt or NULL if this access attempt is directly from
+** input SQL code.
+**
+** Arg-3 Arg-4
+*/
+#define SQLITE_COPY 0 /* Table Name File Name */
+#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
+#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
+#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
+#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
+#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
+#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
+#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
+#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
+#define SQLITE_DELETE 9 /* Table Name NULL */
+#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */
+#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
+#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
+#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
+#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
+#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
+#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
+#define SQLITE_DROP_VIEW 17 /* View Name NULL */
+#define SQLITE_INSERT 18 /* Table Name NULL */
+#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
+#define SQLITE_READ 20 /* Table Name Column Name */
+#define SQLITE_SELECT 21 /* NULL NULL */
+#define SQLITE_TRANSACTION 22 /* NULL NULL */
+#define SQLITE_UPDATE 23 /* Table Name Column Name */
+#define SQLITE_ATTACH 24 /* Filename NULL */
+#define SQLITE_DETACH 25 /* Database Name NULL */
+#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
+#define SQLITE_REINDEX 27 /* Index Name NULL */
+
+
+/*
+** The return value of the authorization function should be one of the
+** following constants:
+*/
+/* #define SQLITE_OK 0 // Allow access (This is actually defined above) */
+#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
+#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
+
+/*
+** Register a function that is called at every invocation of sqlite3_exec()
+** or sqlite3_prepare(). This function can be used (for example) to generate
+** a log file of all SQL executed against a database.
+*/
+void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+
+/*
+** This routine configures a callback function - the progress callback - that
+** is invoked periodically during long running calls to sqlite3_exec(),
+** sqlite3_step() and sqlite3_get_table(). An example use for this API is to
+** keep a GUI updated during a large query.
+**
+** The progress callback is invoked once for every N virtual machine opcodes,
+** where N is the second argument to this function. The progress callback
+** itself is identified by the third argument to this function. The fourth
+** argument to this function is a void pointer passed to the progress callback
+** function each time it is invoked.
+**
+** If a call to sqlite3_exec(), sqlite3_step() or sqlite3_get_table() results
+** in less than N opcodes being executed, then the progress callback is not
+** invoked.
+**
+** To remove the progress callback altogether, pass NULL as the third
+** argument to this function.
+**
+** If the progress callback returns a result other than 0, then the current
+** query is immediately terminated and any database changes rolled back. If the
+** query was part of a larger transaction, then the transaction is not rolled
+** back and remains active. The sqlite3_exec() call returns SQLITE_ABORT.
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+
+/*
+** Register a callback function to be invoked whenever a new transaction
+** is committed. The pArg argument is passed through to the callback.
+** callback. If the callback function returns non-zero, then the commit
+** is converted into a rollback.
+**
+** If another function was previously registered, its pArg value is returned.
+** Otherwise NULL is returned.
+**
+** Registering a NULL function disables the callback.
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+
+/*
+** Open the sqlite database file "filename". The "filename" is UTF-8
+** encoded for sqlite3_open() and UTF-16 encoded in the native byte order
+** for sqlite3_open16(). An sqlite3* handle is returned in *ppDb, even
+** if an error occurs. If the database is opened (or created) successfully,
+** then SQLITE_OK is returned. Otherwise an error code is returned. The
+** sqlite3_errmsg() or sqlite3_errmsg16() routines can be used to obtain
+** an English language description of the error.
+**
+** If the database file does not exist, then a new database is created.
+** The encoding for the database is UTF-8 if sqlite3_open() is called and
+** UTF-16 if sqlite3_open16 is used.
+**
+** Whether or not an error occurs when it is opened, resources associated
+** with the sqlite3* handle should be released by passing it to
+** sqlite3_close() when it is no longer required.
+*/
+int sqlite3_open(
+ const char *filename, /* Database filename (UTF-8) */
+ sqlite3 **ppDb /* OUT: SQLite db handle */
+);
+int sqlite3_open16(
+ const void *filename, /* Database filename (UTF-16) */
+ sqlite3 **ppDb /* OUT: SQLite db handle */
+);
+
+/*
+** Return the error code for the most recent sqlite3_* API call associated
+** with sqlite3 handle 'db'. SQLITE_OK is returned if the most recent
+** API call was successful.
+**
+** Calls to many sqlite3_* functions set the error code and string returned
+** by sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16()
+** (overwriting the previous values). Note that calls to sqlite3_errcode(),
+** sqlite3_errmsg() and sqlite3_errmsg16() themselves do not affect the
+** results of future invocations.
+**
+** Assuming no other intervening sqlite3_* API calls are made, the error
+** code returned by this function is associated with the same error as
+** the strings returned by sqlite3_errmsg() and sqlite3_errmsg16().
+*/
+int sqlite3_errcode(sqlite3 *db);
+
+/*
+** Return a pointer to a UTF-8 encoded string describing in english the
+** error condition for the most recent sqlite3_* API call. The returned
+** string is always terminated by an 0x00 byte.
+**
+** The string "not an error" is returned when the most recent API call was
+** successful.
+*/
+const char *sqlite3_errmsg(sqlite3*);
+
+/*
+** Return a pointer to a UTF-16 native byte order encoded string describing
+** in english the error condition for the most recent sqlite3_* API call.
+** The returned string is always terminated by a pair of 0x00 bytes.
+**
+** The string "not an error" is returned when the most recent API call was
+** successful.
+*/
+const void *sqlite3_errmsg16(sqlite3*);
+
+/*
+** An instance of the following opaque structure is used to represent
+** a compiled SQL statment.
+*/
+typedef struct sqlite3_stmt sqlite3_stmt;
+
+/*
+** To execute an SQL query, it must first be compiled into a byte-code
+** program using one of the following routines. The only difference between
+** them is that the second argument, specifying the SQL statement to
+** compile, is assumed to be encoded in UTF-8 for the sqlite3_prepare()
+** function and UTF-16 for sqlite3_prepare16().
+**
+** The first parameter "db" is an SQLite database handle. The second
+** parameter "zSql" is the statement to be compiled, encoded as either
+** UTF-8 or UTF-16 (see above). If the next parameter, "nBytes", is less
+** than zero, then zSql is read up to the first nul terminator. If
+** "nBytes" is not less than zero, then it is the length of the string zSql
+** in bytes (not characters).
+**
+** *pzTail is made to point to the first byte past the end of the first
+** SQL statement in zSql. This routine only compiles the first statement
+** in zSql, so *pzTail is left pointing to what remains uncompiled.
+**
+** *ppStmt is left pointing to a compiled SQL statement that can be
+** executed using sqlite3_step(). Or if there is an error, *ppStmt may be
+** set to NULL. If the input text contained no SQL (if the input is and
+** empty string or a comment) then *ppStmt is set to NULL.
+**
+** On success, SQLITE_OK is returned. Otherwise an error code is returned.
+*/
+int sqlite3_prepare(
+ sqlite3 *db, /* Database handle */
+ const char *zSql, /* SQL statement, UTF-8 encoded */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const char **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+int sqlite3_prepare16(
+ sqlite3 *db, /* Database handle */
+ const void *zSql, /* SQL statement, UTF-16 encoded */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const void **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+
+/*
+** Pointers to the following two opaque structures are used to communicate
+** with the implementations of user-defined functions.
+*/
+typedef struct sqlite3_context sqlite3_context;
+typedef struct Mem sqlite3_value;
+
+/*
+** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(),
+** one or more literals can be replace by parameters "?" or ":AAA" or
+** "$VVV" where AAA is an identifer and VVV is a variable name according
+** to the syntax rules of the TCL programming language.
+** The value of these parameters (also called "host parameter names") can
+** be set using the routines listed below.
+**
+** In every case, the first parameter is a pointer to the sqlite3_stmt
+** structure returned from sqlite3_prepare(). The second parameter is the
+** index of the parameter. The first parameter as an index of 1. For
+** named parameters (":AAA" or "$VVV") you can use
+** sqlite3_bind_parameter_index() to get the correct index value given
+** the parameters name. If the same named parameter occurs more than
+** once, it is assigned the same index each time.
+**
+** The fifth parameter to sqlite3_bind_blob(), sqlite3_bind_text(), and
+** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
+** text after SQLite has finished with it. If the fifth argument is the
+** special value SQLITE_STATIC, then the library assumes that the information
+** is in static, unmanaged space and does not need to be freed. If the
+** fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its
+** own private copy of the data.
+**
+** The sqlite3_bind_* routine must be called before sqlite3_step() after
+** an sqlite3_prepare() or sqlite3_reset(). Unbound parameterss are
+** interpreted as NULL.
+*/
+int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+int sqlite3_bind_double(sqlite3_stmt*, int, double);
+int sqlite3_bind_int(sqlite3_stmt*, int, int);
+int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite_int64);
+int sqlite3_bind_null(sqlite3_stmt*, int);
+int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
+int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+
+/*
+** Return the number of parameters in a compiled SQL statement. This
+** routine was added to support DBD::SQLite.
+*/
+int sqlite3_bind_parameter_count(sqlite3_stmt*);
+
+/*
+** Return the name of the i-th parameter. Ordinary parameters "?" are
+** nameless and a NULL is returned. For parameters of the form :AAA or
+** $VVV the complete text of the parameter name is returned, including
+** the initial ":" or "$". NULL is returned if the index is out of range.
+*/
+const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+
+/*
+** Return the index of a parameter with the given name. The name
+** must match exactly. If no parameter with the given name is found,
+** return 0.
+*/
+int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+
+/*
+** Set all the parameters in the compiled SQL statement to NULL.
+*/
+int sqlite3_clear_bindings(sqlite3_stmt*);
+
+/*
+** Return the number of columns in the result set returned by the compiled
+** SQL statement. This routine returns 0 if pStmt is an SQL statement
+** that does not return data (for example an UPDATE).
+*/
+int sqlite3_column_count(sqlite3_stmt *pStmt);
+
+/*
+** The first parameter is a compiled SQL statement. This function returns
+** the column heading for the Nth column of that statement, where N is the
+** second function parameter. The string returned is UTF-8 for
+** sqlite3_column_name() and UTF-16 for sqlite3_column_name16().
+*/
+const char *sqlite3_column_name(sqlite3_stmt*,int);
+const void *sqlite3_column_name16(sqlite3_stmt*,int);
+
+/*
+** The first parameter is a compiled SQL statement. If this statement
+** is a SELECT statement, the Nth column of the returned result set
+** of the SELECT is a table column then the declared type of the table
+** column is returned. If the Nth column of the result set is not at table
+** column, then a NULL pointer is returned. The returned string is always
+** UTF-8 encoded. For example, in the database schema:
+**
+** CREATE TABLE t1(c1 VARIANT);
+**
+** And the following statement compiled:
+**
+** SELECT c1 + 1, 0 FROM t1;
+**
+** Then this routine would return the string "VARIANT" for the second
+** result column (i==1), and a NULL pointer for the first result column
+** (i==0).
+*/
+const char *sqlite3_column_decltype(sqlite3_stmt *, int i);
+
+/*
+** The first parameter is a compiled SQL statement. If this statement
+** is a SELECT statement, the Nth column of the returned result set
+** of the SELECT is a table column then the declared type of the table
+** column is returned. If the Nth column of the result set is not at table
+** column, then a NULL pointer is returned. The returned string is always
+** UTF-16 encoded. For example, in the database schema:
+**
+** CREATE TABLE t1(c1 INTEGER);
+**
+** And the following statement compiled:
+**
+** SELECT c1 + 1, 0 FROM t1;
+**
+** Then this routine would return the string "INTEGER" for the second
+** result column (i==1), and a NULL pointer for the first result column
+** (i==0).
+*/
+const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+
+/*
+** After an SQL query has been compiled with a call to either
+** sqlite3_prepare() or sqlite3_prepare16(), then this function must be
+** called one or more times to execute the statement.
+**
+** The return value will be either SQLITE_BUSY, SQLITE_DONE,
+** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE.
+**
+** SQLITE_BUSY means that the database engine attempted to open
+** a locked database and there is no busy callback registered.
+** Call sqlite3_step() again to retry the open.
+**
+** SQLITE_DONE means that the statement has finished executing
+** successfully. sqlite3_step() should not be called again on this virtual
+** machine.
+**
+** If the SQL statement being executed returns any data, then
+** SQLITE_ROW is returned each time a new row of data is ready
+** for processing by the caller. The values may be accessed using
+** the sqlite3_column_*() functions described below. sqlite3_step()
+** is called again to retrieve the next row of data.
+**
+** SQLITE_ERROR means that a run-time error (such as a constraint
+** violation) has occurred. sqlite3_step() should not be called again on
+** the VM. More information may be found by calling sqlite3_errmsg().
+**
+** SQLITE_MISUSE means that the this routine was called inappropriately.
+** Perhaps it was called on a virtual machine that had already been
+** finalized or on one that had previously returned SQLITE_ERROR or
+** SQLITE_DONE. Or it could be the case the the same database connection
+** is being used simulataneously by two or more threads.
+*/
+int sqlite3_step(sqlite3_stmt*);
+
+/*
+** Return the number of values in the current row of the result set.
+**
+** After a call to sqlite3_step() that returns SQLITE_ROW, this routine
+** will return the same value as the sqlite3_column_count() function.
+** After sqlite3_step() has returned an SQLITE_DONE, SQLITE_BUSY or
+** error code, or before sqlite3_step() has been called on a
+** compiled SQL statement, this routine returns zero.
+*/
+int sqlite3_data_count(sqlite3_stmt *pStmt);
+
+/*
+** Values are stored in the database in one of the following fundamental
+** types.
+*/
+#define SQLITE_INTEGER 1
+#define SQLITE_FLOAT 2
+/* #define SQLITE_TEXT 3 // See below */
+#define SQLITE_BLOB 4
+#define SQLITE_NULL 5
+
+/*
+** SQLite version 2 defines SQLITE_TEXT differently. To allow both
+** version 2 and version 3 to be included, undefine them both if a
+** conflict is seen. Define SQLITE3_TEXT to be the version 3 value.
+*/
+#ifdef SQLITE_TEXT
+# undef SQLITE_TEXT
+#else
+# define SQLITE_TEXT 3
+#endif
+#define SQLITE3_TEXT 3
+
+/*
+** The next group of routines returns information about the information
+** in a single column of the current result row of a query. In every
+** case the first parameter is a pointer to the SQL statement that is being
+** executed (the sqlite_stmt* that was returned from sqlite3_prepare()) and
+** the second argument is the index of the column for which information
+** should be returned. iCol is zero-indexed. The left-most column as an
+** index of 0.
+**
+** If the SQL statement is not currently point to a valid row, or if the
+** the colulmn index is out of range, the result is undefined.
+**
+** These routines attempt to convert the value where appropriate. For
+** example, if the internal representation is FLOAT and a text result
+** is requested, sprintf() is used internally to do the conversion
+** automatically. The following table details the conversions that
+** are applied:
+**
+** Internal Type Requested Type Conversion
+** ------------- -------------- --------------------------
+** NULL INTEGER Result is 0
+** NULL FLOAT Result is 0.0
+** NULL TEXT Result is an empty string
+** NULL BLOB Result is a zero-length BLOB
+** INTEGER FLOAT Convert from integer to float
+** INTEGER TEXT ASCII rendering of the integer
+** INTEGER BLOB Same as for INTEGER->TEXT
+** FLOAT INTEGER Convert from float to integer
+** FLOAT TEXT ASCII rendering of the float
+** FLOAT BLOB Same as FLOAT->TEXT
+** TEXT INTEGER Use atoi()
+** TEXT FLOAT Use atof()
+** TEXT BLOB No change
+** BLOB INTEGER Convert to TEXT then use atoi()
+** BLOB FLOAT Convert to TEXT then use atof()
+** BLOB TEXT Add a \000 terminator if needed
+**
+** The following access routines are provided:
+**
+** _type() Return the datatype of the result. This is one of
+** SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB,
+** or SQLITE_NULL.
+** _blob() Return the value of a BLOB.
+** _bytes() Return the number of bytes in a BLOB value or the number
+** of bytes in a TEXT value represented as UTF-8. The \000
+** terminator is included in the byte count for TEXT values.
+** _bytes16() Return the number of bytes in a BLOB value or the number
+** of bytes in a TEXT value represented as UTF-16. The \u0000
+** terminator is included in the byte count for TEXT values.
+** _double() Return a FLOAT value.
+** _int() Return an INTEGER value in the host computer's native
+** integer representation. This might be either a 32- or 64-bit
+** integer depending on the host.
+** _int64() Return an INTEGER value as a 64-bit signed integer.
+** _text() Return the value as UTF-8 text.
+** _text16() Return the value as UTF-16 text.
+*/
+const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+double sqlite3_column_double(sqlite3_stmt*, int iCol);
+int sqlite3_column_int(sqlite3_stmt*, int iCol);
+sqlite_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
+const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
+int sqlite3_column_type(sqlite3_stmt*, int iCol);
+
+/*
+** The sqlite3_finalize() function is called to delete a compiled
+** SQL statement obtained by a previous call to sqlite3_prepare()
+** or sqlite3_prepare16(). If the statement was executed successfully, or
+** not executed at all, then SQLITE_OK is returned. If execution of the
+** statement failed then an error code is returned.
+**
+** This routine can be called at any point during the execution of the
+** virtual machine. If the virtual machine has not completed execution
+** when this routine is called, that is like encountering an error or
+** an interrupt. (See sqlite3_interrupt().) Incomplete updates may be
+** rolled back and transactions cancelled, depending on the circumstances,
+** and the result code returned will be SQLITE_ABORT.
+*/
+int sqlite3_finalize(sqlite3_stmt *pStmt);
+
+/*
+** The sqlite3_reset() function is called to reset a compiled SQL
+** statement obtained by a previous call to sqlite3_prepare() or
+** sqlite3_prepare16() back to it's initial state, ready to be re-executed.
+** Any SQL statement variables that had values bound to them using
+** the sqlite3_bind_*() API retain their values.
+*/
+int sqlite3_reset(sqlite3_stmt *pStmt);
+
+/*
+** The following two functions are used to add user functions or aggregates
+** implemented in C to the SQL langauge interpreted by SQLite. The
+** difference only between the two is that the second parameter, the
+** name of the (scalar) function or aggregate, is encoded in UTF-8 for
+** sqlite3_create_function() and UTF-16 for sqlite3_create_function16().
+**
+** The first argument is the database handle that the new function or
+** aggregate is to be added to. If a single program uses more than one
+** database handle internally, then user functions or aggregates must
+** be added individually to each database handle with which they will be
+** used.
+**
+** The third parameter is the number of arguments that the function or
+** aggregate takes. If this parameter is negative, then the function or
+** aggregate may take any number of arguments.
+**
+** The fourth parameter is one of SQLITE_UTF* values defined below,
+** indicating the encoding that the function is most likely to handle
+** values in. This does not change the behaviour of the programming
+** interface. However, if two versions of the same function are registered
+** with different encoding values, SQLite invokes the version likely to
+** minimize conversions between text encodings.
+**
+** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
+** pointers to user implemented C functions that implement the user
+** function or aggregate. A scalar function requires an implementation of
+** the xFunc callback only, NULL pointers should be passed as the xStep
+** and xFinal parameters. An aggregate function requires an implementation
+** of xStep and xFinal, but NULL should be passed for xFunc. To delete an
+** existing user function or aggregate, pass NULL for all three function
+** callback. Specifying an inconstent set of callback values, such as an
+** xFunc and an xFinal, or an xStep but no xFinal, SQLITE_ERROR is
+** returned.
+*/
+int sqlite3_create_function(
+ sqlite3 *,
+ const char *zFunctionName,
+ int nArg,
+ int eTextRep,
+ void*,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*)
+);
+int sqlite3_create_function16(
+ sqlite3*,
+ const void *zFunctionName,
+ int nArg,
+ int eTextRep,
+ void*,
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*)
+);
+
+/*
+** The next routine returns the number of calls to xStep for a particular
+** aggregate function instance. The current call to xStep counts so this
+** routine always returns at least 1.
+*/
+int sqlite3_aggregate_count(sqlite3_context*);
+
+/*
+** The next group of routines returns information about parameters to
+** a user-defined function. Function implementations use these routines
+** to access their parameters. These routines are the same as the
+** sqlite3_column_* routines except that these routines take a single
+** sqlite3_value* pointer instead of an sqlite3_stmt* and an integer
+** column number.
+*/
+const void *sqlite3_value_blob(sqlite3_value*);
+int sqlite3_value_bytes(sqlite3_value*);
+int sqlite3_value_bytes16(sqlite3_value*);
+double sqlite3_value_double(sqlite3_value*);
+int sqlite3_value_int(sqlite3_value*);
+sqlite_int64 sqlite3_value_int64(sqlite3_value*);
+const unsigned char *sqlite3_value_text(sqlite3_value*);
+const void *sqlite3_value_text16(sqlite3_value*);
+const void *sqlite3_value_text16le(sqlite3_value*);
+const void *sqlite3_value_text16be(sqlite3_value*);
+int sqlite3_value_type(sqlite3_value*);
+
+/*
+** Aggregate functions use the following routine to allocate
+** a structure for storing their state. The first time this routine
+** is called for a particular aggregate, a new structure of size nBytes
+** is allocated, zeroed, and returned. On subsequent calls (for the
+** same aggregate instance) the same buffer is returned. The implementation
+** of the aggregate can use the returned buffer to accumulate data.
+**
+** The buffer allocated is freed automatically by SQLite.
+*/
+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.
+*/
+void *sqlite3_user_data(sqlite3_context*);
+
+/*
+** The following two functions may be used by scalar user functions to
+** associate meta-data with argument values. If the same value is passed to
+** multiple invocations of the user-function during query execution, under
+** some circumstances the associated meta-data may be preserved. This may
+** be used, for example, to add a regular-expression matching scalar
+** function. The compiled version of the regular expression is stored as
+** meta-data associated with the SQL value passed as the regular expression
+** pattern.
+**
+** Calling sqlite3_get_auxdata() returns a pointer to the meta data
+** associated with the Nth argument value to the current user function
+** call, where N is the second parameter. If no meta-data has been set for
+** that value, then a NULL pointer is returned.
+**
+** The sqlite3_set_auxdata() is used to associate meta data with a user
+** function argument. The third parameter is a pointer to the meta data
+** to be associated with the Nth user function argument value. The fourth
+** parameter specifies a 'delete function' that will be called on the meta
+** data pointer to release it when it is no longer required. If the delete
+** function pointer is NULL, it is not invoked.
+**
+** In practice, meta-data is preserved between function calls for
+** expressions that are constant at compile time. This includes literal
+** values and SQL variables.
+*/
+void *sqlite3_get_auxdata(sqlite3_context*, int);
+void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
+
+
+/*
+** These are special value for the destructor that is passed in as the
+** final argument to routines like sqlite3_result_blob(). If the destructor
+** argument is SQLITE_STATIC, it means that the content pointer is constant
+** and will never change. It does not need to be destroyed. The
+** SQLITE_TRANSIENT value means that the content will likely change in
+** the near future and that SQLite should make its own private copy of
+** the content before returning.
+*/
+#define SQLITE_STATIC ((void(*)(void *))0)
+#define SQLITE_TRANSIENT ((void(*)(void *))-1)
+
+/*
+** User-defined functions invoke the following routines in order to
+** set their return value.
+*/
+void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+void sqlite3_result_double(sqlite3_context*, double);
+void sqlite3_result_error(sqlite3_context*, const char*, int);
+void sqlite3_result_error16(sqlite3_context*, const void*, int);
+void sqlite3_result_int(sqlite3_context*, int);
+void sqlite3_result_int64(sqlite3_context*, sqlite_int64);
+void sqlite3_result_null(sqlite3_context*);
+void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+
+/*
+** These are the allowed values for the eTextRep argument to
+** sqlite3_create_collation and sqlite3_create_function.
+*/
+#define SQLITE_UTF8 1
+#define SQLITE_UTF16LE 2
+#define SQLITE_UTF16BE 3
+#define SQLITE_UTF16 4 /* Use native byte order */
+#define SQLITE_ANY 5 /* sqlite3_create_function only */
+
+/*
+** These two functions are used to add new collation sequences to the
+** sqlite3 handle specified as the first argument.
+**
+** The name of the new collation sequence is specified as a UTF-8 string
+** for sqlite3_create_collation() and a UTF-16 string for
+** sqlite3_create_collation16(). In both cases the name is passed as the
+** second function argument.
+**
+** The third argument must be one of the constants SQLITE_UTF8,
+** SQLITE_UTF16LE or SQLITE_UTF16BE, indicating that the user-supplied
+** routine expects to be passed pointers to strings encoded using UTF-8,
+** UTF-16 little-endian or UTF-16 big-endian respectively.
+**
+** A pointer to the user supplied routine must be passed as the fifth
+** argument. If it is NULL, this is the same as deleting the collation
+** sequence (so that SQLite cannot call it anymore). Each time the user
+** supplied function is invoked, it is passed a copy of the void* passed as
+** the fourth argument to sqlite3_create_collation() or
+** sqlite3_create_collation16() as its first parameter.
+**
+** The remaining arguments to the user-supplied routine are two strings,
+** each represented by a [length, data] pair and encoded in the encoding
+** that was passed as the third argument when the collation sequence was
+** registered. The user routine should return negative, zero or positive if
+** the first string is less than, equal to, or greater than the second
+** string. i.e. (STRING1 - STRING2).
+*/
+int sqlite3_create_collation(
+ sqlite3*,
+ const char *zName,
+ int eTextRep,
+ void*,
+ int(*xCompare)(void*,int,const void*,int,const void*)
+);
+int sqlite3_create_collation16(
+ sqlite3*,
+ const char *zName,
+ int eTextRep,
+ void*,
+ int(*xCompare)(void*,int,const void*,int,const void*)
+);
+
+/*
+** To avoid having to register all collation sequences before a database
+** can be used, a single callback function may be registered with the
+** database handle to be called whenever an undefined collation sequence is
+** required.
+**
+** If the function is registered using the sqlite3_collation_needed() API,
+** then it is passed the names of undefined collation sequences as strings
+** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names
+** are passed as UTF-16 in machine native byte order. A call to either
+** function replaces any existing callback.
+**
+** When the user-function is invoked, the first argument passed is a copy
+** of the second argument to sqlite3_collation_needed() or
+** sqlite3_collation_needed16(). The second argument is the database
+** handle. The third argument is one of SQLITE_UTF8, SQLITE_UTF16BE or
+** SQLITE_UTF16LE, indicating the most desirable form of the collation
+** sequence function required. The fourth parameter is the name of the
+** required collation sequence.
+**
+** The collation sequence is returned to SQLite by a collation-needed
+** callback using the sqlite3_create_collation() or
+** sqlite3_create_collation16() APIs, described above.
+*/
+int sqlite3_collation_needed(
+ sqlite3*,
+ void*,
+ void(*)(void*,sqlite3*,int eTextRep,const char*)
+);
+int sqlite3_collation_needed16(
+ sqlite3*,
+ void*,
+ void(*)(void*,sqlite3*,int eTextRep,const void*)
+);
+
+/*
+** Specify the key for an encrypted database. This routine should be
+** called right after sqlite3_open().
+**
+** The code to implement this API is not available in the public release
+** of SQLite.
+*/
+int sqlite3_key(
+ sqlite3 *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The key */
+);
+
+/*
+** Change the key on an open database. If the current database is not
+** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
+** database is decrypted.
+**
+** The code to implement this API is not available in the public release
+** of SQLite.
+*/
+int sqlite3_rekey(
+ sqlite3 *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The new key */
+);
+
+/*
+** Sleep for a little while. The second parameter is the number of
+** miliseconds to sleep for.
+**
+** If the operating system does not support sleep requests with
+** milisecond time resolution, then the time will be rounded up to
+** the nearest second. The number of miliseconds of sleep actually
+** requested from the operating system is returned.
+*/
+int sqlite3_sleep(int);
+
+/*
+** Return TRUE (non-zero) if the statement supplied as an argument needs
+** to be recompiled. A statement needs to be recompiled whenever the
+** execution environment changes in a way that would alter the program
+** that sqlite3_prepare() generates. For example, if new functions or
+** collating sequences are registered or if an authorizer function is
+** added or changed.
+**
+*/
+int sqlite3_expired(sqlite3_stmt*);
+
+/*
+** Move all bindings from the first prepared statement over to the second.
+** This routine is useful, for example, if the first prepared statement
+** fails with an SQLITE_SCHEMA error. The same SQL can be prepared into
+** the second prepared statement then all of the bindings transfered over
+** to the second statement before the first statement is finalized.
+*/
+int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+
+/*
+** If the following global variable is made to point to a
+** string which is the name of a directory, then all temporary files
+** created by SQLite will be placed in that directory. If this variable
+** is NULL pointer, then SQLite does a search for an appropriate temporary
+** file directory.
+**
+** Once sqlite3_open() has been called, changing this variable will invalidate
+** the current temporary database, if any.
+*/
+extern char *sqlite3_temp_directory;
+
+/*
+** This function is called to recover from a malloc() failure that occured
+** within the SQLite library. Normally, after a single malloc() fails the
+** library refuses to function (all major calls return SQLITE_NOMEM).
+** This function restores the library state so that it can be used again.
+**
+** All existing statements (sqlite3_stmt pointers) must be finalized or
+** reset before this call is made. Otherwise, SQLITE_BUSY is returned.
+** If any in-memory databases are in use, either as a main or TEMP
+** database, SQLITE_ERROR is returned. In either of these cases, the
+** library is not reset and remains unusable.
+**
+** This function is *not* threadsafe. Calling this from within a threaded
+** application when threads other than the caller have used SQLite is
+** dangerous and will almost certainly result in malfunctions.
+**
+** This functionality can be omitted from a build by defining the
+** SQLITE_OMIT_GLOBALRECOVER at compile time.
+*/
+int sqlite3_global_recover();
+
+/*
+** Test to see whether or not the database connection is in autocommit
+** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
+** by default. Autocommit is disabled by a BEGIN statement and reenabled
+** by the next COMMIT or ROLLBACK.
+*/
+int sqlite3_get_autocommit(sqlite3*);
+
+/*
+** Return the sqlite3* database handle to which the prepared statement given
+** in the argument belongs. This is the same database handle that was
+** the first argument to the sqlite3_prepare() that was used to create
+** the statement in the first place.
+*/
+sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+
+#ifdef __cplusplus
+} /* End of the 'extern "C"' block */
+#endif
+#endif
diff --git a/src/sqlite/sqliteInt.h b/src/sqlite/sqliteInt.h
new file mode 100644
index 0000000..c4f723f
--- /dev/null
+++ b/src/sqlite/sqliteInt.h
@@ -0,0 +1,1571 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Internal interface definitions for SQLite.
+**
+** @(#) $Id: sqliteInt.h,v 1.1.1.1 2006/02/03 20:35:10 hoganrobert Exp $
+*/
+#ifndef _SQLITEINT_H_
+#define _SQLITEINT_H_
+
+/*
+** These #defines should enable >2GB file support on Posix if the
+** underlying operating system supports it. If the OS lacks
+** large file support, or if the OS is windows, these should be no-ops.
+**
+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
+** on the compiler command line. This is necessary if you are compiling
+** on a recent machine (ex: RedHat 7.2) but you want your code to work
+** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
+** without this option, LFS is enable. But LFS does not exist in the kernel
+** in RedHat 6.0, so the code won't work. Hence, for maximum binary
+** portability you should omit LFS.
+**
+** Similar is true for MacOS. LFS is only supported on MacOS 9 and later.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE 1
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+#include "sqlite3.h"
+#include "hash.h"
+#include "parse.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stddef.h>
+
+/*
+** The maximum number of in-memory pages to use for the main database
+** table and for temporary tables. Internally, the MAX_PAGES and
+** TEMP_PAGES macros are used. To override the default values at
+** compilation time, the SQLITE_DEFAULT_CACHE_SIZE and
+** SQLITE_DEFAULT_TEMP_CACHE_SIZE macros should be set.
+*/
+#ifdef SQLITE_DEFAULT_CACHE_SIZE
+# define MAX_PAGES SQLITE_DEFAULT_CACHE_SIZE
+#else
+# define MAX_PAGES 2000
+#endif
+#ifdef SQLITE_DEFAULT_TEMP_CACHE_SIZE
+# define TEMP_PAGES SQLITE_DEFAULT_TEMP_CACHE_SIZE
+#else
+# define TEMP_PAGES 500
+#endif
+
+/*
+** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
+** afterward. Having this macro allows us to cause the C compiler
+** to omit code used by TEMP tables without messy #ifndef statements.
+*/
+#ifdef SQLITE_OMIT_TEMPDB
+#define OMIT_TEMPDB 1
+#else
+#define OMIT_TEMPDB 0
+#endif
+
+/*
+** If the following macro is set to 1, then NULL values are considered
+** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
+** compound queries. No other SQL database engine (among those tested)
+** works this way except for OCELOT. But the SQL92 spec implies that
+** this is how things should work.
+**
+** If the following macro is set to 0, then NULLs are indistinct for
+** SELECT DISTINCT and for UNION.
+*/
+#define NULL_ALWAYS_DISTINCT 0
+
+/*
+** If the following macro is set to 1, then NULL values are considered
+** distinct when determining whether or not two entries are the same
+** in a UNIQUE index. This is the way PostgreSQL, Oracle, DB2, MySQL,
+** OCELOT, and Firebird all work. The SQL92 spec explicitly says this
+** is the way things are suppose to work.
+**
+** If the following macro is set to 0, the NULLs are indistinct for
+** a UNIQUE index. In this mode, you can only have a single NULL entry
+** for a column declared UNIQUE. This is the way Informix and SQL Server
+** work.
+*/
+#define NULL_DISTINCT_FOR_UNIQUE 1
+
+/*
+** The maximum number of attached databases. This must be at least 2
+** in order to support the main database file (0) and the file used to
+** hold temporary tables (1). And it must be less than 32 because
+** we use a bitmask of databases with a u32 in places (for example
+** the Parse.cookieMask field).
+*/
+#define MAX_ATTACHED 10
+
+/*
+** The maximum value of a ?nnn wildcard that the parser will accept.
+*/
+#define SQLITE_MAX_VARIABLE_NUMBER 999
+
+/*
+** When building SQLite for embedded systems where memory is scarce,
+** you can define one or more of the following macros to omit extra
+** features of the library and thus keep the size of the library to
+** a minimum.
+*/
+/* #define SQLITE_OMIT_AUTHORIZATION 1 */
+/* #define SQLITE_OMIT_MEMORYDB 1 */
+/* #define SQLITE_OMIT_VACUUM 1 */
+/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */
+/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */
+/* #define SQLITE_OMIT_AUTOVACUUM */
+/* #define SQLITE_OMIT_ALTERTABLE */
+
+/*
+** Provide a default value for TEMP_STORE in case it is not specified
+** on the command-line
+*/
+#ifndef TEMP_STORE
+# define TEMP_STORE 1
+#endif
+
+/*
+** GCC does not define the offsetof() macro so we'll have to do it
+** ourselves.
+*/
+#ifndef offsetof
+#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
+#endif
+
+/*
+** Integers of known sizes. These typedefs might change for architectures
+** where the sizes very. Preprocessor macros are available so that the
+** types can be conveniently redefined at compile-type. Like this:
+**
+** cc '-DUINTPTR_TYPE=long long int' ...
+*/
+#ifndef UINT64_TYPE
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+# define UINT64_TYPE unsigned __int64
+# else
+# define UINT64_TYPE unsigned long long int
+# endif
+#endif
+#ifndef UINT32_TYPE
+# define UINT32_TYPE unsigned int
+#endif
+#ifndef UINT16_TYPE
+# define UINT16_TYPE unsigned short int
+#endif
+#ifndef INT16_TYPE
+# define INT16_TYPE short int
+#endif
+#ifndef UINT8_TYPE
+# define UINT8_TYPE unsigned char
+#endif
+#ifndef INT8_TYPE
+# define INT8_TYPE signed char
+#endif
+#ifndef LONGDOUBLE_TYPE
+# define LONGDOUBLE_TYPE long double
+#endif
+typedef sqlite_int64 i64; /* 8-byte signed integer */
+typedef UINT64_TYPE u64; /* 8-byte unsigned integer */
+typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
+typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
+typedef INT16_TYPE i16; /* 2-byte signed integer */
+typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
+typedef UINT8_TYPE i8; /* 1-byte signed integer */
+
+/*
+** Macros to determine whether the machine is big or little endian,
+** evaluated at runtime.
+*/
+extern const int sqlite3one;
+#define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
+#define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
+
+/*
+** An instance of the following structure is used to store the busy-handler
+** callback for a given sqlite handle.
+**
+** The sqlite.busyHandler member of the sqlite struct contains the busy
+** callback for the database handle. Each pager opened via the sqlite
+** handle is passed a pointer to sqlite.busyHandler. The busy-handler
+** callback is currently invoked only from within pager.c.
+*/
+typedef struct BusyHandler BusyHandler;
+struct BusyHandler {
+ int (*xFunc)(void *,int); /* The busy callback */
+ void *pArg; /* First arg to busy callback */
+};
+
+/*
+** Defer sourcing vdbe.h and btree.h until after the "u8" and
+** "BusyHandler typedefs.
+*/
+#include "vdbe.h"
+#include "btree.h"
+
+/*
+** This macro casts a pointer to an integer. Useful for doing
+** pointer arithmetic.
+*/
+#define Addr(X) ((uptr)X)
+
+/*
+** If memory allocation problems are found, recompile with
+**
+** -DSQLITE_DEBUG=1
+**
+** to enable some sanity checking on malloc() and free(). To
+** check for memory leaks, recompile with
+**
+** -DSQLITE_DEBUG=2
+**
+** and a line of text will be written to standard error for
+** each malloc() and free(). This output can be analyzed
+** by an AWK script to determine if there are any leaks.
+*/
+#ifdef SQLITE_MEMDEBUG
+# define sqliteMalloc(X) sqlite3Malloc_(X,1,__FILE__,__LINE__)
+# define sqliteMallocRaw(X) sqlite3Malloc_(X,0,__FILE__,__LINE__)
+# define sqliteFree(X) sqlite3Free_(X,__FILE__,__LINE__)
+# define sqliteRealloc(X,Y) sqlite3Realloc_(X,Y,__FILE__,__LINE__)
+# define sqliteStrDup(X) sqlite3StrDup_(X,__FILE__,__LINE__)
+# define sqliteStrNDup(X,Y) sqlite3StrNDup_(X,Y,__FILE__,__LINE__)
+#else
+# define sqliteFree sqlite3FreeX
+# define sqliteMalloc sqlite3Malloc
+# define sqliteMallocRaw sqlite3MallocRaw
+# define sqliteRealloc sqlite3Realloc
+# define sqliteStrDup sqlite3StrDup
+# define sqliteStrNDup sqlite3StrNDup
+#endif
+
+/*
+** This variable gets set if malloc() ever fails. After it gets set,
+** the SQLite library shuts down permanently.
+*/
+extern int sqlite3_malloc_failed;
+
+/*
+** The following global variables are used for testing and debugging
+** only. They only work if SQLITE_DEBUG is defined.
+*/
+#ifdef SQLITE_MEMDEBUG
+extern int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */
+extern int sqlite3_nFree; /* Number of sqliteFree() calls */
+extern int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */
+extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
+#endif
+
+/*
+** Name of the master database table. The master database table
+** is a special table that holds the names and attributes of all
+** user tables and indices.
+*/
+#define MASTER_NAME "sqlite_master"
+#define TEMP_MASTER_NAME "sqlite_temp_master"
+
+/*
+** The root-page of the master database table.
+*/
+#define MASTER_ROOT 1
+
+/*
+** The name of the schema table.
+*/
+#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)
+
+/*
+** A convenience macro that returns the number of elements in
+** an array.
+*/
+#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
+
+/*
+** Forward references to structures
+*/
+typedef struct Column Column;
+typedef struct Table Table;
+typedef struct Index Index;
+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 KeyClass KeyClass;
+typedef struct CollSeq CollSeq;
+typedef struct KeyInfo KeyInfo;
+typedef struct NameContext NameContext;
+
+/*
+** Each database file to be accessed by the system is an instance
+** of the following structure. There are normally two of these structures
+** in the sqlite.aDb[] array. aDb[0] is the main database file and
+** aDb[1] is the database file used to hold temporary tables. Additional
+** databases may be attached.
+*/
+struct Db {
+ char *zName; /* Name of this database */
+ Btree *pBt; /* The B*Tree structure for this database file */
+ int schema_cookie; /* Database schema version number for this file */
+ Hash tblHash; /* All tables indexed by name */
+ Hash idxHash; /* All (named) indices indexed by name */
+ Hash trigHash; /* All triggers indexed by name */
+ Hash aFKey; /* Foreign keys indexed by to-table */
+ u16 flags; /* Flags associated with this database */
+ u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
+ u8 safety_level; /* How aggressive at synching data to disk */
+ int cache_size; /* Number of pages to use in the cache */
+ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */
+ void *pAux; /* Auxiliary data. Usually NULL */
+ void (*xFreeAux)(void*); /* Routine to free pAux */
+};
+
+/*
+** These macros can be used to test, set, or clear bits in the
+** Db.flags field.
+*/
+#define DbHasProperty(D,I,P) (((D)->aDb[I].flags&(P))==(P))
+#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].flags&(P))!=0)
+#define DbSetProperty(D,I,P) (D)->aDb[I].flags|=(P)
+#define DbClearProperty(D,I,P) (D)->aDb[I].flags&=~(P)
+
+/*
+** Allowed values for the DB.flags field.
+**
+** The DB_SchemaLoaded flag is set after the database schema has been
+** read into internal hash tables.
+**
+** DB_UnresetViews means that one or more views have column names that
+** have been filled out. If the schema changes, these column names might
+** changes and so the view will need to be reset.
+*/
+#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
+#define DB_UnresetViews 0x0002 /* Some views have defined column names */
+
+#define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
+
+/*
+** Each database is an instance of the following structure.
+**
+** The sqlite.lastRowid records the last insert rowid generated by an
+** insert statement. Inserts on views do not affect its value. Each
+** trigger has its own context, so that lastRowid can be updated inside
+** triggers as usual. The previous value will be restored once the trigger
+** exits. Upon entering a before or instead of trigger, lastRowid is no
+** longer (since after version 2.8.12) reset to -1.
+**
+** The sqlite.nChange does not count changes within triggers and keeps no
+** context. It is reset at start of sqlite3_exec.
+** The sqlite.lsChange represents the number of changes made by the last
+** insert, update, or delete statement. It remains constant throughout the
+** length of a statement and is then updated by OP_SetCounts. It keeps a
+** context stack just like lastRowid so that the count of changes
+** within a trigger is not seen outside the trigger. Changes to views do not
+** affect the value of lsChange.
+** The sqlite.csChange keeps track of the number of current changes (since
+** the last statement) and is used to update sqlite_lsChange.
+**
+** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
+** store the most recent error code and, if applicable, string. The
+** internal function sqlite3Error() is used to set these variables
+** consistently.
+*/
+struct sqlite3 {
+ int nDb; /* Number of backends currently in use */
+ Db *aDb; /* All backends */
+ int flags; /* Miscellanous flags. See below */
+ int errCode; /* Most recent error code (SQLITE_*) */
+ u8 enc; /* Text encoding for this database. */
+ u8 autoCommit; /* The auto-commit flag. */
+ u8 file_format; /* What file format version is this database? */
+ u8 temp_store; /* 1: file 2: memory 0: default */
+ int nTable; /* Number of tables in the database */
+ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
+ i64 lastRowid; /* ROWID of most recent insert (see above) */
+ i64 priorNewRowid; /* Last randomly generated ROWID */
+ int magic; /* Magic number for detect library misuse */
+ int nChange; /* Value returned by sqlite3_changes() */
+ int nTotalChange; /* Value returned by sqlite3_total_changes() */
+ struct sqlite3InitInfo { /* Information used during initialization */
+ int iDb; /* When back is being initialized */
+ int newTnum; /* Rootpage of table being initialized */
+ u8 busy; /* TRUE if currently initializing */
+ } init;
+ struct Vdbe *pVdbe; /* List of active virtual machines */
+ int activeVdbeCnt; /* Number of vdbes currently executing */
+ void (*xTrace)(void*,const char*); /* Trace function */
+ void *pTraceArg; /* Argument to the trace function */
+ void *pCommitArg; /* Argument to xCommitCallback() */
+ int (*xCommitCallback)(void*);/* Invoked at every commit. */
+ void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
+ void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
+ void *pCollNeededArg;
+ sqlite3_value *pValue; /* Value used for transient conversions */
+ sqlite3_value *pErr; /* Most recent error message */
+ char *zErrMsg; /* Most recent error message (UTF-8 encoded) */
+ char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
+ /* Access authorization function */
+ void *pAuthArg; /* 1st argument to the access auth function */
+#endif
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ int (*xProgress)(void *); /* The progress callback */
+ void *pProgressArg; /* Argument to the progress callback */
+ int nProgressOps; /* Number of opcodes for progress callback */
+#endif
+#ifndef SQLITE_OMIT_GLOBALRECOVER
+ sqlite3 *pNext; /* Linked list of open db handles. */
+#endif
+ Hash aFunc; /* All functions that can be in SQL exprs */
+ Hash aCollSeq; /* All collating sequences */
+ BusyHandler busyHandler; /* Busy callback */
+ int busyTimeout; /* Busy handler timeout, in msec */
+ Db aDbStatic[2]; /* Static space for the 2 default backends */
+#ifdef SQLITE_SSE
+ sqlite3_stmt *pFetch; /* Used by SSE to fetch stored statements */
+#endif
+};
+
+/*
+** Possible values for the sqlite.flags and or Db.flags fields.
+**
+** On sqlite.flags, the SQLITE_InTrans value means that we have
+** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement
+** transaction is active on that particular database file.
+*/
+#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
+#define SQLITE_Initialized 0x00000002 /* True after initialization */
+#define SQLITE_Interrupt 0x00000004 /* Cancel current operation */
+#define SQLITE_InTrans 0x00000008 /* True if in a transaction */
+#define SQLITE_InternChanges 0x00000010 /* Uncommitted Hash table changes */
+#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
+#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
+#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
+ /* DELETE, or UPDATE and return */
+ /* the count using a callback. */
+#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
+ /* result set is empty */
+#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */
+#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */
+#define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when
+ ** accessing read-only databases */
+
+/*
+** Possible values for the sqlite.magic field.
+** The numbers are obtained at random and have no special meaning, other
+** than being distinct from one another.
+*/
+#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */
+#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */
+#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */
+#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */
+
+/*
+** Each SQL function is defined by an instance of the following
+** structure. A pointer to this structure is stored in the sqlite.aFunc
+** hash table. When multiple functions have the same name, the hash table
+** 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 */
+ u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
+ 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 */
+};
+
+/*
+** information about each column of an SQL table is held in an instance
+** of this structure.
+*/
+struct Column {
+ char *zName; /* Name of this column */
+ Expr *pDflt; /* Default value of this column */
+ char *zType; /* Data type for this column */
+ CollSeq *pColl; /* Collating sequence. If NULL, use the default */
+ u8 notNull; /* True if there is a NOT NULL constraint */
+ u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */
+ char affinity; /* One of the SQLITE_AFF_... values */
+};
+
+/*
+** A "Collating Sequence" is defined by an instance of the following
+** structure. Conceptually, a collating sequence consists of a name and
+** a comparison routine that defines the order of that sequence.
+**
+** There may two seperate implementations of the collation function, one
+** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
+** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
+** native byte order. When a collation sequence is invoked, SQLite selects
+** the version that will require the least expensive encoding
+** transalations, if any.
+**
+** The CollSeq.pUser member variable is an extra parameter that passed in
+** as the first argument to the UTF-8 comparison function, xCmp.
+** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
+** xCmp16.
+**
+** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
+** collating sequence is undefined. Indices built on an undefined
+** collating sequence may not be read or written.
+*/
+struct CollSeq {
+ char *zName; /* Name of the collating sequence, UTF-8 encoded */
+ u8 enc; /* Text encoding handled by xCmp() */
+ void *pUser; /* First argument to xCmp() */
+ int (*xCmp)(void*,int, const void*, int, const void*);
+};
+
+/*
+** A sort order can be either ASC or DESC.
+*/
+#define SQLITE_SO_ASC 0 /* Sort in ascending order */
+#define SQLITE_SO_DESC 1 /* Sort in ascending order */
+
+/*
+** Column affinity types.
+*/
+#define SQLITE_AFF_INTEGER 'i'
+#define SQLITE_AFF_NUMERIC 'n'
+#define SQLITE_AFF_TEXT 't'
+#define SQLITE_AFF_NONE 'o'
+
+
+/*
+** Each SQL table is represented in memory by an instance of the
+** following structure.
+**
+** Table.zName is the name of the table. The case of the original
+** CREATE TABLE statement is stored, but case is not significant for
+** comparisons.
+**
+** Table.nCol is the number of columns in this table. Table.aCol is a
+** pointer to an array of Column structures, one for each column.
+**
+** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
+** the column that is that key. Otherwise Table.iPKey is negative. Note
+** that the datatype of the PRIMARY KEY must be INTEGER for this field to
+** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
+** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
+** is generated for each row of the table. Table.hasPrimKey is true if
+** the table has any PRIMARY KEY, INTEGER or otherwise.
+**
+** Table.tnum is the page number for the root BTree page of the table in the
+** database file. If Table.iDb is the index of the database table backend
+** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
+** holds temporary tables and indices. If Table.isTransient
+** is true, then the table is stored in a file that is automatically deleted
+** when the VDBE cursor to the table is closed. In this case Table.tnum
+** refers VDBE cursor number that holds the table open, not to the root
+** page number. Transient tables are used to hold the results of a
+** sub-query that appears instead of a real table name in the FROM clause
+** of a SELECT statement.
+*/
+struct Table {
+ char *zName; /* Name of the table */
+ int nCol; /* Number of columns in this table */
+ Column *aCol; /* Information about each column */
+ int iPKey; /* If not less then 0, use aCol[iPKey] as the primary key */
+ Index *pIndex; /* List of SQL indexes on this table. */
+ int tnum; /* Root BTree node for this table (see note above) */
+ Select *pSelect; /* NULL for tables. Points to definition if a view. */
+ u8 readOnly; /* True if this table should not be written by the user */
+ u8 iDb; /* Index into sqlite.aDb[] of the backend for this table */
+ u8 isTransient; /* True if automatically deleted when VDBE finishes */
+ u8 hasPrimKey; /* True if there exists a primary key */
+ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
+ u8 autoInc; /* True if the integer primary key is autoincrement */
+ int nRef; /* Number of pointers to this Table */
+ Trigger *pTrigger; /* List of SQL triggers on this table */
+ FKey *pFKey; /* Linked list of all foreign keys in this table */
+ char *zColAff; /* String defining the affinity of each column */
+#ifndef SQLITE_OMIT_ALTERTABLE
+ int addColOffset; /* Offset in CREATE TABLE statement to add a new column */
+#endif
+};
+
+/*
+** Each foreign key constraint is an instance of the following structure.
+**
+** A foreign key is associated with two tables. The "from" table is
+** the table that contains the REFERENCES clause that creates the foreign
+** key. The "to" table is the table that is named in the REFERENCES clause.
+** Consider this example:
+**
+** CREATE TABLE ex1(
+** a INTEGER PRIMARY KEY,
+** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x)
+** );
+**
+** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
+**
+** Each REFERENCES clause generates an instance of the following structure
+** which is attached to the from-table. The to-table need not exist when
+** the from-table is created. The existance of the to-table is not checked
+** until an attempt is made to insert data into the from-table.
+**
+** The sqlite.aFKey hash table stores pointers to this structure
+** given the name of a to-table. For each to-table, all foreign keys
+** associated with that table are on a linked list using the FKey.pNextTo
+** field.
+*/
+struct FKey {
+ Table *pFrom; /* The table that constains the REFERENCES clause */
+ FKey *pNextFrom; /* Next foreign key in pFrom */
+ char *zTo; /* Name of table that the key points to */
+ FKey *pNextTo; /* Next foreign key that points to zTo */
+ int nCol; /* Number of columns in this key */
+ struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
+ int iFrom; /* Index of column in pFrom */
+ char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */
+ } *aCol; /* One entry for each of nCol column s */
+ u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
+ u8 updateConf; /* How to resolve conflicts that occur on UPDATE */
+ u8 deleteConf; /* How to resolve conflicts that occur on DELETE */
+ u8 insertConf; /* How to resolve conflicts that occur on INSERT */
+};
+
+/*
+** SQLite supports many different ways to resolve a contraint
+** error. ROLLBACK processing means that a constraint violation
+** causes the operation in process to fail and for the current transaction
+** to be rolled back. ABORT processing means the operation in process
+** fails and any prior changes from that one operation are backed out,
+** but the transaction is not rolled back. FAIL processing means that
+** the operation in progress stops and returns an error code. But prior
+** changes due to the same operation are not backed out and no rollback
+** occurs. IGNORE means that the particular row that caused the constraint
+** error is not inserted or updated. Processing continues and no error
+** is returned. REPLACE means that preexisting database rows that caused
+** a UNIQUE constraint violation are removed so that the new insert or
+** update can proceed. Processing continues and no error is reported.
+**
+** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys.
+** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
+** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign
+** key is set to NULL. CASCADE means that a DELETE or UPDATE of the
+** referenced table row is propagated into the row that holds the
+** foreign key.
+**
+** The following symbolic values are used to record which type
+** of action to take.
+*/
+#define OE_None 0 /* There is no constraint to check */
+#define OE_Rollback 1 /* Fail the operation and rollback the transaction */
+#define OE_Abort 2 /* Back out changes but do no rollback transaction */
+#define OE_Fail 3 /* Stop the operation but leave all prior changes */
+#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */
+#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */
+
+#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
+#define OE_SetNull 7 /* Set the foreign key value to NULL */
+#define OE_SetDflt 8 /* Set the foreign key value to its default */
+#define OE_Cascade 9 /* Cascade the changes */
+
+#define OE_Default 99 /* Do whatever the default action is */
+
+
+/*
+** An instance of the following structure is passed as the first
+** argument to sqlite3VdbeKeyCompare and is used to control the
+** comparison of the two index keys.
+**
+** If the KeyInfo.incrKey value is true and the comparison would
+** otherwise be equal, then return a result as if the second key
+** were larger.
+*/
+struct KeyInfo {
+ u8 enc; /* Text encoding - one of the TEXT_Utf* values */
+ u8 incrKey; /* Increase 2nd key by epsilon before comparison */
+ int nField; /* Number of entries in aColl[] */
+ u8 *aSortOrder; /* If defined an aSortOrder[i] is true, sort DESC */
+ CollSeq *aColl[1]; /* Collating sequence for each term of the key */
+};
+
+/*
+** Each SQL index is represented in memory by an
+** instance of the following structure.
+**
+** The columns of the table that are to be indexed are described
+** by the aiColumn[] field of this structure. For example, suppose
+** we have the following table and index:
+**
+** CREATE TABLE Ex1(c1 int, c2 int, c3 text);
+** CREATE INDEX Ex2 ON Ex1(c3,c1);
+**
+** In the Table structure describing Ex1, nCol==3 because there are
+** three columns in the table. In the Index structure describing
+** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
+** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
+** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
+** The second column to be indexed (c1) has an index of 0 in
+** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
+**
+** The Index.onError field determines whether or not the indexed columns
+** must be unique and what to do if they are not. When Index.onError=OE_None,
+** it means this is not a unique index. Otherwise it is a unique index
+** and the value of Index.onError indicate the which conflict resolution
+** algorithm to employ whenever an attempt is made to insert a non-unique
+** element.
+*/
+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 */
+ 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 */
+ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
+ u8 iDb; /* Index in sqlite.aDb[] of where this index is stored */
+ char *zColAff; /* String defining the affinity of each column */
+ Index *pNext; /* The next index associated with the same table */
+ KeyInfo keyInfo; /* Info on how to order keys. MUST BE LAST */
+};
+
+/*
+** Each token coming out of the lexer is an instance of
+** this structure. Tokens are also used as part of an expression.
+**
+** Note if Token.z==0 then Token.dyn and Token.n are undefined and
+** may contain random values. Do not make any assuptions about Token.dyn
+** and Token.n when Token.z==0.
+*/
+struct Token {
+ const unsigned char *z; /* Text of the token. Not NULL-terminated! */
+ unsigned dyn : 1; /* True for malloced memory, false for static */
+ unsigned n : 31; /* Number of characters in this token */
+};
+
+/*
+** Each node of an expression in the parse tree is an instance
+** of this structure.
+**
+** Expr.op is the opcode. The integer parser token codes are reused
+** as opcodes here. For example, the parser defines TK_GE to be an integer
+** code representing the ">=" operator. This same integer code is reused
+** to represent the greater-than-or-equal-to operator in the expression
+** tree.
+**
+** Expr.pRight and Expr.pLeft are subexpressions. Expr.pList is a list
+** of argument if the expression is a function.
+**
+** Expr.token is the operator token for this node. For some expressions
+** that have subexpressions, Expr.token can be the complete text that gave
+** rise to the Expr. In the latter case, the token is marked as being
+** a compound token.
+**
+** An expression of the form ID or ID.ID refers to a column in a table.
+** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is
+** the integer cursor number of a VDBE cursor pointing to that table and
+** Expr.iColumn is the column number for the specific column. If the
+** expression is used as a result in an aggregate SELECT, then the
+** value is also stored in the Expr.iAgg column in the aggregate so that
+** it can be accessed after all aggregates are computed.
+**
+** If the expression is a function, the Expr.iTable is an integer code
+** representing which function. If the expression is an unbound variable
+** marker (a question mark character '?' in the original SQL) then the
+** Expr.iTable holds the index number for that variable.
+**
+** If the expression is a subquery then Expr.iColumn holds an integer
+** register number containing the result of the subquery. If the
+** subquery gives a constant result, then iTable is -1. If the subquery
+** gives a different answer at different times during statement processing
+** then iTable is the address of a subroutine that computes the subquery.
+**
+** The Expr.pSelect field points to a SELECT statement. The SELECT might
+** be the right operand of an IN operator. Or, if a scalar SELECT appears
+** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
+** operand.
+**
+** If the Expr is of type OP_Column, and the table it is selecting from
+** is a disk table or the "old.*" pseudo-table, then pTab points to the
+** corresponding table definition.
+*/
+struct Expr {
+ u8 op; /* Operation performed by this node */
+ char affinity; /* The affinity of the column or 0 if not a column */
+ u8 iDb; /* Database referenced by this expression */
+ u8 flags; /* Various flags. See below */
+ CollSeq *pColl; /* The collation type of the column or 0 */
+ Expr *pLeft, *pRight; /* Left and right subnodes */
+ ExprList *pList; /* A list of expressions used as function arguments
+ ** or in "<expr> IN (<expr-list)" */
+ Token token; /* An operand token */
+ Token span; /* Complete text of the expression */
+ int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the
+ ** iColumn-th field of the iTable-th table. */
+ int iAgg; /* When op==TK_COLUMN and pParse->fillAgg==FALSE, pull
+ ** result from the iAgg-th element of the aggregator */
+ int iAggCtx; /* The value to pass as P1 of OP_AggGet. */
+ Select *pSelect; /* When the expression is a sub-select. Also the
+ ** right side of "<expr> IN (<select>)" */
+ Table *pTab; /* Table for OP_Column expressions. */
+};
+
+/*
+** 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 */
+
+/*
+** These macros can be used to test, set, or clear bits in the
+** Expr.flags field.
+*/
+#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
+#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
+#define ExprSetProperty(E,P) (E)->flags|=(P)
+#define ExprClearProperty(E,P) (E)->flags&=~(P)
+
+/*
+** A list of expressions. Each expression may optionally have a
+** name. An expr/name combination can be used in several ways, such
+** as the list of "expr AS ID" fields following a "SELECT" or in the
+** list of "ID = expr" items in an UPDATE. A list of expressions can
+** also be used as the argument to a function, in which case the a.zName
+** field is not used.
+*/
+struct ExprList {
+ int nExpr; /* Number of expressions on the list */
+ int nAlloc; /* Number of entries allocated below */
+ struct ExprList_item {
+ Expr *pExpr; /* The list of expressions */
+ char *zName; /* Token associated with this expression */
+ u8 sortOrder; /* 1 for DESC or 0 for ASC */
+ u8 isAgg; /* True if this is an aggregate like count(*) */
+ u8 done; /* A flag to indicate when processing is finished */
+ } *a; /* One entry for each expression */
+};
+
+/*
+** An instance of this structure can hold a simple list of identifiers,
+** such as the list "a,b,c" in the following statements:
+**
+** INSERT INTO t(a,b,c) VALUES ...;
+** CREATE INDEX idx ON t(a,b,c);
+** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
+**
+** The IdList.a.idx field is used when the IdList represents the list of
+** column names after a table name in an INSERT statement. In the statement
+**
+** INSERT INTO t(a,b,c) ...
+**
+** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
+*/
+struct IdList {
+ int nId; /* Number of identifiers on the list */
+ int nAlloc; /* Number of entries allocated for a[] below */
+ struct IdList_item {
+ char *zName; /* Name of the identifier */
+ int idx; /* Index in some Table.aCol[] of a column named zName */
+ } *a;
+};
+
+/*
+** The bitmask datatype defined below is used for various optimizations.
+*/
+typedef unsigned int Bitmask;
+
+/*
+** The following structure describes the FROM clause of a SELECT statement.
+** Each table or subquery in the FROM clause is a separate element of
+** the SrcList.a[] array.
+**
+** With the addition of multiple database support, the following structure
+** can also be used to describe a particular table such as the table that
+** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL,
+** such a table must be a simple name: ID. But in SQLite, the table can
+** now be identified by a database name, a dot, then the table name: ID.ID.
+*/
+struct SrcList {
+ i16 nSrc; /* Number of tables or subqueries in the FROM clause */
+ i16 nAlloc; /* Number of entries allocated in a[] below */
+ struct SrcList_item {
+ char *zDatabase; /* Name of database holding this table */
+ char *zName; /* Name of the table */
+ 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 */
+ Expr *pOn; /* The ON clause of a join */
+ IdList *pUsing; /* The USING clause of a join */
+ Bitmask colUsed; /* Bit N (1<<N) set if column N or pTab is used */
+ } a[1]; /* One entry for each identifier on the list */
+};
+
+/*
+** Permitted values of the SrcList.a.jointype field
+*/
+#define JT_INNER 0x0001 /* Any kind of inner or cross join */
+#define JT_NATURAL 0x0002 /* True for a "natural" join */
+#define JT_LEFT 0x0004 /* Left outer join */
+#define JT_RIGHT 0x0008 /* Right outer join */
+#define JT_OUTER 0x0010 /* The "OUTER" keyword is present */
+#define JT_ERROR 0x0020 /* unknown or unsupported join type */
+
+/*
+** For each nested loop in a WHERE clause implementation, the WhereInfo
+** structure contains a single instance of this structure. This structure
+** is intended to be private the the where.c module and should not be
+** access or modified by other modules.
+*/
+struct WhereLevel {
+ int iMem; /* Memory cell used by this level */
+ Index *pIdx; /* Index used. NULL if no index */
+ int iTabCur; /* The VDBE cursor used to access the table */
+ int iIdxCur; /* The VDBE cursor used to acesss pIdx */
+ int score; /* How well this index scored */
+ int brk; /* Jump here to break out of the loop */
+ int cont; /* Jump here to continue with the next loop cycle */
+ int op, p1, p2; /* Opcode used to terminate the loop */
+ int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
+ int top; /* First instruction of interior of the loop */
+ int inOp, inP1, inP2;/* Opcode used to implement an IN operator */
+ int bRev; /* Do the scan in the reverse direction */
+};
+
+/*
+** The WHERE clause processing routine has two halves. The
+** first part does the start of the WHERE loop and the second
+** half does the tail of the WHERE loop. An instance of
+** this structure is returned by the first half and passed
+** into the second half to give some continuity.
+*/
+struct WhereInfo {
+ Parse *pParse;
+ SrcList *pTabList; /* List of tables in the join */
+ int iTop; /* The very beginning of the WHERE loop */
+ int iContinue; /* Jump here to continue with next record */
+ int iBreak; /* Jump here to break out of the loop */
+ int nLevel; /* Number of nested loop */
+ WhereLevel a[1]; /* Information about each nest loop in the WHERE */
+};
+
+/*
+** A NameContext defines a context in which to resolve table and column
+** names. The context consists of a list of tables (the pSrcList) field and
+** a list of named expression (pEList). The named expression list may
+** be NULL. The pSrc corresponds to the FROM clause of a SELECT or
+** to the table being operated on by INSERT, UPDATE, or DELETE. The
+** pEList corresponds to the result set of a SELECT and is NULL for
+** other statements.
+**
+** NameContexts can be nested. When resolving names, the inner-most
+** context is searched first. If no match is found, the next outer
+** context is checked. If there is still no match, the next context
+** is checked. This process continues until either a match is found
+** or all contexts are check. When a match is found, the nRef member of
+** the context containing the match is incremented.
+**
+** Each subquery gets a new NameContext. The pNext field points to the
+** NameContext in the parent query. Thus the process of scanning the
+** NameContext list corresponds to searching through successively outer
+** subqueries looking for a match.
+*/
+struct NameContext {
+ Parse *pParse; /* The parser */
+ SrcList *pSrcList; /* One or more tables used to resolve names */
+ ExprList *pEList; /* Optional list of named expressions */
+ int nRef; /* Number of names resolved by this context */
+ int nErr; /* Number of errors encountered while resolving names */
+ u8 allowAgg; /* Aggregate functions allowed here */
+ u8 hasAgg;
+ int nDepth; /* Depth of subquery recursion. 1 for no recursion */
+ NameContext *pNext; /* Next outer name context. NULL for outermost */
+};
+
+/*
+** An instance of the following structure contains all information
+** needed to generate code for a single SELECT statement.
+**
+** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
+** If there is a LIMIT clause, the parser sets nLimit to the value of the
+** limit and nOffset to the value of the offset (or 0 if there is not
+** offset). But later on, nLimit and nOffset become the memory locations
+** in the VDBE that record the limit and offset counters.
+*/
+struct Select {
+ ExprList *pEList; /* The fields of the result */
+ u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
+ u8 isDistinct; /* True if the DISTINCT keyword is present */
+ SrcList *pSrc; /* The FROM clause */
+ Expr *pWhere; /* The WHERE clause */
+ ExprList *pGroupBy; /* The GROUP BY clause */
+ Expr *pHaving; /* The HAVING clause */
+ ExprList *pOrderBy; /* The ORDER BY clause */
+ Select *pPrior; /* Prior select in a compound select statement */
+ Expr *pLimit; /* LIMIT expression. NULL means not used. */
+ Expr *pOffset; /* OFFSET expression. NULL means not used. */
+ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
+ IdList **ppOpenTemp; /* OP_OpenTemp addresses used by multi-selects */
+ u8 isResolved; /* True once sqlite3SelectResolve() has run. */
+ u8 isAgg; /* True if this is an aggregate query */
+};
+
+/*
+** The results of a select can be distributed in several ways.
+*/
+#define SRT_Callback 1 /* Invoke a callback with each row of result */
+#define SRT_Mem 2 /* Store result in a memory cell */
+#define SRT_Set 3 /* Store result as unique keys in a table */
+#define SRT_Union 5 /* Store result as keys in a table */
+#define SRT_Except 6 /* Remove result from a UNION table */
+#define SRT_Table 7 /* Store result as data with a unique key */
+#define SRT_TempTable 8 /* Store result in a trasient table */
+#define SRT_Discard 9 /* Do not save the results anywhere */
+#define SRT_Sorter 10 /* Store results in the sorter */
+#define SRT_Subroutine 11 /* Call a subroutine to handle results */
+#define SRT_Exists 12 /* Put 0 or 1 in a memory cell */
+
+/*
+** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
+** we have to do some additional analysis of expressions. An instance
+** of the following structure holds information about a single subexpression
+** somewhere in the SELECT statement. An array of these structures holds
+** all the information we need to generate code for aggregate
+** expressions.
+**
+** Note that when analyzing a SELECT containing aggregates, both
+** non-aggregate field variables and aggregate functions are stored
+** in the AggExpr array of the Parser structure.
+**
+** The pExpr field points to an expression that is part of either the
+** field list, the GROUP BY clause, the HAVING clause or the ORDER BY
+** clause. The expression will be freed when those clauses are cleaned
+** up. Do not try to delete the expression attached to AggExpr.pExpr.
+**
+** If AggExpr.pExpr==0, that means the expression is "count(*)".
+*/
+struct AggExpr {
+ int isAgg; /* if TRUE contains an aggregate function */
+ Expr *pExpr; /* The expression */
+ FuncDef *pFunc; /* Information about the aggregate function */
+};
+
+/*
+** An SQL parser context. A copy of this structure is passed through
+** the parser and down into all the parser action routine in order to
+** carry around information that is global to the entire parse.
+**
+** The structure is divided into two parts. When the parser and code
+** generate call themselves recursively, the first part of the structure
+** is constant but the second part is reset at the beginning and end of
+** each recursion.
+*/
+struct Parse {
+ sqlite3 *db; /* The main database structure */
+ int rc; /* Return code from execution */
+ char *zErrMsg; /* An error message */
+ Vdbe *pVdbe; /* An engine for executing database bytecode */
+ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */
+ u8 nameClash; /* A permanent table name clashes with temp table name */
+ u8 checkSchema; /* Causes schema cookie check after an error */
+ u8 nested; /* Number of nested calls to the parser/code generator */
+ u8 fillAgg; /* If true, ignore the Expr.iAgg field. Normally false */
+ int nErr; /* Number of errors seen */
+ int nTab; /* Number of previously allocated VDBE cursors */
+ int nMem; /* Number of memory cells used so far */
+ int nSet; /* Number of sets used so far */
+ u32 writeMask; /* Start a write transaction on these databases */
+ u32 cookieMask; /* Bitmask of schema verified databases */
+ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
+ int cookieValue[MAX_ATTACHED+2]; /* Values of cookies to verify */
+
+ /* Above is constant between recursions. Below is reset before and after
+ ** each recursion */
+
+ int nVar; /* Number of '?' variables seen in the SQL so far */
+ int nVarExpr; /* Number of used slots in apVarExpr[] */
+ int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */
+ Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */
+ u8 explain; /* True if the EXPLAIN flag is found on the query */
+ Token sErrToken; /* The token at which the error occurred */
+ Token sNameToken; /* Token with unqualified schema object name */
+ Token sLastToken; /* The last token parsed */
+ const char *zSql; /* All SQL text */
+ const char *zTail; /* All SQL text past the last semicolon parsed */
+ Table *pNewTable; /* A table being constructed by CREATE TABLE */
+ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
+ TriggerStack *trigStack; /* Trigger actions being coded */
+ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
+ int nAgg; /* Number of aggregate expressions */
+ AggExpr *aAgg; /* An array of aggregate expressions */
+ int nMaxDepth; /* Maximum depth of subquery recursion */
+};
+
+/*
+** An instance of the following structure can be declared on a stack and used
+** to save the Parse.zAuthContext value so that it can be restored later.
+*/
+struct AuthContext {
+ const char *zAuthContext; /* Put saved Parse.zAuthContext here */
+ Parse *pParse; /* The Parse structure */
+};
+
+/*
+** Bitfield flags for P2 value in OP_Insert and OP_Delete
+*/
+#define OPFLAG_NCHANGE 1 /* Set to update db->nChange */
+#define OPFLAG_LASTROWID 2 /* Set to update db->lastRowid */
+
+/*
+ * Each trigger present in the database schema is stored as an instance of
+ * struct Trigger.
+ *
+ * Pointers to instances of struct Trigger are stored in two ways.
+ * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
+ * database). This allows Trigger structures to be retrieved by name.
+ * 2. All triggers associated with a single table form a linked list, using the
+ * pNext member of struct Trigger. A pointer to the first element of the
+ * linked list is stored as the "pTrigger" member of the associated
+ * struct Table.
+ *
+ * The "step_list" member points to the first element of a linked list
+ * containing the SQL statements specified as the trigger program.
+ */
+struct Trigger {
+ char *name; /* The name of the trigger */
+ char *table; /* The table or view to which the trigger applies */
+ u8 iDb; /* Database containing this trigger */
+ u8 iTabDb; /* Database containing Trigger.table */
+ u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
+ u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
+ Expr *pWhen; /* The WHEN clause of the expresion (may be NULL) */
+ IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
+ the <column-list> is stored here */
+ int foreach; /* One of TK_ROW or TK_STATEMENT */
+ Token nameToken; /* Token containing zName. Use during parsing only */
+
+ TriggerStep *step_list; /* Link list of trigger program steps */
+ Trigger *pNext; /* Next trigger associated with the table */
+};
+
+/*
+** A trigger is either a BEFORE or an AFTER trigger. The following constants
+** determine which.
+**
+** If there are multiple triggers, you might of some BEFORE and some AFTER.
+** In that cases, the constants below can be ORed together.
+*/
+#define TRIGGER_BEFORE 1
+#define TRIGGER_AFTER 2
+
+/*
+ * An instance of struct TriggerStep is used to store a single SQL statement
+ * that is a part of a trigger-program.
+ *
+ * Instances of struct TriggerStep are stored in a singly linked list (linked
+ * using the "pNext" member) referenced by the "step_list" member of the
+ * associated struct Trigger instance. The first element of the linked list is
+ * the first step of the trigger-program.
+ *
+ * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
+ * "SELECT" statement. The meanings of the other members is determined by the
+ * value of "op" as follows:
+ *
+ * (op == TK_INSERT)
+ * orconf -> stores the ON CONFLICT algorithm
+ * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
+ * this stores a pointer to the SELECT statement. Otherwise NULL.
+ * target -> A token holding the name of the table to insert into.
+ * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
+ * this stores values to be inserted. Otherwise NULL.
+ * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
+ * statement, then this stores the column-names to be
+ * inserted into.
+ *
+ * (op == TK_DELETE)
+ * target -> A token holding the name of the table to delete from.
+ * pWhere -> The WHERE clause of the DELETE statement if one is specified.
+ * Otherwise NULL.
+ *
+ * (op == TK_UPDATE)
+ * target -> A token holding the name of the table to update rows of.
+ * pWhere -> The WHERE clause of the UPDATE statement if one is specified.
+ * Otherwise NULL.
+ * pExprList -> A list of the columns to update and the expressions to update
+ * them to. See sqlite3Update() documentation of "pChanges"
+ * argument.
+ *
+ */
+struct TriggerStep {
+ int op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
+ int orconf; /* OE_Rollback etc. */
+ Trigger *pTrig; /* The trigger that this step is a part of */
+
+ Select *pSelect; /* Valid for SELECT and sometimes
+ INSERT steps (when pExprList == 0) */
+ Token target; /* Valid for DELETE, UPDATE, INSERT steps */
+ Expr *pWhere; /* Valid for DELETE, UPDATE steps */
+ ExprList *pExprList; /* Valid for UPDATE statements and sometimes
+ INSERT steps (when pSelect == 0) */
+ IdList *pIdList; /* Valid for INSERT statements only */
+
+ TriggerStep * pNext; /* Next in the link-list */
+};
+
+/*
+ * An instance of struct TriggerStack stores information required during code
+ * generation of a single trigger program. While the trigger program is being
+ * coded, its associated TriggerStack instance is pointed to by the
+ * "pTriggerStack" member of the Parse structure.
+ *
+ * The pTab member points to the table that triggers are being coded on. The
+ * newIdx member contains the index of the vdbe cursor that points at the temp
+ * table that stores the new.* references. If new.* references are not valid
+ * for the trigger being coded (for example an ON DELETE trigger), then newIdx
+ * is set to -1. The oldIdx member is analogous to newIdx, for old.* references.
+ *
+ * The ON CONFLICT policy to be used for the trigger program steps is stored
+ * as the orconf member. If this is OE_Default, then the ON CONFLICT clause
+ * specified for individual triggers steps is used.
+ *
+ * struct TriggerStack has a "pNext" member, to allow linked lists to be
+ * constructed. When coding nested triggers (triggers fired by other triggers)
+ * each nested trigger stores its parent trigger's TriggerStack as the "pNext"
+ * pointer. Once the nested trigger has been coded, the pNext value is restored
+ * to the pTriggerStack member of the Parse stucture and coding of the parent
+ * trigger continues.
+ *
+ * Before a nested trigger is coded, the linked list pointed to by the
+ * pTriggerStack is scanned to ensure that the trigger is not about to be coded
+ * recursively. If this condition is detected, the nested trigger is not coded.
+ */
+struct TriggerStack {
+ Table *pTab; /* Table that triggers are currently being coded on */
+ int newIdx; /* Index of vdbe cursor to "new" temp table */
+ int oldIdx; /* Index of vdbe cursor to "old" temp table */
+ int orconf; /* Current orconf policy */
+ int ignoreJump; /* where to jump to for a RAISE(IGNORE) */
+ Trigger *pTrigger; /* The trigger currently being coded */
+ TriggerStack *pNext; /* Next trigger down on the trigger stack */
+};
+
+/*
+** The following structure contains information used by the sqliteFix...
+** routines as they walk the parse tree to make database references
+** explicit.
+*/
+typedef struct DbFixer DbFixer;
+struct DbFixer {
+ Parse *pParse; /* The parsing context. Error messages written here */
+ const char *zDb; /* Make sure all objects are contained in this database */
+ const char *zType; /* Type of the container - used for error messages */
+ const Token *pName; /* Name of the container - used for error messages */
+};
+
+/*
+** A pointer to this structure is used to communicate information
+** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
+*/
+typedef struct {
+ sqlite3 *db; /* The database being initialized */
+ char **pzErrMsg; /* Error message stored here */
+} InitData;
+
+/*
+ * This global flag is set for performance testing of triggers. When it is set
+ * SQLite will perform the overhead of building new and old trigger references
+ * even when no triggers exist
+ */
+extern int sqlite3_always_code_trigger_setup;
+
+/*
+** Internal function prototypes
+*/
+int sqlite3StrICmp(const char *, const char *);
+int sqlite3StrNICmp(const char *, const char *, int);
+int sqlite3HashNoCase(const char *, int);
+int sqlite3IsNumber(const char*, int*, u8);
+int sqlite3Compare(const char *, const char *);
+int sqlite3SortCompare(const char *, const char *);
+void sqlite3RealToSortable(double r, char *);
+#ifdef SQLITE_MEMDEBUG
+ void *sqlite3Malloc_(int,int,char*,int);
+ void sqlite3Free_(void*,char*,int);
+ void *sqlite3Realloc_(void*,int,char*,int);
+ char *sqlite3StrDup_(const char*,char*,int);
+ char *sqlite3StrNDup_(const char*, int,char*,int);
+ void sqlite3CheckMemory(void*,int);
+#else
+ void *sqlite3Malloc(int);
+ void *sqlite3MallocRaw(int);
+ void sqlite3Free(void*);
+ void *sqlite3Realloc(void*,int);
+ char *sqlite3StrDup(const char*);
+ char *sqlite3StrNDup(const char*, int);
+# define sqlite3CheckMemory(a,b)
+# define sqlite3MallocX sqlite3Malloc
+#endif
+void sqlite3FreeX(void*);
+void *sqlite3MallocX(int);
+char *sqlite3MPrintf(const char*, ...);
+char *sqlite3VMPrintf(const char*, va_list);
+void sqlite3DebugPrintf(const char*, ...);
+void *sqlite3TextToPtr(const char*);
+void sqlite3SetString(char **, ...);
+void sqlite3ErrorMsg(Parse*, const char*, ...);
+void sqlite3Dequote(char*);
+int sqlite3KeywordCode(const char*, int);
+int sqlite3RunParser(Parse*, const char*, char **);
+void sqlite3FinishCoding(Parse*);
+Expr *sqlite3Expr(int, Expr*, Expr*, const Token*);
+Expr *sqlite3RegisterExpr(Parse*,Token*);
+Expr *sqlite3ExprAnd(Expr*, Expr*);
+void sqlite3ExprSpan(Expr*,Token*,Token*);
+Expr *sqlite3ExprFunction(ExprList*, Token*);
+void sqlite3ExprAssignVarNumber(Parse*, Expr*);
+void sqlite3ExprDelete(Expr*);
+ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
+void sqlite3ExprListDelete(ExprList*);
+int sqlite3Init(sqlite3*, char**);
+int sqlite3InitCallback(void*, int, char**, char**);
+void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
+void sqlite3ResetInternalSchema(sqlite3*, int);
+void sqlite3BeginParse(Parse*,int);
+void sqlite3RollbackInternalChanges(sqlite3*);
+void sqlite3CommitInternalChanges(sqlite3*);
+Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
+void sqlite3OpenMasterTable(Vdbe *v, int);
+void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
+void sqlite3AddColumn(Parse*,Token*);
+void sqlite3AddNotNull(Parse*, int);
+void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int);
+void sqlite3AddColumnType(Parse*,Token*,Token*);
+void sqlite3AddDefaultValue(Parse*,Expr*);
+void sqlite3AddCollateType(Parse*, const char*, int);
+void sqlite3EndTable(Parse*,Token*,Token*,Select*);
+
+#ifndef SQLITE_OMIT_VIEW
+ void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int);
+ int sqlite3ViewGetColumnNames(Parse*,Table*);
+#else
+# define sqlite3ViewGetColumnNames(A,B) 0
+#endif
+
+void sqlite3DropTable(Parse*, SrcList*, int);
+void sqlite3DeleteTable(sqlite3*, Table*);
+void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
+IdList *sqlite3IdListAppend(IdList*, Token*);
+int sqlite3IdListIndex(IdList*,const char*);
+SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
+void sqlite3SrcListAddAlias(SrcList*, Token*);
+void sqlite3SrcListAssignCursors(Parse*, SrcList*);
+void sqlite3IdListDelete(IdList*);
+void sqlite3SrcListDelete(SrcList*);
+void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
+ Token*);
+void sqlite3DropIndex(Parse*, SrcList*);
+void sqlite3AddKeyType(Vdbe*, ExprList*);
+void sqlite3AddIdxKeyType(Vdbe*, Index*);
+int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
+Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
+ int,Expr*,Expr*);
+void sqlite3SelectDelete(Select*);
+void sqlite3SelectUnbind(Select*);
+Table *sqlite3SrcListLookup(Parse*, SrcList*);
+int sqlite3IsReadOnly(Parse*, Table*, int);
+void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*);
+void sqlite3OpenTable(Vdbe*, int iCur, Table*, int);
+void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
+void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
+WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
+void sqlite3WhereEnd(WhereInfo*);
+void sqlite3ExprCode(Parse*, Expr*);
+void sqlite3ExprCodeAndCache(Parse*, Expr*);
+int sqlite3ExprCodeExprList(Parse*, ExprList*);
+void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
+void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
+void sqlite3NextedParse(Parse*, const char*, ...);
+Table *sqlite3FindTable(sqlite3*,const char*, const char*);
+Table *sqlite3LocateTable(Parse*,const char*, const char*);
+Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
+void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
+void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
+void sqlite3Vacuum(Parse*, Token*);
+int sqlite3RunVacuum(char**, sqlite3*);
+char *sqlite3NameFromToken(Token*);
+int sqlite3ExprCheck(Parse*, Expr*, int, int*);
+int sqlite3ExprCompare(Expr*, Expr*);
+int sqliteFuncId(Token*);
+int sqlite3ExprResolveNames(NameContext *, Expr *);
+int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
+Vdbe *sqlite3GetVdbe(Parse*);
+void sqlite3Randomness(int, void*);
+void sqlite3RollbackAll(sqlite3*);
+void sqlite3CodeVerifySchema(Parse*, int);
+void sqlite3BeginTransaction(Parse*, int);
+void sqlite3CommitTransaction(Parse*);
+void sqlite3RollbackTransaction(Parse*);
+int sqlite3ExprIsConstant(Expr*);
+int sqlite3ExprIsInteger(Expr*, int*);
+int sqlite3IsRowid(const char*);
+void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
+void sqlite3GenerateRowIndexDelete(sqlite3*, Vdbe*, Table*, int, char*);
+void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
+void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
+void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
+void sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
+void sqlite3BeginWriteOperation(Parse*, int, int);
+Expr *sqlite3ExprDup(Expr*);
+void sqlite3TokenCopy(Token*, Token*);
+ExprList *sqlite3ExprListDup(ExprList*);
+SrcList *sqlite3SrcListDup(SrcList*);
+IdList *sqlite3IdListDup(IdList*);
+Select *sqlite3SelectDup(Select*);
+FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
+void sqlite3RegisterBuiltinFunctions(sqlite3*);
+void sqlite3RegisterDateTimeFunctions(sqlite3*);
+int sqlite3SafetyOn(sqlite3*);
+int sqlite3SafetyOff(sqlite3*);
+int sqlite3SafetyCheck(sqlite3*);
+void sqlite3ChangeCookie(sqlite3*, Vdbe*, int);
+
+#ifndef SQLITE_OMIT_TRIGGER
+ void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
+ int,Expr*,int);
+ void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
+ void sqlite3DropTrigger(Parse*, SrcList*);
+ void sqlite3DropTriggerPtr(Parse*, Trigger*, int);
+ int sqlite3TriggersExist(Parse*, Table*, int, ExprList*);
+ int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
+ int, int);
+ void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
+ void sqlite3DeleteTriggerStep(TriggerStep*);
+ TriggerStep *sqlite3TriggerSelectStep(Select*);
+ TriggerStep *sqlite3TriggerInsertStep(Token*, IdList*, ExprList*,Select*,int);
+ TriggerStep *sqlite3TriggerUpdateStep(Token*, ExprList*, Expr*, int);
+ TriggerStep *sqlite3TriggerDeleteStep(Token*, Expr*);
+ void sqlite3DeleteTrigger(Trigger*);
+ void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
+#else
+# define sqlite3TriggersExist(A,B,C,D,E,F) 0
+# define sqlite3DeleteTrigger(A)
+# define sqlite3DropTriggerPtr(A,B,C)
+# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
+# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) 0
+#endif
+
+int sqlite3JoinType(Parse*, Token*, Token*, Token*);
+void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
+void sqlite3DeferForeignKey(Parse*, int);
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ void sqlite3AuthRead(Parse*,Expr*,SrcList*);
+ int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
+ void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
+ void sqlite3AuthContextPop(AuthContext*);
+#else
+# define sqlite3AuthRead(a,b,c)
+# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK
+# define sqlite3AuthContextPush(a,b,c)
+# define sqlite3AuthContextPop(a) ((void)(a))
+#endif
+void sqlite3Attach(Parse*, Token*, Token*, int, Token*);
+void sqlite3Detach(Parse*, Token*);
+int sqlite3BtreeFactory(const sqlite3 *db, const char *zFilename,
+ int omitJournal, int nCache, Btree **ppBtree);
+int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
+int sqlite3FixSrcList(DbFixer*, SrcList*);
+int sqlite3FixSelect(DbFixer*, Select*);
+int sqlite3FixExpr(DbFixer*, Expr*);
+int sqlite3FixExprList(DbFixer*, ExprList*);
+int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
+double sqlite3AtoF(const char *z, const char **);
+char *sqlite3_snprintf(int,char*,const char*,...);
+int sqlite3GetInt32(const char *, int*);
+int sqlite3FitsIn64Bits(const char *);
+int sqlite3utf16ByteLen(const void *pData, int nChar);
+int sqlite3utf8CharLen(const char *pData, int nByte);
+int sqlite3ReadUtf8(const unsigned char *);
+int sqlite3PutVarint(unsigned char *, u64);
+int sqlite3GetVarint(const unsigned char *, u64 *);
+int sqlite3GetVarint32(const unsigned char *, u32 *);
+int sqlite3VarintLen(u64 v);
+void sqlite3IndexAffinityStr(Vdbe *, Index *);
+void sqlite3TableAffinityStr(Vdbe *, Table *);
+char sqlite3CompareAffinity(Expr *pExpr, char aff2);
+int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
+char sqlite3ExprAffinity(Expr *pExpr);
+int sqlite3atoi64(const char*, i64*);
+void sqlite3Error(sqlite3*, int, const char*,...);
+void *sqlite3HexToBlob(const char *z);
+int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
+const char *sqlite3ErrStr(int);
+int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
+int sqlite3ReadSchema(Parse *pParse);
+CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
+CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
+CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
+int sqlite3CheckCollSeq(Parse *, CollSeq *);
+int sqlite3CheckIndexCollSeq(Parse *, Index *);
+int sqlite3CheckObjectName(Parse *, const char *);
+void sqlite3VdbeSetChanges(sqlite3 *, int);
+void sqlite3utf16Substr(sqlite3_context *,int,sqlite3_value **);
+
+const void *sqlite3ValueText(sqlite3_value*, u8);
+int sqlite3ValueBytes(sqlite3_value*, u8);
+void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*));
+void sqlite3ValueFree(sqlite3_value*);
+sqlite3_value *sqlite3ValueNew();
+sqlite3_value *sqlite3GetTransientValue(sqlite3*db);
+int sqlite3ValueFromExpr(Expr *, u8, u8, sqlite3_value **);
+void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
+extern const unsigned char sqlite3UpperToLower[];
+void sqlite3RootPageMoved(Db*, int, int);
+void sqlite3Reindex(Parse*, Token*, Token*);
+void sqlite3AlterFunctions(sqlite3*);
+void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
+int sqlite3GetToken(const unsigned char *, int *);
+void sqlite3NestedParse(Parse*, const char*, ...);
+void sqlite3ExpirePreparedStatements(sqlite3*);
+void sqlite3CodeSubselect(Parse *, Expr *);
+int sqlite3SelectResolve(Parse *, Select *, NameContext *);
+void sqlite3ColumnDefault(Vdbe *, Table *, int);
+void sqlite3AlterFinishAddColumn(Parse *, Token *);
+void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
+const char *sqlite3TestErrorName(int);
+CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
+
+#ifdef SQLITE_SSE
+#include "sseInt.h"
+#endif
+
+#endif
diff --git a/src/sqlite/table.c b/src/sqlite/table.c
new file mode 100644
index 0000000..d4ef2c8
--- /dev/null
+++ b/src/sqlite/table.c
@@ -0,0 +1,195 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains the sqlite3_get_table() and sqlite3_free_table()
+** interface routines. These are just wrappers around the main
+** interface routine of sqlite3_exec().
+**
+** These routines are in a separate files so that they will not be linked
+** if they are not used.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include "sqliteInt.h"
+
+/*
+** This structure is used to pass data from sqlite3_get_table() through
+** to the callback function is uses to build the result.
+*/
+typedef struct TabResult {
+ char **azResult;
+ char *zErrMsg;
+ int nResult;
+ int nAlloc;
+ int nRow;
+ int nColumn;
+ int nData;
+ int rc;
+} TabResult;
+
+/*
+** This routine is called once for each row in the result table. Its job
+** is to fill in the TabResult structure appropriately, allocating new
+** memory as necessary.
+*/
+static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
+ TabResult *p = (TabResult*)pArg;
+ int need;
+ int i;
+ char *z;
+
+ /* Make sure there is enough space in p->azResult to hold everything
+ ** we need to remember from this invocation of the callback.
+ */
+ if( p->nRow==0 && argv!=0 ){
+ need = nCol*2;
+ }else{
+ need = nCol;
+ }
+ if( p->nData + need >= p->nAlloc ){
+ char **azNew;
+ p->nAlloc = p->nAlloc*2 + need + 1;
+ azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
+ if( azNew==0 ) goto malloc_failed;
+ p->azResult = azNew;
+ }
+
+ /* If this is the first row, then generate an extra row containing
+ ** the names of all columns.
+ */
+ if( p->nRow==0 ){
+ p->nColumn = nCol;
+ for(i=0; i<nCol; i++){
+ if( colv[i]==0 ){
+ z = 0;
+ }else{
+ z = malloc( strlen(colv[i])+1 );
+ if( z==0 ) goto malloc_failed;
+ strcpy(z, colv[i]);
+ }
+ p->azResult[p->nData++] = z;
+ }
+ }else if( p->nColumn!=nCol ){
+ sqlite3SetString(&p->zErrMsg,
+ "sqlite3_get_table() called with two or more incompatible queries",
+ (char*)0);
+ p->rc = SQLITE_ERROR;
+ return 1;
+ }
+
+ /* Copy over the row data
+ */
+ if( argv!=0 ){
+ for(i=0; i<nCol; i++){
+ if( argv[i]==0 ){
+ z = 0;
+ }else{
+ z = malloc( strlen(argv[i])+1 );
+ if( z==0 ) goto malloc_failed;
+ strcpy(z, argv[i]);
+ }
+ p->azResult[p->nData++] = z;
+ }
+ p->nRow++;
+ }
+ return 0;
+
+malloc_failed:
+ p->rc = SQLITE_NOMEM;
+ return 1;
+}
+
+/*
+** Query the database. But instead of invoking a callback for each row,
+** malloc() for space to hold the result and return the entire results
+** at the conclusion of the call.
+**
+** The result that is written to ***pazResult is held in memory obtained
+** from malloc(). But the caller cannot free this memory directly.
+** Instead, the entire table should be passed to sqlite3_free_table() when
+** the calling procedure is finished using it.
+*/
+int sqlite3_get_table(
+ sqlite3 *db, /* The database on which the SQL executes */
+ const char *zSql, /* The SQL to be executed */
+ char ***pazResult, /* Write the result table here */
+ int *pnRow, /* Write the number of rows in the result here */
+ int *pnColumn, /* Write the number of columns of result here */
+ char **pzErrMsg /* Write error messages here */
+){
+ int rc;
+ TabResult res;
+ if( pazResult==0 ){ return SQLITE_ERROR; }
+ *pazResult = 0;
+ if( pnColumn ) *pnColumn = 0;
+ if( pnRow ) *pnRow = 0;
+ res.zErrMsg = 0;
+ res.nResult = 0;
+ res.nRow = 0;
+ res.nColumn = 0;
+ res.nData = 1;
+ res.nAlloc = 20;
+ res.rc = SQLITE_OK;
+ res.azResult = malloc( sizeof(char*)*res.nAlloc );
+ if( res.azResult==0 ) return SQLITE_NOMEM;
+ res.azResult[0] = 0;
+ rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
+ if( res.azResult ){
+ res.azResult[0] = (char*)res.nData;
+ }
+ if( rc==SQLITE_ABORT ){
+ sqlite3_free_table(&res.azResult[1]);
+ if( res.zErrMsg ){
+ if( pzErrMsg ){
+ free(*pzErrMsg);
+ *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
+ }
+ sqliteFree(res.zErrMsg);
+ }
+ db->errCode = res.rc;
+ return res.rc;
+ }
+ sqliteFree(res.zErrMsg);
+ if( rc!=SQLITE_OK ){
+ sqlite3_free_table(&res.azResult[1]);
+ return rc;
+ }
+ if( res.nAlloc>res.nData ){
+ char **azNew;
+ azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
+ if( azNew==0 ){
+ sqlite3_free_table(&res.azResult[1]);
+ return SQLITE_NOMEM;
+ }
+ res.nAlloc = res.nData+1;
+ res.azResult = azNew;
+ }
+ *pazResult = &res.azResult[1];
+ if( pnColumn ) *pnColumn = res.nColumn;
+ if( pnRow ) *pnRow = res.nRow;
+ return rc;
+}
+
+/*
+** This routine frees the space the sqlite3_get_table() malloced.
+*/
+void sqlite3_free_table(
+ char **azResult /* Result returned from from sqlite3_get_table() */
+){
+ if( azResult ){
+ int i, n;
+ azResult--;
+ if( azResult==0 ) return;
+ n = (int)azResult[0];
+ for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
+ free(azResult);
+ }
+}
diff --git a/src/sqlite/tokenize.c b/src/sqlite/tokenize.c
new file mode 100644
index 0000000..056a4ba
--- /dev/null
+++ b/src/sqlite/tokenize.c
@@ -0,0 +1,670 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** An tokenizer for SQL
+**
+** This file contains C code that splits an SQL input string up into
+** individual tokens and sends those tokens one-by-one over to the
+** parser for analysis.
+**
+** $Id: tokenize.c,v 1.1.1.1 2006/02/03 20:35:19 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+** The sqlite3KeywordCode function looks up an identifier to determine if
+** it is a keyword. If it is a keyword, the token code of that keyword is
+** returned. If the input is not a keyword, TK_ID is returned.
+**
+** The implementation of this routine was generated by a program,
+** mkkeywordhash.h, located in the tool subdirectory of the distribution.
+** The output of the mkkeywordhash.c program is written into a file
+** named keywordhash.h and then included into this source file by
+** the #include below.
+*/
+#include "keywordhash.h"
+
+
+/*
+** If X is a character that can be used in an identifier and
+** X&0x80==0 then isIdChar[X] will be 1. If X&0x80==0x80 then
+** X is always an identifier character. (Hence all UTF-8
+** characters can be part of an identifier). isIdChar[X] will
+** be 0 for every character in the lower 128 ASCII characters
+** that cannot be used as part of an identifier.
+**
+** In this implementation, an identifier can be a string of
+** alphabetic characters, digits, and "_" plus any character
+** with the high-order bit set. The latter rule means that
+** any sequence of UTF-8 characters or characters taken from
+** an extended ISO8859 character set can form an identifier.
+**
+** Ticket #1066. the SQL standard does not allow '$' in the
+** middle of identfiers. But many SQL implementations do.
+** SQLite will allow '$' in identifiers for compatibility.
+** But the feature is undocumented.
+*/
+static const char isIdChar[] = {
+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
+};
+
+#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && isIdChar[c-0x20]))
+
+/*
+** Return the length of the token that begins at z[0].
+** Store the token type in *tokenType before returning.
+*/
+static int getToken(const unsigned char *z, int *tokenType){
+ int i, c;
+ switch( *z ){
+ case ' ': case '\t': case '\n': case '\f': case '\r': {
+ for(i=1; isspace(z[i]); i++){}
+ *tokenType = TK_SPACE;
+ return i;
+ }
+ case '-': {
+ if( z[1]=='-' ){
+ for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
+ *tokenType = TK_COMMENT;
+ return i;
+ }
+ *tokenType = TK_MINUS;
+ return 1;
+ }
+ case '(': {
+ *tokenType = TK_LP;
+ return 1;
+ }
+ case ')': {
+ *tokenType = TK_RP;
+ return 1;
+ }
+ case ';': {
+ *tokenType = TK_SEMI;
+ return 1;
+ }
+ case '+': {
+ *tokenType = TK_PLUS;
+ return 1;
+ }
+ case '*': {
+ *tokenType = TK_STAR;
+ return 1;
+ }
+ case '/': {
+ if( z[1]!='*' || z[2]==0 ){
+ *tokenType = TK_SLASH;
+ return 1;
+ }
+ for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
+ if( c ) i++;
+ *tokenType = TK_COMMENT;
+ return i;
+ }
+ case '%': {
+ *tokenType = TK_REM;
+ return 1;
+ }
+ case '=': {
+ *tokenType = TK_EQ;
+ return 1 + (z[1]=='=');
+ }
+ case '<': {
+ if( (c=z[1])=='=' ){
+ *tokenType = TK_LE;
+ return 2;
+ }else if( c=='>' ){
+ *tokenType = TK_NE;
+ return 2;
+ }else if( c=='<' ){
+ *tokenType = TK_LSHIFT;
+ return 2;
+ }else{
+ *tokenType = TK_LT;
+ return 1;
+ }
+ }
+ case '>': {
+ if( (c=z[1])=='=' ){
+ *tokenType = TK_GE;
+ return 2;
+ }else if( c=='>' ){
+ *tokenType = TK_RSHIFT;
+ return 2;
+ }else{
+ *tokenType = TK_GT;
+ return 1;
+ }
+ }
+ case '!': {
+ if( z[1]!='=' ){
+ *tokenType = TK_ILLEGAL;
+ return 2;
+ }else{
+ *tokenType = TK_NE;
+ return 2;
+ }
+ }
+ case '|': {
+ if( z[1]!='|' ){
+ *tokenType = TK_BITOR;
+ return 1;
+ }else{
+ *tokenType = TK_CONCAT;
+ return 2;
+ }
+ }
+ case ',': {
+ *tokenType = TK_COMMA;
+ return 1;
+ }
+ case '&': {
+ *tokenType = TK_BITAND;
+ return 1;
+ }
+ case '~': {
+ *tokenType = TK_BITNOT;
+ return 1;
+ }
+ case '#': {
+ for(i=1; isdigit(z[i]) || (i==1 && z[1]=='-'); i++){}
+ *tokenType = TK_REGISTER;
+ return i;
+ }
+ case '\'': case '"': {
+ int delim = z[0];
+ for(i=1; (c=z[i])!=0; i++){
+ if( c==delim ){
+ if( z[i+1]==delim ){
+ i++;
+ }else{
+ break;
+ }
+ }
+ }
+ if( c ) i++;
+ *tokenType = TK_STRING;
+ return i;
+ }
+ case '.': {
+ *tokenType = TK_DOT;
+ return 1;
+ }
+ 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++){}
+#ifndef SQLITE_OMIT_FLOATING_POINT
+ if( z[i]=='.' && isdigit(z[i+1]) ){
+ i += 2;
+ while( isdigit(z[i]) ){ i++; }
+ *tokenType = TK_FLOAT;
+ }
+ if( (z[i]=='e' || z[i]=='E') &&
+ ( isdigit(z[i+1])
+ || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
+ )
+ ){
+ i += 2;
+ while( isdigit(z[i]) ){ i++; }
+ *tokenType = TK_FLOAT;
+ }
+#endif
+ return i;
+ }
+ case '[': {
+ for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
+ *tokenType = TK_ID;
+ return i;
+ }
+ case '?': {
+ *tokenType = TK_VARIABLE;
+ 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;
+ }
+#ifndef SQLITE_OMIT_TCL_VARIABLE
+ case '$': {
+ *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]==':' ){
+ i++;
+ }else{
+ break;
+ }
+ }
+ if( n==0 ) *tokenType = TK_ILLEGAL;
+ }
+ return i;
+ }
+#endif
+#ifndef SQLITE_OMIT_BLOB_LITERAL
+ case 'x': case 'X': {
+ if( (c=z[1])=='\'' || c=='"' ){
+ int delim = c;
+ *tokenType = TK_BLOB;
+ for(i=2; (c=z[i])!=0; i++){
+ if( c==delim ){
+ if( i%2 ) *tokenType = TK_ILLEGAL;
+ break;
+ }
+ if( !isxdigit(c) ){
+ *tokenType = TK_ILLEGAL;
+ return i;
+ }
+ }
+ if( c ) i++;
+ return i;
+ }
+ /* Otherwise fall through to the next case */
+ }
+#endif
+ default: {
+ if( !IdChar(*z) ){
+ break;
+ }
+ for(i=1; IdChar(z[i]); i++){}
+ *tokenType = keywordCode((char*)z, i);
+ return i;
+ }
+ }
+ *tokenType = TK_ILLEGAL;
+ return 1;
+}
+int sqlite3GetToken(const unsigned char *z, int *tokenType){
+ return getToken(z, tokenType);
+}
+
+/*
+** Run the parser on the given SQL string. The parser structure is
+** passed in. An SQLITE_ status code is returned. If an error occurs
+** and pzErrMsg!=NULL then an error message might be written into
+** memory obtained from malloc() and *pzErrMsg made to point to that
+** error message. Or maybe not.
+*/
+int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
+ int nErr = 0;
+ int i;
+ void *pEngine;
+ int tokenType;
+ int lastTokenParsed = -1;
+ sqlite3 *db = pParse->db;
+ extern void *sqlite3ParserAlloc(void*(*)(int));
+ extern void sqlite3ParserFree(void*, void(*)(void*));
+ extern int sqlite3Parser(void*, int, Token, Parse*);
+
+ db->flags &= ~SQLITE_Interrupt;
+ pParse->rc = SQLITE_OK;
+ i = 0;
+ pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX);
+ if( pEngine==0 ){
+ sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
+ return SQLITE_NOMEM;
+ }
+ assert( pParse->sLastToken.dyn==0 );
+ assert( pParse->pNewTable==0 );
+ assert( pParse->pNewTrigger==0 );
+ assert( pParse->nVar==0 );
+ assert( pParse->nVarExpr==0 );
+ assert( pParse->nVarExprAlloc==0 );
+ assert( pParse->apVarExpr==0 );
+ pParse->zTail = pParse->zSql = zSql;
+ while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
+ assert( i>=0 );
+ pParse->sLastToken.z = &zSql[i];
+ assert( pParse->sLastToken.dyn==0 );
+ pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
+ i += pParse->sLastToken.n;
+ switch( tokenType ){
+ case TK_SPACE:
+ case TK_COMMENT: {
+ if( (db->flags & SQLITE_Interrupt)!=0 ){
+ pParse->rc = SQLITE_INTERRUPT;
+ sqlite3SetString(pzErrMsg, "interrupt", (char*)0);
+ goto abort_parse;
+ }
+ break;
+ }
+ case TK_ILLEGAL: {
+ if( pzErrMsg ){
+ sqliteFree(*pzErrMsg);
+ *pzErrMsg = sqlite3MPrintf("unrecognized token: \"%T\"",
+ &pParse->sLastToken);
+ }
+ nErr++;
+ goto abort_parse;
+ }
+ case TK_SEMI: {
+ pParse->zTail = &zSql[i];
+ /* Fall thru into the default case */
+ }
+ default: {
+ sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
+ lastTokenParsed = tokenType;
+ if( pParse->rc!=SQLITE_OK ){
+ goto abort_parse;
+ }
+ break;
+ }
+ }
+ }
+abort_parse:
+ if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
+ if( lastTokenParsed!=TK_SEMI ){
+ sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
+ pParse->zTail = &zSql[i];
+ }
+ sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+ }
+ sqlite3ParserFree(pEngine, sqlite3FreeX);
+ if( sqlite3_malloc_failed ){
+ pParse->rc = SQLITE_NOMEM;
+ }
+ if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
+ sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc),
+ (char*)0);
+ }
+ if( pParse->zErrMsg ){
+ if( pzErrMsg && *pzErrMsg==0 ){
+ *pzErrMsg = pParse->zErrMsg;
+ }else{
+ sqliteFree(pParse->zErrMsg);
+ }
+ pParse->zErrMsg = 0;
+ if( !nErr ) nErr++;
+ }
+ if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
+ sqlite3VdbeDelete(pParse->pVdbe);
+ pParse->pVdbe = 0;
+ }
+ sqlite3DeleteTable(pParse->db, pParse->pNewTable);
+ sqlite3DeleteTrigger(pParse->pNewTrigger);
+ sqliteFree(pParse->apVarExpr);
+ if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
+ pParse->rc = SQLITE_ERROR;
+ }
+ 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/src/sqlite/trigger.c b/src/sqlite/trigger.c
new file mode 100644
index 0000000..f39d2bd
--- /dev/null
+++ b/src/sqlite/trigger.c
@@ -0,0 +1,802 @@
+/*
+**
+** 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.
+**
+*************************************************************************
+*
+*/
+#include "sqliteInt.h"
+
+#ifndef SQLITE_OMIT_TRIGGER
+/*
+** Delete a linked list of TriggerStep structures.
+*/
+void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){
+ while( pTriggerStep ){
+ TriggerStep * pTmp = pTriggerStep;
+ pTriggerStep = pTriggerStep->pNext;
+
+ if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
+ sqlite3ExprDelete(pTmp->pWhere);
+ sqlite3ExprListDelete(pTmp->pExprList);
+ sqlite3SelectDelete(pTmp->pSelect);
+ sqlite3IdListDelete(pTmp->pIdList);
+
+ sqliteFree(pTmp);
+ }
+}
+
+/*
+** This is called by the parser when it sees a CREATE TRIGGER statement
+** up to the point of the BEGIN before the trigger actions. A Trigger
+** structure is generated based on the information available and stored
+** in pParse->pNewTrigger. After the trigger actions have been parsed, the
+** sqlite3FinishTrigger() function is called to complete the trigger
+** construction process.
+*/
+void sqlite3BeginTrigger(
+ Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
+ Token *pName1, /* The name of the trigger */
+ Token *pName2, /* The name of the trigger */
+ int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
+ int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
+ IdList *pColumns, /* column list if this is an UPDATE OF trigger */
+ SrcList *pTableName,/* The name of the table/view the trigger applies to */
+ int foreach, /* One of TK_ROW or TK_STATEMENT */
+ Expr *pWhen, /* WHEN clause */
+ int isTemp /* True if the TEMPORARY keyword is present */
+){
+ Trigger *pTrigger = 0;
+ Table *pTab;
+ char *zName = 0; /* Name of the trigger */
+ sqlite3 *db = pParse->db;
+ int iDb; /* The database to store the trigger in */
+ Token *pName; /* The unqualified db name */
+ DbFixer sFix;
+
+ if( isTemp ){
+ /* If TEMP was specified, then the trigger name may not be qualified. */
+ if( pName2 && pName2->n>0 ){
+ sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
+ goto trigger_cleanup;
+ }
+ iDb = 1;
+ pName = pName1;
+ }else{
+ /* Figure out the db that the the trigger will be created in */
+ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+ if( iDb<0 ){
+ goto trigger_cleanup;
+ }
+ }
+
+ /* If the trigger name was unqualified, and the table is a temp table,
+ ** then set iDb to 1 to create the trigger in the temporary database.
+ ** If sqlite3SrcListLookup() returns 0, indicating the table does not
+ ** exist, the error is caught by the block below.
+ */
+ if( !pTableName || sqlite3_malloc_failed ) goto trigger_cleanup;
+ pTab = sqlite3SrcListLookup(pParse, pTableName);
+ if( pName2->n==0 && pTab && pTab->iDb==1 ){
+ iDb = 1;
+ }
+
+ /* Ensure the table name matches database name and that the table exists */
+ if( sqlite3_malloc_failed ) goto trigger_cleanup;
+ assert( pTableName->nSrc==1 );
+ if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) &&
+ sqlite3FixSrcList(&sFix, pTableName) ){
+ goto trigger_cleanup;
+ }
+ pTab = sqlite3SrcListLookup(pParse, pTableName);
+ if( !pTab ){
+ /* The table does not exist. */
+ goto trigger_cleanup;
+ }
+
+ /* Check that the trigger name is not reserved and that no trigger of the
+ ** specified name exists */
+ zName = sqlite3NameFromToken(pName);
+ if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+ goto trigger_cleanup;
+ }
+ if( sqlite3HashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
+ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+ goto trigger_cleanup;
+ }
+
+ /* Do not create a trigger on a system table */
+ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
+ sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
+ pParse->nErr++;
+ goto trigger_cleanup;
+ }
+
+ /* INSTEAD of triggers are only for views and views only support INSTEAD
+ ** of triggers.
+ */
+ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
+ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S",
+ (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
+ goto trigger_cleanup;
+ }
+ if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
+ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
+ " trigger on table: %S", pTableName, 0);
+ goto trigger_cleanup;
+ }
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int code = SQLITE_CREATE_TRIGGER;
+ const char *zDb = db->aDb[pTab->iDb].zName;
+ const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
+ if( pTab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
+ if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
+ goto trigger_cleanup;
+ }
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(pTab->iDb),0,zDb)){
+ goto trigger_cleanup;
+ }
+ }
+#endif
+
+ /* INSTEAD OF triggers can only appear on views and BEFORE triggers
+ ** cannot appear on views. So we might as well translate every
+ ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code
+ ** elsewhere.
+ */
+ if (tr_tm == TK_INSTEAD){
+ tr_tm = TK_BEFORE;
+ }
+
+ /* Build the Trigger object */
+ pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger));
+ if( pTrigger==0 ) goto trigger_cleanup;
+ pTrigger->name = zName;
+ zName = 0;
+ pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
+ pTrigger->iDb = iDb;
+ pTrigger->iTabDb = pTab->iDb;
+ pTrigger->op = op;
+ pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
+ pTrigger->pWhen = sqlite3ExprDup(pWhen);
+ pTrigger->pColumns = sqlite3IdListDup(pColumns);
+ pTrigger->foreach = foreach;
+ sqlite3TokenCopy(&pTrigger->nameToken,pName);
+ assert( pParse->pNewTrigger==0 );
+ pParse->pNewTrigger = pTrigger;
+
+trigger_cleanup:
+ sqliteFree(zName);
+ sqlite3SrcListDelete(pTableName);
+ sqlite3IdListDelete(pColumns);
+ sqlite3ExprDelete(pWhen);
+ if( !pParse->pNewTrigger ){
+ sqlite3DeleteTrigger(pTrigger);
+ }else{
+ assert( pParse->pNewTrigger==pTrigger );
+ }
+}
+
+/*
+** This routine is called after all of the trigger actions have been parsed
+** in order to complete the process of building the trigger.
+*/
+void sqlite3FinishTrigger(
+ Parse *pParse, /* Parser context */
+ TriggerStep *pStepList, /* The triggered program */
+ Token *pAll /* Token that describes the complete CREATE TRIGGER */
+){
+ Trigger *pTrig = 0; /* The trigger whose construction is finishing up */
+ sqlite3 *db = pParse->db; /* The database */
+ DbFixer sFix;
+
+ pTrig = pParse->pNewTrigger;
+ pParse->pNewTrigger = 0;
+ if( pParse->nErr || pTrig==0 ) goto triggerfinish_cleanup;
+ pTrig->step_list = pStepList;
+ while( pStepList ){
+ pStepList->pTrig = pTrig;
+ pStepList = pStepList->pNext;
+ }
+ if( sqlite3FixInit(&sFix, pParse, pTrig->iDb, "trigger", &pTrig->nameToken)
+ && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
+ goto triggerfinish_cleanup;
+ }
+
+ /* if we are not initializing, and this trigger is not on a TEMP table,
+ ** build the sqlite_master entry
+ */
+ if( !db->init.busy ){
+ static const VdbeOpList insertTrig[] = {
+ { OP_NewRowid, 0, 0, 0 },
+ { OP_String8, 0, 0, "trigger" },
+ { OP_String8, 0, 0, 0 }, /* 2: trigger name */
+ { OP_String8, 0, 0, 0 }, /* 3: table name */
+ { OP_Integer, 0, 0, 0 },
+ { OP_String8, 0, 0, "CREATE TRIGGER "},
+ { OP_String8, 0, 0, 0 }, /* 6: SQL */
+ { OP_Concat, 0, 0, 0 },
+ { OP_MakeRecord, 5, 0, "tttit" },
+ { OP_Insert, 0, 0, 0 },
+ };
+ int addr;
+ Vdbe *v;
+
+ /* Make an entry in the sqlite_master table */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto triggerfinish_cleanup;
+ sqlite3BeginWriteOperation(pParse, 0, pTrig->iDb);
+ sqlite3OpenMasterTable(v, pTrig->iDb);
+ addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
+ sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0);
+ sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0);
+ sqlite3VdbeChangeP3(v, addr+6, pAll->z, pAll->n);
+ sqlite3ChangeCookie(db, v, pTrig->iDb);
+ sqlite3VdbeAddOp(v, OP_Close, 0, 0);
+ sqlite3VdbeOp3(v, OP_ParseSchema, pTrig->iDb, 0,
+ sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC);
+ }
+
+ if( db->init.busy ){
+ Table *pTab;
+ Trigger *pDel;
+ pDel = sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash,
+ pTrig->name, strlen(pTrig->name)+1, pTrig);
+ if( pDel ){
+ assert( sqlite3_malloc_failed && pDel==pTrig );
+ goto triggerfinish_cleanup;
+ }
+ pTab = sqlite3LocateTable(pParse,pTrig->table,db->aDb[pTrig->iTabDb].zName);
+ assert( pTab!=0 );
+ pTrig->pNext = pTab->pTrigger;
+ pTab->pTrigger = pTrig;
+ pTrig = 0;
+ }
+
+triggerfinish_cleanup:
+ sqlite3DeleteTrigger(pTrig);
+ assert( !pParse->pNewTrigger );
+ sqlite3DeleteTriggerStep(pStepList);
+}
+
+/*
+** Make a copy of all components of the given trigger step. This has
+** the effect of copying all Expr.token.z values into memory obtained
+** from sqliteMalloc(). As initially created, the Expr.token.z values
+** all point to the input string that was fed to the parser. But that
+** string is ephemeral - it will go away as soon as the sqlite3_exec()
+** call that started the parser exits. This routine makes a persistent
+** copy of all the Expr.token.z strings so that the TriggerStep structure
+** will be valid even after the sqlite3_exec() call returns.
+*/
+static void sqlitePersistTriggerStep(TriggerStep *p){
+ if( p->target.z ){
+ p->target.z = sqliteStrNDup(p->target.z, p->target.n);
+ p->target.dyn = 1;
+ }
+ if( p->pSelect ){
+ Select *pNew = sqlite3SelectDup(p->pSelect);
+ sqlite3SelectDelete(p->pSelect);
+ p->pSelect = pNew;
+ }
+ if( p->pWhere ){
+ Expr *pNew = sqlite3ExprDup(p->pWhere);
+ sqlite3ExprDelete(p->pWhere);
+ p->pWhere = pNew;
+ }
+ if( p->pExprList ){
+ ExprList *pNew = sqlite3ExprListDup(p->pExprList);
+ sqlite3ExprListDelete(p->pExprList);
+ p->pExprList = pNew;
+ }
+ if( p->pIdList ){
+ IdList *pNew = sqlite3IdListDup(p->pIdList);
+ sqlite3IdListDelete(p->pIdList);
+ p->pIdList = pNew;
+ }
+}
+
+/*
+** Turn a SELECT statement (that the pSelect parameter points to) into
+** a trigger step. Return a pointer to a TriggerStep structure.
+**
+** The parser calls this routine when it finds a SELECT statement in
+** body of a TRIGGER.
+*/
+TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+ if( pTriggerStep==0 ) return 0;
+
+ pTriggerStep->op = TK_SELECT;
+ pTriggerStep->pSelect = pSelect;
+ pTriggerStep->orconf = OE_Default;
+ sqlitePersistTriggerStep(pTriggerStep);
+
+ return pTriggerStep;
+}
+
+/*
+** Build a trigger step out of an INSERT statement. Return a pointer
+** to the new trigger step.
+**
+** The parser calls this routine when it sees an INSERT inside the
+** body of a trigger.
+*/
+TriggerStep *sqlite3TriggerInsertStep(
+ Token *pTableName, /* Name of the table into which we insert */
+ IdList *pColumn, /* List of columns in pTableName to insert into */
+ ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
+ Select *pSelect, /* A SELECT statement that supplies values */
+ int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+
+ assert(pEList == 0 || pSelect == 0);
+ assert(pEList != 0 || pSelect != 0);
+
+ if( pTriggerStep ){
+ pTriggerStep->op = TK_INSERT;
+ pTriggerStep->pSelect = pSelect;
+ pTriggerStep->target = *pTableName;
+ pTriggerStep->pIdList = pColumn;
+ pTriggerStep->pExprList = pEList;
+ pTriggerStep->orconf = orconf;
+ sqlitePersistTriggerStep(pTriggerStep);
+ }else{
+ sqlite3IdListDelete(pColumn);
+ sqlite3ExprListDelete(pEList);
+ sqlite3SelectDup(pSelect);
+ }
+
+ return pTriggerStep;
+}
+
+/*
+** Construct a trigger step that implements an UPDATE statement and return
+** a pointer to that trigger step. The parser calls this routine when it
+** sees an UPDATE statement inside the body of a CREATE TRIGGER.
+*/
+TriggerStep *sqlite3TriggerUpdateStep(
+ Token *pTableName, /* Name of the table to be updated */
+ ExprList *pEList, /* The SET clause: list of column and new values */
+ Expr *pWhere, /* The WHERE clause */
+ int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+ if( pTriggerStep==0 ) return 0;
+
+ pTriggerStep->op = TK_UPDATE;
+ pTriggerStep->target = *pTableName;
+ pTriggerStep->pExprList = pEList;
+ pTriggerStep->pWhere = pWhere;
+ pTriggerStep->orconf = orconf;
+ sqlitePersistTriggerStep(pTriggerStep);
+
+ return pTriggerStep;
+}
+
+/*
+** Construct a trigger step that implements a DELETE statement and return
+** a pointer to that trigger step. The parser calls this routine when it
+** sees a DELETE statement inside the body of a CREATE TRIGGER.
+*/
+TriggerStep *sqlite3TriggerDeleteStep(Token *pTableName, Expr *pWhere){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+ if( pTriggerStep==0 ) return 0;
+
+ pTriggerStep->op = TK_DELETE;
+ pTriggerStep->target = *pTableName;
+ pTriggerStep->pWhere = pWhere;
+ pTriggerStep->orconf = OE_Default;
+ sqlitePersistTriggerStep(pTriggerStep);
+
+ return pTriggerStep;
+}
+
+/*
+** Recursively delete a Trigger structure
+*/
+void sqlite3DeleteTrigger(Trigger *pTrigger){
+ if( pTrigger==0 ) return;
+ sqlite3DeleteTriggerStep(pTrigger->step_list);
+ sqliteFree(pTrigger->name);
+ sqliteFree(pTrigger->table);
+ sqlite3ExprDelete(pTrigger->pWhen);
+ sqlite3IdListDelete(pTrigger->pColumns);
+ if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
+ sqliteFree(pTrigger);
+}
+
+/*
+** This function is called to drop a trigger from the database schema.
+**
+** This may be called directly from the parser and therefore identifies
+** the trigger by name. The sqlite3DropTriggerPtr() routine does the
+** same job as this routine except it takes a pointer to the trigger
+** instead of the trigger name.
+**/
+void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
+ Trigger *pTrigger = 0;
+ int i;
+ const char *zDb;
+ const char *zName;
+ int nName;
+ sqlite3 *db = pParse->db;
+
+ if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+ goto drop_trigger_cleanup;
+ }
+
+ assert( pName->nSrc==1 );
+ zDb = pName->a[0].zDatabase;
+ zName = pName->a[0].zName;
+ nName = strlen(zName);
+ for(i=OMIT_TEMPDB; i<db->nDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
+ pTrigger = sqlite3HashFind(&(db->aDb[j].trigHash), zName, nName+1);
+ if( pTrigger ) break;
+ }
+ if( !pTrigger ){
+ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
+ goto drop_trigger_cleanup;
+ }
+ sqlite3DropTriggerPtr(pParse, pTrigger, 0);
+
+drop_trigger_cleanup:
+ sqlite3SrcListDelete(pName);
+}
+
+/*
+** Return a pointer to the Table structure for the table that a trigger
+** is set on.
+*/
+static Table *tableOfTrigger(sqlite3 *db, Trigger *pTrigger){
+ return sqlite3FindTable(db,pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
+}
+
+
+/*
+** Drop a trigger given a pointer to that trigger. If nested is false,
+** then also generate code to remove the trigger from the SQLITE_MASTER
+** table.
+*/
+void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
+ Table *pTable;
+ Vdbe *v;
+ sqlite3 *db = pParse->db;
+ int iDb;
+
+ iDb = pTrigger->iDb;
+ assert( iDb>=0 && iDb<db->nDb );
+ pTable = tableOfTrigger(db, pTrigger);
+ assert(pTable);
+ assert( pTable->iDb==iDb || iDb==1 );
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int code = SQLITE_DROP_TRIGGER;
+ const char *zDb = db->aDb[iDb].zName;
+ const char *zTab = SCHEMA_TABLE(iDb);
+ if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
+ if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
+ sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
+ return;
+ }
+ }
+#endif
+
+ /* Generate code to destroy the database record of the trigger.
+ */
+ if( pTable!=0 && (v = sqlite3GetVdbe(pParse))!=0 ){
+ int base;
+ static const VdbeOpList dropTrigger[] = {
+ { OP_Rewind, 0, ADDR(9), 0},
+ { OP_String8, 0, 0, 0}, /* 1 */
+ { OP_Column, 0, 1, 0},
+ { OP_Ne, 0, ADDR(8), 0},
+ { OP_String8, 0, 0, "trigger"},
+ { OP_Column, 0, 0, 0},
+ { OP_Ne, 0, ADDR(8), 0},
+ { OP_Delete, 0, 0, 0},
+ { OP_Next, 0, ADDR(1), 0}, /* 8 */
+ };
+
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3OpenMasterTable(v, iDb);
+ base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
+ sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
+ sqlite3ChangeCookie(db, v, iDb);
+ sqlite3VdbeAddOp(v, OP_Close, 0, 0);
+ sqlite3VdbeOp3(v, OP_DropTrigger, iDb, 0, pTrigger->name, 0);
+ }
+}
+
+/*
+** Remove a trigger from the hash tables of the sqlite* pointer.
+*/
+void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
+ Trigger *pTrigger;
+ int nName = strlen(zName);
+ pTrigger = sqlite3HashInsert(&(db->aDb[iDb].trigHash), zName, nName+1, 0);
+ if( pTrigger ){
+ Table *pTable = tableOfTrigger(db, pTrigger);
+ assert( pTable!=0 );
+ if( pTable->pTrigger == pTrigger ){
+ pTable->pTrigger = pTrigger->pNext;
+ }else{
+ Trigger *cc = pTable->pTrigger;
+ while( cc ){
+ if( cc->pNext == pTrigger ){
+ cc->pNext = cc->pNext->pNext;
+ break;
+ }
+ cc = cc->pNext;
+ }
+ assert(cc);
+ }
+ sqlite3DeleteTrigger(pTrigger);
+ db->flags |= SQLITE_InternChanges;
+ }
+}
+
+/*
+** pEList is the SET clause of an UPDATE statement. Each entry
+** in pEList is of the format <id>=<expr>. If any of the entries
+** in pEList have an <id> which matches an identifier in pIdList,
+** then return TRUE. If pIdList==NULL, then it is considered a
+** wildcard that matches anything. Likewise if pEList==NULL then
+** it matches anything so always return true. Return false only
+** if there is no match.
+*/
+static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
+ int e;
+ if( !pIdList || !pEList ) return 1;
+ for(e=0; e<pEList->nExpr; e++){
+ if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
+ }
+ return 0;
+}
+
+/*
+** Return a bit vector to indicate what kind of triggers exist for operation
+** "op" on table pTab. If pChanges is not NULL then it is a list of columns
+** that are being updated. Triggers only match if the ON clause of the
+** trigger definition overlaps the set of columns being updated.
+**
+** The returned bit vector is some combination of TRIGGER_BEFORE and
+** TRIGGER_AFTER.
+*/
+int sqlite3TriggersExist(
+ Parse *pParse, /* Used to check for recursive triggers */
+ Table *pTab, /* The table the contains the triggers */
+ int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
+ ExprList *pChanges /* Columns that change in an UPDATE statement */
+){
+ Trigger *pTrigger = pTab->pTrigger;
+ int mask = 0;
+
+ while( pTrigger ){
+ if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
+ TriggerStack *ss;
+ ss = pParse->trigStack;
+ while( ss && ss->pTrigger!=pTab->pTrigger ){
+ ss = ss->pNext;
+ }
+ if( ss==0 ){
+ mask |= pTrigger->tr_tm;
+ }
+ }
+ pTrigger = pTrigger->pNext;
+ }
+ return mask;
+}
+
+/*
+** Convert the pStep->target token into a SrcList and return a pointer
+** to that SrcList.
+**
+** This routine adds a specific database name, if needed, to the target when
+** forming the SrcList. This prevents a trigger in one database from
+** referring to a target in another database. An exception is when the
+** trigger is in TEMP in which case it can refer to any other database it
+** wants.
+*/
+static SrcList *targetSrcList(
+ Parse *pParse, /* The parsing context */
+ TriggerStep *pStep /* The trigger containing the target token */
+){
+ Token sDb; /* Dummy database name token */
+ int iDb; /* Index of the database to use */
+ SrcList *pSrc; /* SrcList to be returned */
+
+ iDb = pStep->pTrig->iDb;
+ if( iDb==0 || iDb>=2 ){
+ assert( iDb<pParse->db->nDb );
+ sDb.z = pParse->db->aDb[iDb].zName;
+ sDb.n = strlen(sDb.z);
+ pSrc = sqlite3SrcListAppend(0, &sDb, &pStep->target);
+ } else {
+ pSrc = sqlite3SrcListAppend(0, &pStep->target, 0);
+ }
+ return pSrc;
+}
+
+/*
+** Generate VDBE code for zero or more statements inside the body of a
+** trigger.
+*/
+static int codeTriggerProgram(
+ Parse *pParse, /* The parser context */
+ TriggerStep *pStepList, /* List of statements inside the trigger body */
+ int orconfin /* Conflict algorithm. (OE_Abort, etc) */
+){
+ TriggerStep * pTriggerStep = pStepList;
+ int orconf;
+ Vdbe *v = pParse->pVdbe;
+
+ assert( pTriggerStep!=0 );
+ assert( v!=0 );
+ sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0);
+ VdbeComment((v, "# begin trigger %s", pStepList->pTrig->name));
+ while( pTriggerStep ){
+ orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
+ pParse->trigStack->orconf = orconf;
+ switch( pTriggerStep->op ){
+ case TK_SELECT: {
+ Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);
+ assert(ss);
+ assert(ss->pSrc);
+ sqlite3SelectResolve(pParse, ss, 0);
+ sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
+ sqlite3SelectDelete(ss);
+ break;
+ }
+ case TK_UPDATE: {
+ SrcList *pSrc;
+ pSrc = targetSrcList(pParse, pTriggerStep);
+ sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
+ sqlite3Update(pParse, pSrc,
+ sqlite3ExprListDup(pTriggerStep->pExprList),
+ sqlite3ExprDup(pTriggerStep->pWhere), orconf);
+ sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
+ break;
+ }
+ case TK_INSERT: {
+ SrcList *pSrc;
+ pSrc = targetSrcList(pParse, pTriggerStep);
+ sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
+ sqlite3Insert(pParse, pSrc,
+ sqlite3ExprListDup(pTriggerStep->pExprList),
+ sqlite3SelectDup(pTriggerStep->pSelect),
+ sqlite3IdListDup(pTriggerStep->pIdList), orconf);
+ sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
+ break;
+ }
+ case TK_DELETE: {
+ SrcList *pSrc;
+ sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
+ pSrc = targetSrcList(pParse, pTriggerStep);
+ sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(pTriggerStep->pWhere));
+ sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
+ break;
+ }
+ default:
+ assert(0);
+ }
+ pTriggerStep = pTriggerStep->pNext;
+ }
+ sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
+ VdbeComment((v, "# end trigger %s", pStepList->pTrig->name));
+
+ return 0;
+}
+
+/*
+** This is called to code FOR EACH ROW triggers.
+**
+** When the code that this function generates is executed, the following
+** must be true:
+**
+** 1. No cursors may be open in the main database. (But newIdx and oldIdx
+** can be indices of cursors in temporary tables. See below.)
+**
+** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
+** a temporary vdbe cursor (index newIdx) must be open and pointing at
+** a row containing values to be substituted for new.* expressions in the
+** trigger program(s).
+**
+** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
+** a temporary vdbe cursor (index oldIdx) must be open and pointing at
+** a row containing values to be substituted for old.* expressions in the
+** trigger program(s).
+**
+*/
+int sqlite3CodeRowTrigger(
+ Parse *pParse, /* Parse context */
+ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
+ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
+ int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
+ Table *pTab, /* The table to code triggers from */
+ int newIdx, /* The indice of the "new" row to access */
+ int oldIdx, /* The indice of the "old" row to access */
+ int orconf, /* ON CONFLICT policy */
+ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
+){
+ Trigger *pTrigger;
+ TriggerStack *pStack;
+ TriggerStack trigStackEntry;
+
+ assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
+ assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );
+
+ assert(newIdx != -1 || oldIdx != -1);
+
+ pTrigger = pTab->pTrigger;
+ while( pTrigger ){
+ int fire_this = 0;
+
+ /* determine whether we should code this trigger */
+ if( pTrigger->op == op && pTrigger->tr_tm == tr_tm ){
+ fire_this = 1;
+ for(pStack=pParse->trigStack; pStack; pStack=pStack->pNext){
+ if( pStack->pTrigger==pTrigger ){
+ fire_this = 0;
+ }
+ }
+ if( op == TK_UPDATE && pTrigger->pColumns &&
+ !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
+ fire_this = 0;
+ }
+ }
+
+ if( fire_this ){
+ int endTrigger;
+ Expr * whenExpr;
+ AuthContext sContext;
+ NameContext sNC;
+
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+
+ /* Push an entry on to the trigger stack */
+ trigStackEntry.pTrigger = pTrigger;
+ trigStackEntry.newIdx = newIdx;
+ trigStackEntry.oldIdx = oldIdx;
+ trigStackEntry.pTab = pTab;
+ trigStackEntry.pNext = pParse->trigStack;
+ trigStackEntry.ignoreJump = ignoreJump;
+ pParse->trigStack = &trigStackEntry;
+ sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);
+
+ /* code the WHEN clause */
+ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
+ whenExpr = sqlite3ExprDup(pTrigger->pWhen);
+ if( sqlite3ExprResolveNames(&sNC, whenExpr) ){
+ pParse->trigStack = trigStackEntry.pNext;
+ sqlite3ExprDelete(whenExpr);
+ return 1;
+ }
+ sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
+ sqlite3ExprDelete(whenExpr);
+
+ codeTriggerProgram(pParse, pTrigger->step_list, orconf);
+
+ /* Pop the entry off the trigger stack */
+ pParse->trigStack = trigStackEntry.pNext;
+ sqlite3AuthContextPop(&sContext);
+
+ sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
+ }
+ pTrigger = pTrigger->pNext;
+ }
+ return 0;
+}
+#endif /* !defined(SQLITE_OMIT_TRIGGER) */
diff --git a/src/sqlite/update.c b/src/sqlite/update.c
new file mode 100644
index 0000000..47bfe13
--- /dev/null
+++ b/src/sqlite/update.c
@@ -0,0 +1,505 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains C code routines that are called by the parser
+** to handle UPDATE statements.
+**
+** $Id: update.c,v 1.1.1.1 2006/02/03 20:35:11 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** The most recently coded instruction was an OP_Column to retrieve column
+** 'i' of table pTab. This routine sets the P3 parameter of the
+** OP_Column to the default value, if any.
+**
+** The default value of a column is specified by a DEFAULT clause in the
+** column definition. This was either supplied by the user when the table
+** was created, or added later to the table definition by an ALTER TABLE
+** command. If the latter, then the row-records in the table btree on disk
+** may not contain a value for the column and the default value, taken
+** from the P3 parameter of the OP_Column instruction, is returned instead.
+** If the former, then all row-records are guaranteed to include a value
+** for the column and the P3 value is not required.
+**
+** Column definitions created by an ALTER TABLE command may only have
+** literal default values specified: a number, null or a string. (If a more
+** complicated default expression value was provided, it is evaluated
+** when the ALTER TABLE is executed and one of the literal values written
+** into the sqlite_master table.)
+**
+** Therefore, the P3 parameter is only required if the default value for
+** the column is a literal number, string or null. The sqlite3ValueFromExpr()
+** function is capable of transforming these types of expressions into
+** sqlite3_value objects.
+*/
+void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
+ if( pTab && !pTab->pSelect ){
+ sqlite3_value *pValue;
+ 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);
+ }
+}
+
+/*
+** Process an UPDATE statement.
+**
+** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
+** \_______/ \________/ \______/ \________________/
+* onError pTabList pChanges pWhere
+*/
+void sqlite3Update(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* The table in which we should change things */
+ ExprList *pChanges, /* Things to be changed */
+ Expr *pWhere, /* The WHERE clause. May be null */
+ int onError /* How to handle constraint errors */
+){
+ int i, j; /* Loop counters */
+ Table *pTab; /* The table to be updated */
+ int addr = 0; /* VDBE instruction address of the start of the loop */
+ WhereInfo *pWInfo; /* Information about the WHERE clause */
+ Vdbe *v; /* The virtual database engine */
+ Index *pIdx; /* For looping over indices */
+ int nIdx; /* Number of indices that need updating */
+ int nIdxTotal; /* Total number of indices */
+ int iCur; /* VDBE Cursor number of pTab */
+ sqlite3 *db; /* The database structure */
+ Index **apIdx = 0; /* An array of indices that need updating too */
+ char *aIdxUsed = 0; /* aIdxUsed[i]==1 if the i-th index is used */
+ int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
+ ** an expression for the i-th column of the table.
+ ** aXRef[i]==-1 if the i-th column is not changed. */
+ int chngRowid; /* True if the record number is being changed */
+ Expr *pRowidExpr = 0; /* Expression defining the new record number */
+ int openAll = 0; /* True if all indices need to be opened */
+ AuthContext sContext; /* The authorization context */
+ NameContext sNC; /* The name-context to resolve expressions in */
+
+#ifndef SQLITE_OMIT_TRIGGER
+ int isView; /* Trying to update a view */
+ int triggers_exist = 0; /* True if any row triggers exist */
+#endif
+
+ int newIdx = -1; /* index of trigger "new" temp table */
+ int oldIdx = -1; /* index of trigger "old" temp table */
+
+ sContext.pParse = 0;
+ if( pParse->nErr || sqlite3_malloc_failed ) goto update_cleanup;
+ db = pParse->db;
+ assert( pTabList->nSrc==1 );
+
+ /* Locate the table which we want to update.
+ */
+ pTab = sqlite3SrcListLookup(pParse, pTabList);
+ if( pTab==0 ) goto update_cleanup;
+
+ /* Figure out if we have any triggers and if the table being
+ ** updated is a view
+ */
+#ifndef SQLITE_OMIT_TRIGGER
+ triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges);
+ isView = pTab->pSelect!=0;
+#else
+# define triggers_exist 0
+# define isView 0
+#endif
+#ifdef SQLITE_OMIT_VIEW
+# undef isView
+# define isView 0
+#endif
+
+ if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
+ goto update_cleanup;
+ }
+ if( isView ){
+ if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+ goto update_cleanup;
+ }
+ }
+ aXRef = sqliteMallocRaw( sizeof(int) * pTab->nCol );
+ if( aXRef==0 ) goto update_cleanup;
+ for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
+
+ /* If there are FOR EACH ROW triggers, allocate cursors for the
+ ** special OLD and NEW tables
+ */
+ if( triggers_exist ){
+ newIdx = pParse->nTab++;
+ oldIdx = pParse->nTab++;
+ }
+
+ /* Allocate a cursors for the main database table and for all indices.
+ ** The index cursors might not be used, but if they are used they
+ ** need to occur right after the database cursor. So go ahead and
+ ** allocate enough space, just in case.
+ */
+ pTabList->a[0].iCursor = iCur = pParse->nTab++;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ pParse->nTab++;
+ }
+
+ /* Initialize the name-context */
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ sNC.pSrcList = pTabList;
+
+ /* Resolve the column names in all the expressions of the
+ ** of the UPDATE statement. Also find the column index
+ ** for each column to be updated in the pChanges array. For each
+ ** column to be updated, make sure we have authorization to change
+ ** that column.
+ */
+ chngRowid = 0;
+ for(i=0; i<pChanges->nExpr; i++){
+ if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
+ goto update_cleanup;
+ }
+ for(j=0; j<pTab->nCol; j++){
+ if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
+ if( j==pTab->iPKey ){
+ chngRowid = 1;
+ pRowidExpr = pChanges->a[i].pExpr;
+ }
+ aXRef[j] = i;
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( sqlite3IsRowid(pChanges->a[i].zName) ){
+ chngRowid = 1;
+ pRowidExpr = pChanges->a[i].pExpr;
+ }else{
+ sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
+ goto update_cleanup;
+ }
+ }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ {
+ int rc;
+ rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
+ pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
+ if( rc==SQLITE_DENY ){
+ goto update_cleanup;
+ }else if( rc==SQLITE_IGNORE ){
+ aXRef[j] = -1;
+ }
+ }
+#endif
+ }
+
+ /* Allocate memory for the array apIdx[] and fill it with pointers to every
+ ** index that needs to be updated. Indices only need updating if their
+ ** key includes one of the columns named in pChanges or if the record
+ ** number of the original table entry is changing.
+ */
+ for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
+ if( chngRowid ){
+ i = 0;
+ }else {
+ for(i=0; i<pIdx->nColumn; i++){
+ if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
+ }
+ }
+ if( i<pIdx->nColumn ) nIdx++;
+ }
+ if( nIdxTotal>0 ){
+ apIdx = sqliteMallocRaw( sizeof(Index*) * nIdx + nIdxTotal );
+ if( apIdx==0 ) goto update_cleanup;
+ aIdxUsed = (char*)&apIdx[nIdx];
+ }
+ for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( chngRowid ){
+ i = 0;
+ }else{
+ for(i=0; i<pIdx->nColumn; i++){
+ if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
+ }
+ }
+ if( i<pIdx->nColumn ){
+ if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto update_cleanup;
+ apIdx[nIdx++] = pIdx;
+ aIdxUsed[j] = 1;
+ }else{
+ aIdxUsed[j] = 0;
+ }
+ }
+
+ /* Resolve the column names in all the expressions in the
+ ** WHERE clause.
+ */
+ if( sqlite3ExprResolveNames(&sNC, pWhere) ){
+ goto update_cleanup;
+ }
+
+ /* Start the view context
+ */
+ if( isView ){
+ sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
+ }
+
+ /* Begin generating code.
+ */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto update_cleanup;
+ if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+ sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);
+
+ /* If we are trying to update a view, construct that view into
+ ** a temporary table.
+ */
+ if( isView ){
+ Select *pView;
+ pView = sqlite3SelectDup(pTab->pSelect);
+ sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0);
+ sqlite3SelectDelete(pView);
+ }
+
+ /* Begin the database scan
+ */
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
+ if( pWInfo==0 ) goto update_cleanup;
+
+ /* Remember the index of every item to be updated.
+ */
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
+
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+
+ /* Initialize the count of updated rows
+ */
+ if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
+ sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+ }
+
+ if( triggers_exist ){
+ /* Create pseudo-tables for NEW and OLD
+ */
+ sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
+ sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
+
+ /* The top of the update loop for when there are triggers.
+ */
+ sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
+ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
+
+ if( !isView ){
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ /* Open a cursor and make it point to the record that is
+ ** being updated.
+ */
+ sqlite3OpenTableForReading(v, iCur, pTab);
+ }
+ sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
+
+ /* Generate the OLD table
+ */
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
+ sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
+
+ /* Generate the NEW table
+ */
+ if( chngRowid ){
+ sqlite3ExprCodeAndCache(pParse, pRowidExpr);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ }
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ continue;
+ }
+ j = aXRef[i];
+ if( j<0 ){
+ sqlite3VdbeAddOp(v, OP_Column, iCur, i);
+ sqlite3ColumnDefault(v, pTab, i);
+ }else{
+ sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ if( !isView ){
+ sqlite3TableAffinityStr(v, pTab);
+ }
+ if( pParse->nErr ) goto update_cleanup;
+ sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
+ if( !isView ){
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+
+ /* Fire the BEFORE and INSTEAD OF triggers
+ */
+ if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
+ newIdx, oldIdx, onError, addr) ){
+ goto update_cleanup;
+ }
+ }
+
+ if( !isView ){
+ /*
+ ** Open every index that needs updating. Note that if any
+ ** index could potentially invoke a REPLACE conflict resolution
+ ** action, then we need to open all indices because we might need
+ ** to be deleting some records.
+ */
+ sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
+ if( onError==OE_Replace ){
+ openAll = 1;
+ }else{
+ openAll = 0;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->onError==OE_Replace ){
+ openAll = 1;
+ break;
+ }
+ }
+ }
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( openAll || aIdxUsed[i] ){
+ sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
+ (char*)&pIdx->keyInfo, P3_KEYINFO);
+ assert( pParse->nTab>iCur+i+1 );
+ }
+ }
+
+ /* Loop over every record that needs updating. We have to load
+ ** the old data for each record to be updated because some columns
+ ** might not change and we will need to copy the old value.
+ ** Also, the old data is needed to delete the old index entires.
+ ** 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);
+ sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
+ }
+ sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
+
+ /* If the record number will change, push the record number as it
+ ** will be after the update. (The old record number is currently
+ ** on top of the stack.)
+ */
+ if( chngRowid ){
+ sqlite3ExprCode(pParse, pRowidExpr);
+ sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+ }
+
+ /* Compute new data for this record.
+ */
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ continue;
+ }
+ j = aXRef[i];
+ if( j<0 ){
+ sqlite3VdbeAddOp(v, OP_Column, iCur, i);
+ sqlite3ColumnDefault(v, pTab, i);
+ }else{
+ sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
+ }
+ }
+
+ /* Do constraint checks
+ */
+ sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1,
+ onError, addr);
+
+ /* Delete the old indices for the current record.
+ */
+ sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
+
+ /* If changing the record number, delete the old record.
+ */
+ if( chngRowid ){
+ sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
+ }
+
+ /* Create the new index entries and the new record.
+ */
+ sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1);
+ }
+
+ /* Increment the row counter
+ */
+ if( db->flags & SQLITE_CountRows && !pParse->trigStack){
+ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
+ }
+
+ /* If there are triggers, close all the cursors after each iteration
+ ** through the loop. The fire the after triggers.
+ */
+ if( triggers_exist ){
+ if( !isView ){
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( openAll || aIdxUsed[i] )
+ sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
+ }
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }
+ if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab,
+ newIdx, oldIdx, onError, addr) ){
+ goto update_cleanup;
+ }
+ }
+
+ /* Repeat the above with the next record to be updated, until
+ ** all record selected by the WHERE clause have been updated.
+ */
+ 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 ){
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( openAll || aIdxUsed[i] ){
+ sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
+ sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
+ }
+
+ /*
+ ** Return the number of rows that were changed. If this routine is
+ ** generating code because of a call to sqlite3NestedParse(), do not
+ ** invoke the callback function.
+ */
+ if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
+ sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, "rows updated", P3_STATIC);
+ }
+
+update_cleanup:
+ sqlite3AuthContextPop(&sContext);
+ sqliteFree(apIdx);
+ sqliteFree(aXRef);
+ sqlite3SrcListDelete(pTabList);
+ sqlite3ExprListDelete(pChanges);
+ sqlite3ExprDelete(pWhere);
+ return;
+}
diff --git a/src/sqlite/utf.c b/src/sqlite/utf.c
new file mode 100644
index 0000000..bc94009
--- /dev/null
+++ b/src/sqlite/utf.c
@@ -0,0 +1,570 @@
+/*
+** 2004 April 13
+**
+** 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 routines used to translate between UTF-8,
+** UTF-16, UTF-16BE, and UTF-16LE.
+**
+** $Id: utf.c,v 1.1.1.1 2006/02/03 20:35:10 hoganrobert Exp $
+**
+** Notes on UTF-8:
+**
+** Byte-0 Byte-1 Byte-2 Byte-3 Value
+** 0xxxxxxx 00000000 00000000 0xxxxxxx
+** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx
+** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx
+** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx
+**
+**
+** Notes on UTF-16: (with wwww+1==uuuuu)
+**
+** Word-0 Word-1 Value
+** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx
+** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx
+**
+**
+** BOM or Byte Order Mark:
+** 0xff 0xfe little-endian utf-16 follows
+** 0xfe 0xff big-endian utf-16 follows
+**
+**
+** Handling of malformed strings:
+**
+** SQLite accepts and processes malformed strings without an error wherever
+** possible. However this is not possible when converting between UTF-8 and
+** UTF-16.
+**
+** When converting malformed UTF-8 strings to UTF-16, one instance of the
+** replacement character U+FFFD for each byte that cannot be interpeted as
+** part of a valid unicode character.
+**
+** When converting malformed UTF-16 strings to UTF-8, one instance of the
+** replacement character U+FFFD for each pair of bytes that cannot be
+** interpeted as part of a valid unicode character.
+**
+** This file contains the following public routines:
+**
+** sqlite3VdbeMemTranslate() - Translate the encoding used by a Mem* string.
+** sqlite3VdbeMemHandleBom() - Handle byte-order-marks in UTF16 Mem* strings.
+** sqlite3utf16ByteLen() - Calculate byte-length of a void* UTF16 string.
+** sqlite3utf8CharLen() - Calculate char-length of a char* UTF8 string.
+** sqlite3utf8LikeCompare() - Do a LIKE match given two UTF8 char* strings.
+**
+*/
+#include "sqliteInt.h"
+#include <assert.h>
+#include "vdbeInt.h"
+
+/*
+** This table maps from the first byte of a UTF-8 character to the number
+** of trailing bytes expected. A value '255' indicates that the table key
+** is not a legal first byte for a UTF-8 character.
+*/
+static const u8 xtra_utf8_bytes[256] = {
+/* 0xxxxxxx */
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* 10wwwwww */
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+
+/* 110yyyyy */
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+/* 1110zzzz */
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+
+/* 11110yyy */
+3, 3, 3, 3, 3, 3, 3, 3, 255, 255, 255, 255, 255, 255, 255, 255,
+};
+
+/*
+** This table maps from the number of trailing bytes in a UTF-8 character
+** to an integer constant that is effectively calculated for each character
+** read by a naive implementation of a UTF-8 character reader. The code
+** in the READ_UTF8 macro explains things best.
+*/
+static const int xtra_utf8_bits[4] = {
+0,
+12416, /* (0xC0 << 6) + (0x80) */
+925824, /* (0xE0 << 12) + (0x80 << 6) + (0x80) */
+63447168 /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
+};
+
+#define READ_UTF8(zIn, c) { \
+ int xtra; \
+ c = *(zIn)++; \
+ xtra = xtra_utf8_bytes[c]; \
+ switch( xtra ){ \
+ case 255: c = (int)0xFFFD; break; \
+ case 3: c = (c<<6) + *(zIn)++; \
+ case 2: c = (c<<6) + *(zIn)++; \
+ case 1: c = (c<<6) + *(zIn)++; \
+ c -= xtra_utf8_bits[xtra]; \
+ } \
+}
+int sqlite3ReadUtf8(const unsigned char *z){
+ int c;
+ READ_UTF8(z, c);
+ return c;
+}
+
+#define SKIP_UTF8(zIn) { \
+ zIn += (xtra_utf8_bytes[*(u8 *)zIn] + 1); \
+}
+
+#define WRITE_UTF8(zOut, c) { \
+ if( c<0x00080 ){ \
+ *zOut++ = (c&0xFF); \
+ } \
+ else if( c<0x00800 ){ \
+ *zOut++ = 0xC0 + ((c>>6)&0x1F); \
+ *zOut++ = 0x80 + (c & 0x3F); \
+ } \
+ else if( c<0x10000 ){ \
+ *zOut++ = 0xE0 + ((c>>12)&0x0F); \
+ *zOut++ = 0x80 + ((c>>6) & 0x3F); \
+ *zOut++ = 0x80 + (c & 0x3F); \
+ }else{ \
+ *zOut++ = 0xF0 + ((c>>18) & 0x07); \
+ *zOut++ = 0x80 + ((c>>12) & 0x3F); \
+ *zOut++ = 0x80 + ((c>>6) & 0x3F); \
+ *zOut++ = 0x80 + (c & 0x3F); \
+ } \
+}
+
+#define WRITE_UTF16LE(zOut, c) { \
+ if( c<=0xFFFF ){ \
+ *zOut++ = (c&0x00FF); \
+ *zOut++ = ((c>>8)&0x00FF); \
+ }else{ \
+ *zOut++ = (((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
+ *zOut++ = (0x00D8 + (((c-0x10000)>>18)&0x03)); \
+ *zOut++ = (c&0x00FF); \
+ *zOut++ = (0x00DC + ((c>>8)&0x03)); \
+ } \
+}
+
+#define WRITE_UTF16BE(zOut, c) { \
+ if( c<=0xFFFF ){ \
+ *zOut++ = ((c>>8)&0x00FF); \
+ *zOut++ = (c&0x00FF); \
+ }else{ \
+ *zOut++ = (0x00D8 + (((c-0x10000)>>18)&0x03)); \
+ *zOut++ = (((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
+ *zOut++ = (0x00DC + ((c>>8)&0x03)); \
+ *zOut++ = (c&0x00FF); \
+ } \
+}
+
+#define READ_UTF16LE(zIn, c){ \
+ c = (*zIn++); \
+ c += ((*zIn++)<<8); \
+ if( c>=0xD800 && c<=0xE000 ){ \
+ int c2 = (*zIn++); \
+ c2 += ((*zIn++)<<8); \
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
+ } \
+}
+
+#define READ_UTF16BE(zIn, c){ \
+ c = ((*zIn++)<<8); \
+ c += (*zIn++); \
+ if( c>=0xD800 && c<=0xE000 ){ \
+ int c2 = ((*zIn++)<<8); \
+ c2 += (*zIn++); \
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
+ } \
+}
+
+#define SKIP_UTF16BE(zIn){ \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn+1)==0x00)) ){ \
+ zIn += 4; \
+ }else{ \
+ zIn += 2; \
+ } \
+}
+#define SKIP_UTF16LE(zIn){ \
+ zIn++; \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn-1)==0x00)) ){ \
+ zIn += 3; \
+ }else{ \
+ zIn += 1; \
+ } \
+}
+
+#define RSKIP_UTF16LE(zIn){ \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn-1)==0x00)) ){ \
+ zIn -= 4; \
+ }else{ \
+ zIn -= 2; \
+ } \
+}
+#define RSKIP_UTF16BE(zIn){ \
+ zIn--; \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn+1)==0x00)) ){ \
+ zIn -= 3; \
+ }else{ \
+ zIn -= 1; \
+ } \
+}
+
+/*
+** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
+** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
+*/
+/* #define TRANSLATE_TRACE 1 */
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** This routine transforms the internal text encoding used by pMem to
+** desiredEnc. It is an error if the string is already of the desired
+** encoding, or if *pMem does not contain a string value.
+*/
+int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
+ unsigned char zShort[NBFS]; /* Temporary short output buffer */
+ int len; /* Maximum length of output string in bytes */
+ unsigned char *zOut; /* Output buffer */
+ unsigned char *zIn; /* Input iterator */
+ unsigned char *zTerm; /* End of input */
+ unsigned char *z; /* Output iterator */
+ int c;
+
+ assert( pMem->flags&MEM_Str );
+ assert( pMem->enc!=desiredEnc );
+ assert( pMem->enc!=0 );
+ assert( pMem->n>=0 );
+
+#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
+ {
+ char zBuf[100];
+ sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
+ fprintf(stderr, "INPUT: %s\n", zBuf);
+ }
+#endif
+
+ /* If the translation is between UTF-16 little and big endian, then
+ ** all that is required is to swap the byte order. This case is handled
+ ** differently from the others.
+ */
+ if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
+ u8 temp;
+ int rc;
+ rc = sqlite3VdbeMemMakeWriteable(pMem);
+ if( rc!=SQLITE_OK ){
+ assert( rc==SQLITE_NOMEM );
+ return SQLITE_NOMEM;
+ }
+ zIn = pMem->z;
+ zTerm = &zIn[pMem->n];
+ while( zIn<zTerm ){
+ temp = *zIn;
+ *zIn = *(zIn+1);
+ zIn++;
+ *zIn++ = temp;
+ }
+ pMem->enc = desiredEnc;
+ goto translate_out;
+ }
+
+ /* Set len to the maximum number of bytes required in the output buffer. */
+ if( desiredEnc==SQLITE_UTF8 ){
+ /* When converting from UTF-16, the maximum growth results from
+ ** translating a 2-byte character to a 3-byte UTF-8 character (i.e.
+ ** code-point 0xFFFC). A single byte is required for the output string
+ ** nul-terminator.
+ */
+ len = (pMem->n/2) * 3 + 1;
+ }else{
+ /* When converting from UTF-8 to UTF-16 the maximum growth is caused
+ ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
+ ** character. Two bytes are required in the output buffer for the
+ ** nul-terminator.
+ */
+ len = pMem->n * 2 + 2;
+ }
+
+ /* Set zIn to point at the start of the input buffer and zTerm to point 1
+ ** byte past the end.
+ **
+ ** Variable zOut is set to point at the output buffer. This may be space
+ ** obtained from malloc(), or Mem.zShort, if it large enough and not in
+ ** use, or the zShort array on the stack (see above).
+ */
+ zIn = pMem->z;
+ zTerm = &zIn[pMem->n];
+ if( len>NBFS ){
+ zOut = sqliteMallocRaw(len);
+ if( !zOut ) return SQLITE_NOMEM;
+ }else{
+ zOut = zShort;
+ }
+ z = zOut;
+
+ if( pMem->enc==SQLITE_UTF8 ){
+ if( desiredEnc==SQLITE_UTF16LE ){
+ /* UTF-8 -> UTF-16 Little-endian */
+ while( zIn<zTerm ){
+ READ_UTF8(zIn, c);
+ WRITE_UTF16LE(z, c);
+ }
+ }else{
+ assert( desiredEnc==SQLITE_UTF16BE );
+ /* UTF-8 -> UTF-16 Big-endian */
+ while( zIn<zTerm ){
+ READ_UTF8(zIn, c);
+ WRITE_UTF16BE(z, c);
+ }
+ }
+ pMem->n = z - zOut;
+ *z++ = 0;
+ }else{
+ assert( desiredEnc==SQLITE_UTF8 );
+ if( pMem->enc==SQLITE_UTF16LE ){
+ /* UTF-16 Little-endian -> UTF-8 */
+ while( zIn<zTerm ){
+ READ_UTF16LE(zIn, c);
+ WRITE_UTF8(z, c);
+ }
+ }else{
+ /* UTF-16 Little-endian -> UTF-8 */
+ while( zIn<zTerm ){
+ READ_UTF16BE(zIn, c);
+ WRITE_UTF8(z, c);
+ }
+ }
+ pMem->n = z - zOut;
+ }
+ *z = 0;
+ assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
+
+ sqlite3VdbeMemRelease(pMem);
+ pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
+ pMem->enc = desiredEnc;
+ if( zOut==zShort ){
+ memcpy(pMem->zShort, zOut, len);
+ zOut = pMem->zShort;
+ pMem->flags |= (MEM_Term|MEM_Short);
+ }else{
+ pMem->flags |= (MEM_Term|MEM_Dyn);
+ }
+ pMem->z = zOut;
+
+translate_out:
+#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
+ {
+ char zBuf[100];
+ sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
+ fprintf(stderr, "OUTPUT: %s\n", zBuf);
+ }
+#endif
+ return SQLITE_OK;
+}
+
+/*
+** This routine checks for a byte-order mark at the beginning of the
+** UTF-16 string stored in *pMem. If one is present, it is removed and
+** the encoding of the Mem adjusted. This routine does not do any
+** byte-swapping, it just sets Mem.enc appropriately.
+**
+** The allocation (static, dynamic etc.) and encoding of the Mem may be
+** changed by this function.
+*/
+int sqlite3VdbeMemHandleBom(Mem *pMem){
+ int rc = SQLITE_OK;
+ u8 bom = 0;
+
+ if( pMem->n<0 || pMem->n>1 ){
+ u8 b1 = *(u8 *)pMem->z;
+ u8 b2 = *(((u8 *)pMem->z) + 1);
+ if( b1==0xFE && b2==0xFF ){
+ bom = SQLITE_UTF16BE;
+ }
+ if( b1==0xFF && b2==0xFE ){
+ bom = SQLITE_UTF16LE;
+ }
+ }
+
+ if( bom ){
+ /* This function is called as soon as a string is stored in a Mem*,
+ ** from within sqlite3VdbeMemSetStr(). At that point it is not possible
+ ** for the string to be stored in Mem.zShort, or for it to be stored
+ ** in dynamic memory with no destructor.
+ */
+ assert( !(pMem->flags&MEM_Short) );
+ assert( !(pMem->flags&MEM_Dyn) || pMem->xDel );
+ if( pMem->flags & MEM_Dyn ){
+ void (*xDel)(void*) = pMem->xDel;
+ char *z = pMem->z;
+ pMem->z = 0;
+ pMem->xDel = 0;
+ rc = sqlite3VdbeMemSetStr(pMem, &z[2], pMem->n-2, bom, SQLITE_TRANSIENT);
+ xDel(z);
+ }else{
+ rc = sqlite3VdbeMemSetStr(pMem, &pMem->z[2], pMem->n-2, bom,
+ SQLITE_TRANSIENT);
+ }
+ }
+ return rc;
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+/*
+** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
+** return the number of unicode characters in pZ up to (but not including)
+** the first 0x00 byte. If nByte is not less than zero, return the
+** number of unicode characters in the first nByte of pZ (or up to
+** the first 0x00, whichever comes first).
+*/
+int sqlite3utf8CharLen(const char *z, int nByte){
+ int r = 0;
+ const char *zTerm;
+ if( nByte>=0 ){
+ zTerm = &z[nByte];
+ }else{
+ zTerm = (const char *)(-1);
+ }
+ assert( z<=zTerm );
+ while( *z!=0 && z<zTerm ){
+ SKIP_UTF8(z);
+ r++;
+ }
+ return r;
+}
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** pZ is a UTF-16 encoded unicode string. If nChar is less than zero,
+** return the number of bytes up to (but not including), the first pair
+** of consecutive 0x00 bytes in pZ. If nChar is not less than zero,
+** then return the number of bytes in the first nChar unicode characters
+** in pZ (or up until the first pair of 0x00 bytes, whichever comes first).
+*/
+int sqlite3utf16ByteLen(const void *zIn, int nChar){
+ int c = 1;
+ char const *z = zIn;
+ int n = 0;
+ if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
+ while( c && ((nChar<0) || n<nChar) ){
+ READ_UTF16BE(z, c);
+ n++;
+ }
+ }else{
+ while( c && ((nChar<0) || n<nChar) ){
+ READ_UTF16LE(z, c);
+ n++;
+ }
+ }
+ return (z-(char const *)zIn)-((c==0)?2:0);
+}
+
+/*
+** UTF-16 implementation of the substr()
+*/
+void sqlite3utf16Substr(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int y, z;
+ unsigned char const *zStr;
+ unsigned char const *zStrEnd;
+ unsigned char const *zStart;
+ unsigned char const *zEnd;
+ int i;
+
+ zStr = (unsigned char const *)sqlite3_value_text16(argv[0]);
+ zStrEnd = &zStr[sqlite3_value_bytes16(argv[0])];
+ y = sqlite3_value_int(argv[1]);
+ z = sqlite3_value_int(argv[2]);
+
+ if( y>0 ){
+ y = y-1;
+ zStart = zStr;
+ if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
+ for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16BE(zStart);
+ }else{
+ for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16LE(zStart);
+ }
+ }else{
+ zStart = zStrEnd;
+ if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
+ for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16BE(zStart);
+ }else{
+ for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16LE(zStart);
+ }
+ for(; i<0; i++) z -= 1;
+ }
+
+ zEnd = zStart;
+ if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
+ for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16BE(zEnd);
+ }else{
+ for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16LE(zEnd);
+ }
+
+ sqlite3_result_text16(context, zStart, zEnd-zStart, SQLITE_TRANSIENT);
+}
+
+#if defined(SQLITE_TEST)
+/*
+** This routine is called from the TCL test function "translate_selftest".
+** It checks that the primitives for serializing and deserializing
+** characters in each encoding are inverses of each other.
+*/
+void sqlite3utfSelfTest(){
+ int i;
+ unsigned char zBuf[20];
+ unsigned char *z;
+ int n;
+ int c;
+
+ for(i=0; i<0x00110000; i++){
+ z = zBuf;
+ WRITE_UTF8(z, i);
+ n = z-zBuf;
+ z = zBuf;
+ READ_UTF8(z, c);
+ assert( c==i );
+ assert( (z-zBuf)==n );
+ }
+ for(i=0; i<0x00110000; i++){
+ if( i>=0xD800 && i<=0xE000 ) continue;
+ z = zBuf;
+ WRITE_UTF16LE(z, i);
+ n = z-zBuf;
+ z = zBuf;
+ READ_UTF16LE(z, c);
+ assert( c==i );
+ assert( (z-zBuf)==n );
+ }
+ for(i=0; i<0x00110000; i++){
+ if( i>=0xD800 && i<=0xE000 ) continue;
+ z = zBuf;
+ WRITE_UTF16BE(z, i);
+ n = z-zBuf;
+ z = zBuf;
+ READ_UTF16BE(z, c);
+ assert( c==i );
+ assert( (z-zBuf)==n );
+ }
+}
+#endif /* SQLITE_TEST */
+#endif /* SQLITE_OMIT_UTF16 */
diff --git a/src/sqlite/util.c b/src/sqlite/util.c
new file mode 100644
index 0000000..02acff4
--- /dev/null
+++ b/src/sqlite/util.c
@@ -0,0 +1,964 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Utility functions used throughout sqlite.
+**
+** This file contains functions for allocating memory, comparing
+** strings, and stuff like that.
+**
+** $Id: util.c,v 1.1.1.1 2006/02/03 20:35:16 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+#if SQLITE_MEMDEBUG>2 && defined(__GLIBC__)
+#include <execinfo.h>
+void print_stack_trace(){
+ void *bt[30];
+ int i;
+ int n = backtrace(bt, 30);
+
+ fprintf(stderr, "STACK: ");
+ for(i=0; i<n;i++){
+ fprintf(stderr, "%p ", bt[i]);
+ }
+ fprintf(stderr, "\n");
+}
+#else
+#define print_stack_trace()
+#endif
+
+/*
+** If malloc() ever fails, this global variable gets set to 1.
+** This causes the library to abort and never again function.
+*/
+int sqlite3_malloc_failed = 0;
+
+/*
+** If SQLITE_MEMDEBUG is defined, then use versions of malloc() and
+** free() that track memory usage and check for buffer overruns.
+*/
+#ifdef SQLITE_MEMDEBUG
+
+/*
+** For keeping track of the number of mallocs and frees. This
+** is used to check for memory leaks. The iMallocFail and iMallocReset
+** values are used to simulate malloc() failures during testing in
+** order to verify that the library correctly handles an out-of-memory
+** condition.
+*/
+int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */
+int sqlite3_nFree; /* Number of sqliteFree() calls */
+int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */
+int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */
+#if SQLITE_MEMDEBUG>1
+static int memcnt = 0;
+#endif
+
+/*
+** Number of 32-bit guard words. This should probably be a multiple of
+** 2 since on 64-bit machines we want the value returned by sqliteMalloc()
+** to be 8-byte aligned.
+*/
+#define N_GUARD 2
+
+/*
+** 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( sqlite3_iMallocFail>=0 ){
+ sqlite3_iMallocFail--;
+ if( sqlite3_iMallocFail==0 ){
+ sqlite3_malloc_failed++;
+#if SQLITE_MEMDEBUG>1
+ fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
+ n, zFile,line);
+#endif
+ sqlite3_iMallocFail = sqlite3_iMallocReset;
+ return 0;
+ }
+ }
+ if( n==0 ) return 0;
+ k = (n+sizeof(int)-1)/sizeof(int);
+ pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
+ if( pi==0 ){
+ if( n>0 ) sqlite3_malloc_failed++;
+ return 0;
+ }
+ sqlite3_nMalloc++;
+ for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
+ pi[N_GUARD] = n;
+ for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
+ p = &pi[N_GUARD+1];
+ memset(p, bZero==0, n);
+#if SQLITE_MEMDEBUG>1
+ print_stack_trace();
+ fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
+ ++memcnt, n, (int)p, zFile,line);
+#endif
+ return p;
+}
+
+/*
+** This version of malloc is always a real function, never a macro
+*/
+void *sqlite3MallocX(int n){
+ return sqlite3Malloc_(n, 0, __FILE__, __LINE__);
+}
+
+/*
+** Check to see if the given pointer was obtained from sqliteMalloc()
+** and is able to hold at least N bytes. Raise an exception if this
+** is not the case.
+**
+** This routine is used for testing purposes only.
+*/
+void sqlite3CheckMemory(void *p, int N){
+ int *pi = p;
+ int n, i, k;
+ pi -= N_GUARD+1;
+ for(i=0; i<N_GUARD; i++){
+ assert( pi[i]==0xdead1122 );
+ }
+ n = pi[N_GUARD];
+ assert( N>=0 && N<n );
+ k = (n+sizeof(int)-1)/sizeof(int);
+ for(i=0; i<N_GUARD; i++){
+ assert( pi[k+N_GUARD+1+i]==0xdead3344 );
+ }
+}
+
+/*
+** Free memory previously obtained from sqliteMalloc()
+*/
+void sqlite3Free_(void *p, char *zFile, int line){
+ if( p ){
+ int *pi, i, k, n;
+ pi = p;
+ pi -= N_GUARD+1;
+ sqlite3_nFree++;
+ for(i=0; i<N_GUARD; i++){
+ if( pi[i]!=0xdead1122 ){
+ fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
+ return;
+ }
+ }
+ n = pi[N_GUARD];
+ k = (n+sizeof(int)-1)/sizeof(int);
+ for(i=0; i<N_GUARD; i++){
+ if( pi[k+N_GUARD+1+i]!=0xdead3344 ){
+ fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
+ return;
+ }
+ }
+ memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
+#if SQLITE_MEMDEBUG>1
+ fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
+ ++memcnt, n, (int)p, zFile,line);
+#endif
+ free(pi);
+ }
+}
+
+/*
+** Resize a prior allocation. If p==0, then this routine
+** works just like sqliteMalloc(). If n==0, then this routine
+** works just like sqliteFree().
+*/
+void *sqlite3Realloc_(void *oldP, int n, char *zFile, int line){
+ int *oldPi, *pi, i, k, oldN, oldK;
+ void *p;
+ if( oldP==0 ){
+ return sqlite3Malloc_(n,1,zFile,line);
+ }
+ if( n==0 ){
+ sqlite3Free_(oldP,zFile,line);
+ return 0;
+ }
+ oldPi = oldP;
+ oldPi -= N_GUARD+1;
+ if( oldPi[0]!=0xdead1122 ){
+ fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);
+ return 0;
+ }
+ oldN = oldPi[N_GUARD];
+ oldK = (oldN+sizeof(int)-1)/sizeof(int);
+ for(i=0; i<N_GUARD; i++){
+ if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
+ fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",
+ (int)oldP);
+ return 0;
+ }
+ }
+ k = (n + sizeof(int) - 1)/sizeof(int);
+ pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
+ if( pi==0 ){
+ if( n>0 ) sqlite3_malloc_failed++;
+ return 0;
+ }
+ for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
+ pi[N_GUARD] = n;
+ for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
+ p = &pi[N_GUARD+1];
+ memcpy(p, oldP, n>oldN ? oldN : n);
+ if( n>oldN ){
+ memset(&((char*)p)[oldN], 0x55, n-oldN);
+ }
+ memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
+ free(oldPi);
+#if SQLITE_MEMDEBUG>1
+ print_stack_trace();
+ fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
+ ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);
+#endif
+ return p;
+}
+
+/*
+** Make a copy of a string in memory obtained from sqliteMalloc()
+*/
+char *sqlite3StrDup_(const char *z, char *zFile, int line){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqlite3Malloc_(strlen(z)+1, 0, zFile, line);
+ if( zNew ) strcpy(zNew, z);
+ return zNew;
+}
+char *sqlite3StrNDup_(const char *z, int n, char *zFile, int line){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqlite3Malloc_(n+1, 0, zFile, line);
+ if( zNew ){
+ memcpy(zNew, z, n);
+ zNew[n] = 0;
+ }
+ return zNew;
+}
+
+/*
+** A version of sqliteFree that is always a function, not a macro.
+*/
+void sqlite3FreeX(void *p){
+ sqliteFree(p);
+}
+#endif /* SQLITE_MEMDEBUG */
+
+/*
+** The following versions of malloc() and free() are for use in a
+** normal build.
+*/
+#if !defined(SQLITE_MEMDEBUG)
+
+/*
+** Allocate new memory and set it to zero. Return NULL if
+** no memory is available. See also sqliteMallocRaw().
+*/
+void *sqlite3Malloc(int n){
+ void *p;
+ if( (p = malloc(n))==0 ){
+ if( n>0 ) sqlite3_malloc_failed++;
+ }else{
+ memset(p, 0, n);
+ }
+ return p;
+}
+
+/*
+** Allocate new memory but do not set it to zero. Return NULL if
+** no memory is available. See also sqliteMalloc().
+*/
+void *sqlite3MallocRaw(int n){
+ void *p;
+ if( (p = malloc(n))==0 ){
+ if( n>0 ) sqlite3_malloc_failed++;
+ }
+ return p;
+}
+
+/*
+** Free memory previously obtained from sqliteMalloc()
+*/
+void sqlite3FreeX(void *p){
+ if( p ){
+ free(p);
+ }
+}
+
+/*
+** Resize a prior allocation. If p==0, then this routine
+** works just like sqliteMalloc(). If n==0, then this routine
+** works just like sqliteFree().
+*/
+void *sqlite3Realloc(void *p, int n){
+ void *p2;
+ if( p==0 ){
+ return sqliteMalloc(n);
+ }
+ if( n==0 ){
+ sqliteFree(p);
+ return 0;
+ }
+ p2 = realloc(p, n);
+ if( p2==0 ){
+ if( n>0 ) sqlite3_malloc_failed++;
+ }
+ return p2;
+}
+
+/*
+** Make a copy of a string in memory obtained from sqliteMalloc()
+*/
+char *sqlite3StrDup(const char *z){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqliteMallocRaw(strlen(z)+1);
+ if( zNew ) strcpy(zNew, z);
+ return zNew;
+}
+char *sqlite3StrNDup(const char *z, int n){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqliteMallocRaw(n+1);
+ if( zNew ){
+ memcpy(zNew, z, n);
+ zNew[n] = 0;
+ }
+ return zNew;
+}
+#endif /* !defined(SQLITE_MEMDEBUG) */
+
+/*
+** Create a string from the 2nd and subsequent arguments (up to the
+** first NULL argument), store the string in memory obtained from
+** sqliteMalloc() and make the pointer indicated by the 1st argument
+** point to that string. The 1st argument must either be NULL or
+** point to memory obtained from sqliteMalloc().
+*/
+void sqlite3SetString(char **pz, ...){
+ va_list ap;
+ int nByte;
+ const char *z;
+ char *zResult;
+
+ if( pz==0 ) return;
+ nByte = 1;
+ va_start(ap, pz);
+ while( (z = va_arg(ap, const char*))!=0 ){
+ nByte += strlen(z);
+ }
+ va_end(ap);
+ sqliteFree(*pz);
+ *pz = zResult = sqliteMallocRaw( nByte );
+ if( zResult==0 ){
+ return;
+ }
+ *zResult = 0;
+ va_start(ap, pz);
+ while( (z = va_arg(ap, const char*))!=0 ){
+ strcpy(zResult, z);
+ zResult += strlen(zResult);
+ }
+ va_end(ap);
+#ifdef SQLITE_DEBUG
+#if SQLITE_DEBUG>1
+ fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
+#endif
+#endif
+}
+
+/*
+** Set the most recent error code and error string for the sqlite
+** handle "db". The error code is set to "err_code".
+**
+** If it is not NULL, string zFormat specifies the format of the
+** error string in the style of the printf functions: The following
+** format characters are allowed:
+**
+** %s Insert a string
+** %z A string that should be freed after use
+** %d Insert an integer
+** %T Insert a token
+** %S Insert the first element of a SrcList
+**
+** zFormat and any string tokens that follow it are assumed to be
+** encoded in UTF-8.
+**
+** To clear the most recent error for sqlite handle "db", sqlite3Error
+** should be called with err_code set to SQLITE_OK and zFormat set
+** to NULL.
+*/
+void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
+ if( db && (db->pErr || (db->pErr = sqlite3ValueNew())) ){
+ db->errCode = err_code;
+ if( zFormat ){
+ char *z;
+ va_list ap;
+ va_start(ap, zFormat);
+ z = sqlite3VMPrintf(zFormat, ap);
+ va_end(ap);
+ sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, sqlite3FreeX);
+ }else{
+ sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
+ }
+ }
+}
+
+/*
+** Add an error message to pParse->zErrMsg and increment pParse->nErr.
+** The following formatting characters are allowed:
+**
+** %s Insert a string
+** %z A string that should be freed after use
+** %d Insert an integer
+** %T Insert a token
+** %S Insert the first element of a SrcList
+**
+** This function should be used to report any error that occurs whilst
+** compiling an SQL statement (i.e. within sqlite3_prepare()). The
+** last thing the sqlite3_prepare() function does is copy the error
+** stored by this function into the database handle using sqlite3Error().
+** Function sqlite3Error() should be used during statement execution
+** (sqlite3_step() etc.).
+*/
+void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
+ va_list ap;
+ pParse->nErr++;
+ sqliteFree(pParse->zErrMsg);
+ va_start(ap, zFormat);
+ pParse->zErrMsg = sqlite3VMPrintf(zFormat, ap);
+ va_end(ap);
+}
+
+/*
+** Convert an SQL-style quoted string into a normal string by removing
+** the quote characters. The conversion is done in-place. If the
+** input does not begin with a quote character, then this routine
+** is a no-op.
+**
+** 2002-Feb-14: This routine is extended to remove MS-Access style
+** brackets from around identifers. For example: "[a-b-c]" becomes
+** "a-b-c".
+*/
+void sqlite3Dequote(char *z){
+ int quote;
+ int i, j;
+ if( z==0 ) return;
+ quote = z[0];
+ switch( quote ){
+ case '\'': break;
+ case '"': break;
+ case '[': quote = ']'; break;
+ default: return;
+ }
+ for(i=1, j=0; z[i]; i++){
+ if( z[i]==quote ){
+ if( z[i+1]==quote ){
+ z[j++] = quote;
+ i++;
+ }else{
+ z[j++] = 0;
+ break;
+ }
+ }else{
+ z[j++] = z[i];
+ }
+ }
+}
+
+/* An array to map all upper-case characters into their corresponding
+** lower-case character.
+*/
+const unsigned char sqlite3UpperToLower[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
+ 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
+ 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
+ 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
+ 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+ 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
+ 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
+ 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
+ 252,253,254,255
+};
+#define UpperToLower sqlite3UpperToLower
+
+/*
+** Some systems have stricmp(). Others have strcasecmp(). Because
+** there is no consistency, we will define our own.
+*/
+int sqlite3StrICmp(const char *zLeft, const char *zRight){
+ register unsigned char *a, *b;
+ a = (unsigned char *)zLeft;
+ b = (unsigned char *)zRight;
+ while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+ return UpperToLower[*a] - UpperToLower[*b];
+}
+int sqlite3StrNICmp(const char *zLeft, const char *zRight, int N){
+ register unsigned char *a, *b;
+ a = (unsigned char *)zLeft;
+ b = (unsigned char *)zRight;
+ while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+ return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
+}
+
+/*
+** Return TRUE if z is a pure numeric string. Return FALSE if the
+** string contains any character which is not part of a number. If
+** the string is numeric and contains the '.' character, set *realnum
+** to TRUE (otherwise FALSE).
+**
+** An empty string is considered non-numeric.
+*/
+int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
+ int incr = (enc==SQLITE_UTF8?1:2);
+ if( enc==SQLITE_UTF16BE ) z++;
+ if( *z=='-' || *z=='+' ) z += incr;
+ if( !isdigit(*(u8*)z) ){
+ return 0;
+ }
+ z += incr;
+ if( realnum ) *realnum = 0;
+ while( isdigit(*(u8*)z) ){ z += incr; }
+ if( *z=='.' ){
+ z += incr;
+ if( !isdigit(*(u8*)z) ) return 0;
+ while( isdigit(*(u8*)z) ){ z += incr; }
+ if( realnum ) *realnum = 1;
+ }
+ if( *z=='e' || *z=='E' ){
+ z += incr;
+ if( *z=='+' || *z=='-' ) z += incr;
+ if( !isdigit(*(u8*)z) ) return 0;
+ while( isdigit(*(u8*)z) ){ z += incr; }
+ if( realnum ) *realnum = 1;
+ }
+ return *z==0;
+}
+
+/*
+** The string z[] is an ascii representation of a real number.
+** Convert this string to a double.
+**
+** This routine assumes that z[] really is a valid number. If it
+** is not, the result is undefined.
+**
+** This routine is used instead of the library atof() function because
+** the library atof() might want to use "," as the decimal point instead
+** 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 sign = 1;
+ LONGDOUBLE_TYPE v1 = 0.0;
+ if( *z=='-' ){
+ sign = -1;
+ z++;
+ }else if( *z=='+' ){
+ z++;
+ }
+ while( isdigit(*(u8*)z) ){
+ v1 = v1*10.0 + (*z - '0');
+ z++;
+ }
+ if( *z=='.' ){
+ LONGDOUBLE_TYPE divisor = 1.0;
+ z++;
+ while( isdigit(*(u8*)z) ){
+ v1 = v1*10.0 + (*z - '0');
+ divisor *= 10.0;
+ z++;
+ }
+ v1 /= divisor;
+ }
+ if( *z=='e' || *z=='E' ){
+ int esign = 1;
+ int eval = 0;
+ LONGDOUBLE_TYPE scale = 1.0;
+ z++;
+ if( *z=='-' ){
+ esign = -1;
+ z++;
+ }else if( *z=='+' ){
+ z++;
+ }
+ while( isdigit(*(u8*)z) ){
+ eval = eval*10 + *z - '0';
+ z++;
+ }
+ while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
+ while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
+ while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
+ while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
+ if( esign<0 ){
+ v1 /= scale;
+ }else{
+ v1 *= scale;
+ }
+ }
+ if( pzEnd ) *pzEnd = z;
+ return sign<0 ? -v1 : v1;
+}
+
+/*
+** Return TRUE if zNum is a 64-bit signed integer and write
+** the value of the integer into *pNum. If zNum is not an integer
+** or is an integer that is too large to be expressed with 64 bits,
+** then return false. If n>0 and the integer is string is not
+** exactly n bytes long, return false.
+**
+** When this routine was originally written it dealt with only
+** 32-bit numbers. At that time, it was much faster than the
+** atoi() library routine in RedHat 7.2.
+*/
+int sqlite3atoi64(const char *zNum, i64 *pNum){
+ i64 v = 0;
+ int neg;
+ int i, c;
+ if( *zNum=='-' ){
+ neg = 1;
+ zNum++;
+ }else if( *zNum=='+' ){
+ neg = 0;
+ zNum++;
+ }else{
+ neg = 0;
+ }
+ for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
+ v = v*10 + c - '0';
+ }
+ *pNum = neg ? -v : v;
+ return c==0 && i>0 &&
+ (i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0));
+}
+
+/*
+** The string zNum represents an integer. There might be some other
+** information following the integer too, but that part is ignored.
+** If the integer that the prefix of zNum represents will fit in a
+** 32-bit signed integer, return TRUE. Otherwise return FALSE.
+**
+** This routine returns FALSE for the string -2147483648 even that
+** that number will in fact fit in a 32-bit integer. But positive
+** 2147483648 will not fit in 32 bits. So it seems safer to return
+** false.
+*/
+static int sqlite3FitsIn32Bits(const char *zNum){
+ int i, c;
+ if( *zNum=='-' || *zNum=='+' ) zNum++;
+ for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
+ return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
+}
+
+/*
+** If zNum represents an integer that will fit in 32-bits, then set
+** *pValue to that integer and return true. Otherwise return false.
+*/
+int sqlite3GetInt32(const char *zNum, int *pValue){
+ if( sqlite3FitsIn32Bits(zNum) ){
+ *pValue = atoi(zNum);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+** The string zNum represents an integer. There might be some other
+** information following the integer too, but that part is ignored.
+** If the integer that the prefix of zNum represents will fit in a
+** 64-bit signed integer, return TRUE. Otherwise return FALSE.
+**
+** This routine returns FALSE for the string -9223372036854775808 even that
+** that number will, in theory fit in a 64-bit integer. Positive
+** 9223373036854775808 will not fit in 64 bits. So it seems safer to return
+** false.
+*/
+int sqlite3FitsIn64Bits(const char *zNum){
+ int i, c;
+ if( *zNum=='-' || *zNum=='+' ) zNum++;
+ for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
+ return i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0);
+}
+
+
+/*
+** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
+** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
+** when this routine is called.
+**
+** This routine is a attempt to detect if two threads use the
+** same sqlite* pointer at the same time. There is a race
+** condition so it is possible that the error is not detected.
+** But usually the problem will be seen. The result will be an
+** error which can be used to debug the application that is
+** using SQLite incorrectly.
+**
+** Ticket #202: If db->magic is not a valid open value, take care not
+** to modify the db structure at all. It could be that db is a stale
+** pointer. In other words, it could be that there has been a prior
+** call to sqlite3_close(db) and db has been deallocated. And we do
+** not want to write into deallocated memory.
+*/
+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 ){
+ db->magic = SQLITE_MAGIC_ERROR;
+ db->flags |= SQLITE_Interrupt;
+ }
+ return 1;
+}
+
+/*
+** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
+** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
+** when this routine is called.
+*/
+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 ){
+ db->magic = SQLITE_MAGIC_ERROR;
+ db->flags |= SQLITE_Interrupt;
+ }
+ return 1;
+}
+
+/*
+** Check to make sure we have a valid db pointer. This test is not
+** foolproof but it does provide some measure of protection against
+** misuse of the interface such as passing in db pointers that are
+** NULL or which have been previously closed. If this routine returns
+** TRUE it means that the db pointer is invalid and should not be
+** dereferenced for any reason. The calling function should invoke
+** SQLITE_MISUSE immediately.
+*/
+int sqlite3SafetyCheck(sqlite3 *db){
+ int magic;
+ if( db==0 ) return 1;
+ magic = db->magic;
+ if( magic!=SQLITE_MAGIC_CLOSED &&
+ magic!=SQLITE_MAGIC_OPEN &&
+ magic!=SQLITE_MAGIC_BUSY ) return 1;
+ return 0;
+}
+
+/*
+** The variable-length integer encoding is as follows:
+**
+** KEY:
+** A = 0xxxxxxx 7 bits of data and one flag bit
+** B = 1xxxxxxx 7 bits of data and one flag bit
+** C = xxxxxxxx 8 bits of data
+**
+** 7 bits - A
+** 14 bits - BA
+** 21 bits - BBA
+** 28 bits - BBBA
+** 35 bits - BBBBA
+** 42 bits - BBBBBA
+** 49 bits - BBBBBBA
+** 56 bits - BBBBBBBA
+** 64 bits - BBBBBBBBC
+*/
+
+/*
+** Write a 64-bit variable-length integer to memory starting at p[0].
+** The length of data write will be between 1 and 9 bytes. The number
+** of bytes written is returned.
+**
+** A variable-length integer consists of the lower 7 bits of each byte
+** for all bytes that have the 8th bit set and one byte with the 8th
+** bit clear. Except, if we get to the 9th byte, it stores the full
+** 8 bits and is the last byte.
+*/
+int sqlite3PutVarint(unsigned char *p, u64 v){
+ int i, j, n;
+ u8 buf[10];
+ if( v & (((u64)0xff000000)<<32) ){
+ p[8] = v;
+ v >>= 8;
+ for(i=7; i>=0; i--){
+ p[i] = (v & 0x7f) | 0x80;
+ v >>= 7;
+ }
+ return 9;
+ }
+ n = 0;
+ do{
+ buf[n++] = (v & 0x7f) | 0x80;
+ v >>= 7;
+ }while( v!=0 );
+ buf[0] &= 0x7f;
+ assert( n<=9 );
+ for(i=0, j=n-1; j>=0; j--, i++){
+ p[i] = buf[j];
+ }
+ return n;
+}
+
+/*
+** Read a 64-bit variable-length integer from memory starting at p[0].
+** Return the number of bytes read. The value is stored in *v.
+*/
+int sqlite3GetVarint(const unsigned char *p, u64 *v){
+ u32 x;
+ u64 x64;
+ int n;
+ unsigned char c;
+ if( ((c = p[0]) & 0x80)==0 ){
+ *v = c;
+ return 1;
+ }
+ x = c & 0x7f;
+ if( ((c = p[1]) & 0x80)==0 ){
+ *v = (x<<7) | c;
+ return 2;
+ }
+ x = (x<<7) | (c&0x7f);
+ if( ((c = p[2]) & 0x80)==0 ){
+ *v = (x<<7) | c;
+ return 3;
+ }
+ x = (x<<7) | (c&0x7f);
+ if( ((c = p[3]) & 0x80)==0 ){
+ *v = (x<<7) | c;
+ return 4;
+ }
+ x64 = (x<<7) | (c&0x7f);
+ n = 4;
+ do{
+ c = p[n++];
+ if( n==9 ){
+ x64 = (x64<<8) | c;
+ break;
+ }
+ x64 = (x64<<7) | (c&0x7f);
+ }while( (c & 0x80)!=0 );
+ *v = x64;
+ return n;
+}
+
+/*
+** Read a 32-bit variable-length integer from memory starting at p[0].
+** Return the number of bytes read. The value is stored in *v.
+*/
+int sqlite3GetVarint32(const unsigned char *p, u32 *v){
+ u32 x;
+ int n;
+ unsigned char c;
+ if( ((signed char*)p)[0]>=0 ){
+ *v = p[0];
+ return 1;
+ }
+ x = p[0] & 0x7f;
+ if( ((signed char*)p)[1]>=0 ){
+ *v = (x<<7) | p[1];
+ return 2;
+ }
+ x = (x<<7) | (p[1] & 0x7f);
+ n = 2;
+ do{
+ x = (x<<7) | ((c = p[n++])&0x7f);
+ }while( (c & 0x80)!=0 && n<9 );
+ *v = x;
+ return n;
+}
+
+/*
+** Return the number of bytes that will be needed to store the given
+** 64-bit integer.
+*/
+int sqlite3VarintLen(u64 v){
+ int i = 0;
+ do{
+ i++;
+ v >>= 7;
+ }while( v!=0 && i<9 );
+ return i;
+}
+
+#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) \
+ || defined(SQLITE_TEST)
+/*
+** Translate a single byte of Hex into an integer.
+*/
+static int hexToInt(int h){
+ if( h>='0' && h<='9' ){
+ return h - '0';
+ }else if( h>='a' && h<='f' ){
+ return h - 'a' + 10;
+ }else{
+ assert( h>='A' && h<='F' );
+ return h - 'A' + 10;
+ }
+}
+#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC || SQLITE_TEST */
+
+#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
+/*
+** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
+** value. Return a pointer to its binary value. Space to hold the
+** binary value has been obtained from malloc and must be freed by
+** the calling routine.
+*/
+void *sqlite3HexToBlob(const char *z){
+ char *zBlob;
+ int i;
+ int n = strlen(z);
+ if( n%2 ) return 0;
+
+ zBlob = (char *)sqliteMalloc(n/2);
+ for(i=0; i<n; i+=2){
+ zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]);
+ }
+ return zBlob;
+}
+#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
+
+#if defined(SQLITE_TEST)
+/*
+** Convert text generated by the "%p" conversion format back into
+** a pointer.
+*/
+void *sqlite3TextToPtr(const char *z){
+ void *p;
+ u64 v;
+ u32 v2;
+ if( z[0]=='0' && z[1]=='x' ){
+ z += 2;
+ }
+ v = 0;
+ while( *z ){
+ v = (v<<4) + hexToInt(*z);
+ z++;
+ }
+ if( sizeof(p)==sizeof(v) ){
+ p = *(void**)&v;
+ }else{
+ assert( sizeof(p)==sizeof(v2) );
+ v2 = (u32)v;
+ p = *(void**)&v2;
+ }
+ return p;
+}
+#endif
diff --git a/src/sqlite/vacuum.c b/src/sqlite/vacuum.c
new file mode 100644
index 0000000..b85d36d
--- /dev/null
+++ b/src/sqlite/vacuum.c
@@ -0,0 +1,310 @@
+/*
+** 2003 April 6
+**
+** 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 used to implement the VACUUM command.
+**
+** Most of the code in this file may be omitted by defining the
+** SQLITE_OMIT_VACUUM macro.
+**
+** $Id: vacuum.c,v 1.1.1.1 2006/02/03 20:35:17 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+
+#ifndef SQLITE_OMIT_VACUUM
+/*
+** Generate a random name of 20 character in length.
+*/
+static void randomName(unsigned char *zBuf){
+ static const unsigned char zChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789";
+ int i;
+ sqlite3Randomness(20, zBuf);
+ for(i=0; i<20; i++){
+ zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
+ }
+}
+
+/*
+** Execute zSql on database db. Return an error code.
+*/
+static int execSql(sqlite3 *db, const char *zSql){
+ sqlite3_stmt *pStmt;
+ if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
+ return sqlite3_errcode(db);
+ }
+ while( SQLITE_ROW==sqlite3_step(pStmt) );
+ return sqlite3_finalize(pStmt);
+}
+
+/*
+** Execute zSql on database db. The statement returns exactly
+** one column. Execute this as SQL on the same database.
+*/
+static int execExecSql(sqlite3 *db, const char *zSql){
+ sqlite3_stmt *pStmt;
+ int rc;
+
+ rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+ if( rc!=SQLITE_OK ) return rc;
+
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ rc = execSql(db, sqlite3_column_text(pStmt, 0));
+ if( rc!=SQLITE_OK ){
+ sqlite3_finalize(pStmt);
+ return rc;
+ }
+ }
+
+ return sqlite3_finalize(pStmt);
+}
+
+#endif
+
+/*
+** The non-standard VACUUM command is used to clean up the database,
+** collapse free space, etc. It is modelled after the VACUUM command
+** in PostgreSQL.
+**
+** In version 1.0.x of SQLite, the VACUUM command would call
+** gdbm_reorganize() on all the database tables. But beginning
+** with 2.0.0, SQLite no longer uses GDBM so this command has
+** become a no-op.
+*/
+void sqlite3Vacuum(Parse *pParse, Token *pTableName){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( v ){
+ sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
+ }
+ return;
+}
+
+/*
+** This routine implements the OP_Vacuum opcode of the VDBE.
+*/
+int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
+ int rc = SQLITE_OK; /* Return code from service routines */
+#ifndef SQLITE_OMIT_VACUUM
+ const char *zFilename; /* full pathname of the database file */
+ int nFilename; /* number of characters in zFilename[] */
+ char *zTemp = 0; /* a temporary file in same directory as zFilename */
+ Btree *pMain; /* The database being vacuumed */
+ Btree *pTemp;
+ char *zSql = 0;
+ int writeschema_flag; /* Saved value of the write-schema flag */
+
+ /* Save the current value of the write-schema flag before setting it. */
+ writeschema_flag = db->flags&SQLITE_WriteSchema;
+ db->flags |= SQLITE_WriteSchema;
+
+ if( !db->autoCommit ){
+ sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction",
+ (char*)0);
+ rc = SQLITE_ERROR;
+ goto end_of_vacuum;
+ }
+
+ /* Get the full pathname of the database file and create a
+ ** temporary filename in the same directory as the original file.
+ */
+ pMain = db->aDb[0].pBt;
+ zFilename = sqlite3BtreeGetFilename(pMain);
+ assert( zFilename );
+ if( zFilename[0]=='\0' ){
+ /* The in-memory database. Do nothing. Return directly to avoid causing
+ ** an error trying to DETACH the vacuum_db (which never got attached)
+ ** in the exit-handler.
+ */
+ return SQLITE_OK;
+ }
+ nFilename = strlen(zFilename);
+ zTemp = sqliteMalloc( nFilename+100 );
+ if( zTemp==0 ){
+ rc = SQLITE_NOMEM;
+ goto end_of_vacuum;
+ }
+ strcpy(zTemp, zFilename);
+
+ /* The randomName() procedure in the following loop uses an excellent
+ ** source of randomness to generate a name from a space of 1.3e+31
+ ** possibilities. So unless the directory already contains on the order
+ ** of 1.3e+31 files, the probability that the following loop will
+ ** run more than once or twice is vanishingly small. We are certain
+ ** enough that this loop will always terminate (and terminate quickly)
+ ** that we don't even bother to set a maximum loop count.
+ */
+ do {
+ zTemp[nFilename] = '-';
+ randomName((unsigned char*)&zTemp[nFilename+1]);
+ } while( sqlite3OsFileExists(zTemp) );
+
+ /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
+ ** can be set to 'off' for this file, as it is not recovered if a crash
+ ** occurs anyway. The integrity of the database is maintained by a
+ ** (possibly synchronous) transaction opened on the main database before
+ ** sqlite3BtreeCopyFile() is called.
+ **
+ ** An optimisation would be to use a non-journaled pager.
+ */
+ zSql = sqlite3MPrintf("ATTACH '%q' AS vacuum_db;", zTemp);
+ if( !zSql ){
+ rc = SQLITE_NOMEM;
+ goto end_of_vacuum;
+ }
+ rc = execSql(db, zSql);
+ sqliteFree(zSql);
+ zSql = 0;
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
+ pTemp = db->aDb[db->nDb-1].pBt;
+ sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
+ sqlite3BtreeGetReserve(pMain));
+ assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
+ execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
+
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain));
+#endif
+
+ /* Begin a transaction */
+ rc = execSql(db, "BEGIN;");
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+ /* Query the schema of the main database. Create a mirror schema
+ ** in the temporary database.
+ */
+ rc = execExecSql(db,
+ "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) "
+ " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'");
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = execExecSql(db,
+ "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000)"
+ " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = execExecSql(db,
+ "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) "
+ " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = execExecSql(db,
+ "SELECT 'CREATE VIEW vacuum_db.' || substr(sql,13,100000000) "
+ " FROM sqlite_master WHERE type='view'"
+ );
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+ /* Loop through the tables in the main database. For each, do
+ ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy
+ ** the contents to the temporary database.
+ */
+ rc = execExecSql(db,
+ "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
+ "|| ' SELECT * FROM ' || quote(name) || ';'"
+ "FROM sqlite_master "
+ "WHERE type = 'table' AND name!='sqlite_sequence';"
+ );
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+ /* Copy over the sequence table
+ */
+ rc = execExecSql(db,
+ "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
+ "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
+ );
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = execExecSql(db,
+ "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
+ "|| ' SELECT * FROM ' || quote(name) || ';' "
+ "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
+ );
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+
+ /* Copy the triggers from the main database to the temporary database.
+ ** This was deferred before in case the triggers interfered with copying
+ ** the data. It's possible the indices should be deferred until this
+ ** point also.
+ */
+ rc = execExecSql(db,
+ "SELECT 'CREATE TRIGGER vacuum_db.' || substr(sql, 16, 1000000) "
+ "FROM sqlite_master WHERE type='trigger'"
+ );
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+
+ /* At this point, unless the main db was completely empty, there is now a
+ ** transaction open on the vacuum database, but not on the main database.
+ ** Open a btree level transaction on the main database. This allows a
+ ** call to sqlite3BtreeCopyFile(). The main database btree level
+ ** transaction is then committed, so the SQL level never knows it was
+ ** opened for writing. This way, the SQL transaction used to create the
+ ** temporary database never needs to be committed.
+ */
+ if( sqlite3BtreeIsInTrans(pTemp) ){
+ u32 meta;
+ int i;
+
+ /* This array determines which meta meta values are preserved in the
+ ** vacuum. Even entries are the meta value number and odd entries
+ ** are an increment to apply to the meta value after the vacuum.
+ ** The increment is used to increase the schema cookie so that other
+ ** connections to the same database will know to reread the schema.
+ */
+ static const unsigned char aCopy[] = {
+ 1, 1, /* Add one to the old schema cookie */
+ 3, 0, /* Preserve the default page cache size */
+ 5, 0, /* Preserve the default text encoding */
+ 6, 0, /* Preserve the user version */
+ };
+
+ assert( 0==sqlite3BtreeIsInTrans(pMain) );
+ rc = sqlite3BtreeBeginTrans(pMain, 1);
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+ /* Copy Btree meta values */
+ for(i=0; i<sizeof(aCopy)/sizeof(aCopy[0]); i+=2){
+ rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
+ }
+
+ rc = sqlite3BtreeCopyFile(pMain, pTemp);
+ if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ rc = sqlite3BtreeCommit(pMain);
+ }
+
+end_of_vacuum:
+ /* Restore the original value of the write-schema flag. */
+ db->flags &= ~SQLITE_WriteSchema;
+ db->flags |= writeschema_flag;
+
+ /* Currently there is an SQL level transaction open on the vacuum
+ ** database. No locks are held on any other files (since the main file
+ ** was committed at the btree level). So it safe to end the transaction
+ ** by manually setting the autoCommit flag to true and detaching the
+ ** vacuum database. The vacuum_db journal file is deleted when the pager
+ ** is closed by the DETACH.
+ */
+ db->autoCommit = 1;
+ if( rc==SQLITE_OK ){
+ rc = execSql(db, "DETACH vacuum_db;");
+ }else{
+ execSql(db, "DETACH vacuum_db;");
+ }
+ if( zTemp ){
+ sqlite3OsDelete(zTemp);
+ sqliteFree(zTemp);
+ }
+ if( zSql ) sqliteFree( zSql );
+ sqlite3ResetInternalSchema(db, 0);
+#endif
+
+ return rc;
+}
diff --git a/src/sqlite/vdbe.c b/src/sqlite/vdbe.c
new file mode 100644
index 0000000..cebb065
--- /dev/null
+++ b/src/sqlite/vdbe.c
@@ -0,0 +1,4692 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** The code in this file implements execution method of the
+** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c")
+** handles housekeeping details such as creating and deleting
+** VDBE instances. This file is solely interested in executing
+** the VDBE program.
+**
+** In the external interface, an "sqlite3_stmt*" is an opaque pointer
+** to a VDBE.
+**
+** The SQL parser generates a program which is then executed by
+** the VDBE to do the work of the SQL statement. VDBE programs are
+** similar in form to assembly language. The program consists of
+** a linear sequence of operations. Each operation has an opcode
+** and 3 operands. Operands P1 and P2 are integers. Operand P3
+** is a null-terminated string. The P2 operand must be non-negative.
+** Opcodes will typically ignore one or more operands. Many opcodes
+** ignore all three operands.
+**
+** Computation results are stored on a stack. Each entry on the
+** stack is either an integer, a null-terminated string, a floating point
+** number, or the SQL "NULL" value. An inplicit conversion from one
+** type to the other occurs as necessary.
+**
+** Most of the code in this file is taken up by the sqlite3VdbeExec()
+** function which does the work of interpreting a VDBE program.
+** But other routines are also provided to help in building up
+** a program instruction by instruction.
+**
+** Various scripts scan this source file in order to generate HTML
+** documentation, headers files, or other derived files. The formatting
+** of the code in this file is, therefore, important. See other comments
+** in this file for details. If in doubt, do not deviate from existing
+** commenting and indentation practices when changing or adding code.
+**
+** $Id: vdbe.c,v 1.1.1.1 2006/02/03 20:35:15 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include "vdbeInt.h"
+
+/*
+** The following global variable is incremented every time a cursor
+** moves, either by the OP_MoveXX, OP_Next, or OP_Prev opcodes. The test
+** procedures use this information to make sure that indices are
+** working correctly. This variable has no function other than to
+** help verify the correct operation of the library.
+*/
+int sqlite3_search_count = 0;
+
+/*
+** When this global variable is positive, it gets decremented once before
+** each instruction in the VDBE. When reaches zero, the SQLITE_Interrupt
+** of the db.flags field is set in order to simulate and interrupt.
+**
+** This facility is used for testing purposes only. It does not function
+** in an ordinary build.
+*/
+int sqlite3_interrupt_count = 0;
+
+/*
+** The next global variable is incremented each type the OP_Sort opcode
+** is executed. The test procedures use this information to make sure that
+** sorting is occurring or not occuring at appropriate times. This variable
+** has no function other than to help verify the correct operation of the
+** library.
+*/
+int sqlite3_sort_count = 0;
+
+/*
+** Release the memory associated with the given stack level. This
+** leaves the Mem.flags field in an inconsistent state.
+*/
+#define Release(P) if((P)->flags&MEM_Dyn){ sqlite3VdbeMemRelease(P); }
+
+/*
+** Convert the given stack entity into a string if it isn't one
+** already. Return non-zero if a malloc() fails.
+*/
+#define Stringify(P, enc) \
+ if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
+ { goto no_mem; }
+
+/*
+** Convert the given stack entity into a string that has been obtained
+** from sqliteMalloc(). This is different from Stringify() above in that
+** Stringify() will use the NBFS bytes of static string space if the string
+** will fit but this routine always mallocs for space.
+** Return non-zero if we run out of memory.
+*/
+#define Dynamicify(P,enc) sqlite3VdbeMemDynamicify(P)
+
+
+/*
+** An ephemeral string value (signified by the MEM_Ephem flag) contains
+** a pointer to a dynamically allocated string where some other entity
+** is responsible for deallocating that string. Because the stack entry
+** does not control the string, it might be deleted without the stack
+** entry knowing it.
+**
+** This routine converts an ephemeral string into a dynamically allocated
+** string that the stack entry itself controls. In other words, it
+** converts an MEM_Ephem string into an MEM_Dyn string.
+*/
+#define Deephemeralize(P) \
+ if( ((P)->flags&MEM_Ephem)!=0 \
+ && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
+
+/*
+** Convert the given stack entity into a integer if it isn't one
+** already.
+**
+** Any prior string or real representation is invalidated.
+** NULLs are converted into 0.
+*/
+#define Integerify(P) sqlite3VdbeMemIntegerify(P)
+
+/*
+** Convert P so that it has type MEM_Real.
+**
+** Any prior string or integer representation is invalidated.
+** NULLs are converted into 0.0.
+*/
+#define Realify(P) sqlite3VdbeMemRealify(P)
+
+/*
+** Argument pMem points at a memory cell that will be passed to a
+** user-defined function or returned to the user as the result of a query.
+** The second argument, 'db_enc' is the text encoding used by the vdbe for
+** stack variables. This routine sets the pMem->enc and pMem->type
+** variables used by the sqlite3_value_*() routines.
+*/
+#define storeTypeInfo(A,B) _storeTypeInfo(A)
+static void _storeTypeInfo(Mem *pMem){
+ int flags = pMem->flags;
+ if( flags & MEM_Null ){
+ pMem->type = SQLITE_NULL;
+ }
+ else if( flags & MEM_Int ){
+ pMem->type = SQLITE_INTEGER;
+ }
+ else if( flags & MEM_Real ){
+ pMem->type = SQLITE_FLOAT;
+ }
+ else if( flags & MEM_Str ){
+ pMem->type = SQLITE_TEXT;
+ }else{
+ pMem->type = SQLITE_BLOB;
+ }
+}
+
+/*
+** Insert a new aggregate element and make it the element that
+** has focus.
+**
+** Return 0 on success and 1 if memory is exhausted.
+*/
+static int AggInsert(Agg *p, char *zKey, int nKey){
+ AggElem *pElem;
+ int i;
+ int rc;
+ pElem = sqliteMalloc( sizeof(AggElem) + nKey +
+ (p->nMem-1)*sizeof(pElem->aMem[0]) );
+ if( pElem==0 ) return SQLITE_NOMEM;
+ pElem->zKey = (char*)&pElem->aMem[p->nMem];
+ memcpy(pElem->zKey, zKey, nKey);
+ pElem->nKey = nKey;
+
+ if( p->pCsr ){
+ rc = sqlite3BtreeInsert(p->pCsr, zKey, nKey, &pElem, sizeof(AggElem*));
+ if( rc!=SQLITE_OK ){
+ sqliteFree(pElem);
+ return rc;
+ }
+ }
+
+ for(i=0; i<p->nMem; i++){
+ pElem->aMem[i].flags = MEM_Null;
+ }
+ p->pCurrent = pElem;
+ return 0;
+}
+
+/*
+** Pop the stack N times.
+*/
+static void popStack(Mem **ppTos, int N){
+ Mem *pTos = *ppTos;
+ while( N>0 ){
+ N--;
+ Release(pTos);
+ pTos--;
+ }
+ *ppTos = pTos;
+}
+
+/*
+** The parameters are pointers to the head of two sorted lists
+** of Sorter structures. Merge these two lists together and return
+** a single sorted list. This routine forms the core of the merge-sort
+** algorithm.
+**
+** In the case of a tie, left sorts in front of right.
+*/
+static Sorter *Merge(Sorter *pLeft, Sorter *pRight, KeyInfo *pKeyInfo){
+ Sorter sHead;
+ Sorter *pTail;
+ pTail = &sHead;
+ pTail->pNext = 0;
+ while( pLeft && pRight ){
+ int c = sqlite3VdbeRecordCompare(pKeyInfo, pLeft->nKey, pLeft->zKey,
+ pRight->nKey, pRight->zKey);
+ if( c<=0 ){
+ pTail->pNext = pLeft;
+ pLeft = pLeft->pNext;
+ }else{
+ pTail->pNext = pRight;
+ pRight = pRight->pNext;
+ }
+ pTail = pTail->pNext;
+ }
+ if( pLeft ){
+ pTail->pNext = pLeft;
+ }else if( pRight ){
+ pTail->pNext = pRight;
+ }
+ return sHead.pNext;
+}
+
+/*
+** Allocate cursor number iCur. Return a pointer to it. Return NULL
+** if we run out of memory.
+*/
+static Cursor *allocateCursor(Vdbe *p, int iCur){
+ Cursor *pCx;
+ assert( iCur<p->nCursor );
+ if( p->apCsr[iCur] ){
+ sqlite3VdbeFreeCursor(p->apCsr[iCur]);
+ }
+ p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
+ return pCx;
+}
+
+/*
+** Apply any conversion required by the supplied column affinity to
+** memory cell pRec. affinity may be one of:
+**
+** SQLITE_AFF_NUMERIC
+** SQLITE_AFF_TEXT
+** SQLITE_AFF_NONE
+** SQLITE_AFF_INTEGER
+**
+*/
+static void applyAffinity(Mem *pRec, char affinity, u8 enc){
+ if( affinity==SQLITE_AFF_NONE ){
+ /* do nothing */
+ }else if( affinity==SQLITE_AFF_TEXT ){
+ /* Only attempt the conversion to TEXT if there is an integer or real
+ ** representation (blob and NULL do not get converted) but no string
+ ** representation.
+ */
+ if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
+ sqlite3VdbeMemStringify(pRec, enc);
+ }
+ pRec->flags &= ~(MEM_Real|MEM_Int);
+ }else{
+ if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){
+ /* pRec does not have a valid integer or real representation.
+ ** Attempt a conversion if pRec has a string representation and
+ ** it looks like a number.
+ */
+ int realnum;
+ sqlite3VdbeMemNulTerminate(pRec);
+ if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){
+ if( realnum ){
+ Realify(pRec);
+ }else{
+ Integerify(pRec);
+ }
+ }
+ }
+
+ if( affinity==SQLITE_AFF_INTEGER ){
+ /* For INTEGER affinity, try to convert a real value to an int */
+ if( (pRec->flags&MEM_Real) && !(pRec->flags&MEM_Int) ){
+ pRec->i = pRec->r;
+ if( ((double)pRec->i)==pRec->r ){
+ pRec->flags |= MEM_Int;
+ }
+ }
+ }
+ }
+}
+
+/*
+** Exported version of applyAffinity(). This one works on sqlite3_value*,
+** not the internal Mem* type.
+*/
+void sqlite3ValueApplyAffinity(sqlite3_value *pVal, u8 affinity, u8 enc){
+ applyAffinity((Mem *)pVal, affinity, enc);
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** Write a nice string representation of the contents of cell pMem
+** into buffer zBuf, length nBuf.
+*/
+void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf){
+ char *zCsr = zBuf;
+ int f = pMem->flags;
+
+ static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};
+
+ if( f&MEM_Blob ){
+ int i;
+ char c;
+ if( f & MEM_Dyn ){
+ c = 'z';
+ assert( (f & (MEM_Static|MEM_Ephem))==0 );
+ }else if( f & MEM_Static ){
+ c = 't';
+ assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
+ }else if( f & MEM_Ephem ){
+ c = 'e';
+ assert( (f & (MEM_Static|MEM_Dyn))==0 );
+ }else{
+ c = 's';
+ }
+
+ zCsr += sprintf(zCsr, "%c", c);
+ zCsr += sprintf(zCsr, "%d[", pMem->n);
+ for(i=0; i<16 && i<pMem->n; i++){
+ zCsr += sprintf(zCsr, "%02X ", ((int)pMem->z[i] & 0xFF));
+ }
+ for(i=0; i<16 && i<pMem->n; i++){
+ char z = pMem->z[i];
+ if( z<32 || z>126 ) *zCsr++ = '.';
+ else *zCsr++ = z;
+ }
+
+ zCsr += sprintf(zCsr, "]");
+ *zCsr = '\0';
+ }else if( f & MEM_Str ){
+ int j, k;
+ zBuf[0] = ' ';
+ if( f & MEM_Dyn ){
+ zBuf[1] = 'z';
+ assert( (f & (MEM_Static|MEM_Ephem))==0 );
+ }else if( f & MEM_Static ){
+ zBuf[1] = 't';
+ assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
+ }else if( f & MEM_Ephem ){
+ zBuf[1] = 'e';
+ assert( (f & (MEM_Static|MEM_Dyn))==0 );
+ }else{
+ zBuf[1] = 's';
+ }
+ k = 2;
+ k += sprintf(&zBuf[k], "%d", pMem->n);
+ zBuf[k++] = '[';
+ for(j=0; j<15 && j<pMem->n; j++){
+ u8 c = pMem->z[j];
+ if( c>=0x20 && c<0x7f ){
+ zBuf[k++] = c;
+ }else{
+ zBuf[k++] = '.';
+ }
+ }
+ zBuf[k++] = ']';
+ k += sprintf(&zBuf[k], encnames[pMem->enc]);
+ zBuf[k++] = 0;
+ }
+}
+#endif
+
+
+#ifdef VDBE_PROFILE
+/*
+** The following routine only works on pentium-class processors.
+** It uses the RDTSC opcode to read the cycle count value out of the
+** processor and returns that value. This can be used for high-res
+** profiling.
+*/
+__inline__ unsigned long long int hwtime(void){
+ unsigned long long int x;
+ __asm__("rdtsc\n\t"
+ "mov %%edx, %%ecx\n\t"
+ :"=A" (x));
+ return x;
+}
+#endif
+
+/*
+** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
+** sqlite3_interrupt() routine has been called. If it has been, then
+** processing of the VDBE program is interrupted.
+**
+** This macro added to every instruction that does a jump in order to
+** implement a loop. This test used to be on every single instruction,
+** but that meant we more testing that we needed. By only testing the
+** flag on jump instructions, we get a (small) speed improvement.
+*/
+#define CHECK_FOR_INTERRUPT \
+ if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt;
+
+
+/*
+** Execute as much of a VDBE program as we can then return.
+**
+** sqlite3VdbeMakeReady() must be called before this routine in order to
+** close the program with a final OP_Halt and to set up the callbacks
+** and the error message pointer.
+**
+** Whenever a row or result data is available, this routine will either
+** invoke the result callback (if there is one) or return with
+** SQLITE_ROW.
+**
+** If an attempt is made to open a locked database, then this routine
+** will either invoke the busy callback (if there is one) or it will
+** return SQLITE_BUSY.
+**
+** If an error occurs, an error message is written to memory obtained
+** from sqliteMalloc() and p->zErrMsg is made to point to that memory.
+** The error code is stored in p->rc and this routine returns SQLITE_ERROR.
+**
+** If the callback ever returns non-zero, then the program exits
+** immediately. There will be no error message but the p->rc field is
+** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.
+**
+** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this
+** routine to return SQLITE_ERROR.
+**
+** Other fatal errors return SQLITE_ERROR.
+**
+** After this routine has finished, sqlite3VdbeFinalize() should be
+** used to clean up the mess that was left behind.
+*/
+int sqlite3VdbeExec(
+ Vdbe *p /* The VDBE */
+){
+ int pc; /* The program counter */
+ Op *pOp; /* Current operation */
+ 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 */
+#endif
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ int nProgressOps = 0; /* Opcodes executed since progress callback. */
+#endif
+#ifndef NDEBUG
+ Mem *pStackLimit;
+#endif
+
+ if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
+ assert( db->magic==SQLITE_MAGIC_BUSY );
+ assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+ p->rc = SQLITE_OK;
+ assert( p->explain==0 );
+ pTos = p->pTos;
+ if( sqlite3_malloc_failed ) goto no_mem;
+ if( p->popStack ){
+ popStack(&pTos, p->popStack);
+ p->popStack = 0;
+ }
+ p->resOnStack = 0;
+ CHECK_FOR_INTERRUPT;
+ for(pc=p->pc; rc==SQLITE_OK; pc++){
+ assert( pc>=0 && pc<p->nOp );
+ assert( pTos<=&p->aStack[pc] );
+ if( sqlite3_malloc_failed ) goto no_mem;
+#ifdef VDBE_PROFILE
+ origPc = pc;
+ start = hwtime();
+#endif
+ pOp = &p->aOp[pc];
+
+ /* Only allow tracing if SQLITE_DEBUG is defined.
+ */
+#ifdef SQLITE_DEBUG
+ if( p->trace ){
+ if( pc==0 ){
+ printf("VDBE Execution Trace:\n");
+ sqlite3VdbePrintSql(p);
+ }
+ sqlite3VdbePrintOp(p->trace, pc, pOp);
+ }
+ if( p->trace==0 && pc==0 && sqlite3OsFileExists("vdbe_sqltrace") ){
+ sqlite3VdbePrintSql(p);
+ }
+#endif
+
+
+ /* Check to see if we need to simulate an interrupt. This only happens
+ ** if we have a special test build.
+ */
+#ifdef SQLITE_TEST
+ if( sqlite3_interrupt_count>0 ){
+ sqlite3_interrupt_count--;
+ if( sqlite3_interrupt_count==0 ){
+ sqlite3_interrupt(db);
+ }
+ }
+#endif
+
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ /* Call the progress callback if it is configured and the required number
+ ** of VDBE ops have been executed (either since this invocation of
+ ** sqlite3VdbeExec() or since last time the progress callback was called).
+ ** If the progress callback returns non-zero, exit the virtual machine with
+ ** a return code SQLITE_ABORT.
+ */
+ if( db->xProgress ){
+ if( db->nProgressOps==nProgressOps ){
+ if( db->xProgress(db->pProgressArg)!=0 ){
+ rc = SQLITE_ABORT;
+ continue; /* skip to the next iteration of the for loop */
+ }
+ nProgressOps = 0;
+ }
+ nProgressOps++;
+ }
+#endif
+
+#ifndef NDEBUG
+ /* This is to check that the return value of static function
+ ** opcodeNoPush() (see vdbeaux.c) returns values that match the
+ ** implementation of the virtual machine in this file. If
+ ** opcodeNoPush() returns non-zero, then the stack is guarenteed
+ ** not to grow when the opcode is executed. If it returns zero, then
+ ** the stack may grow by at most 1.
+ **
+ ** The global wrapper function sqlite3VdbeOpcodeUsesStack() is not
+ ** available if NDEBUG is defined at build time.
+ */
+ pStackLimit = pTos;
+ if( !sqlite3VdbeOpcodeNoPush(pOp->opcode) ){
+ pStackLimit++;
+ }
+#endif
+
+ switch( pOp->opcode ){
+
+/*****************************************************************************
+** What follows is a massive switch statement where each case implements a
+** separate instruction in the virtual machine. If we follow the usual
+** indentation conventions, each case should be indented by 6 spaces. But
+** that is a lot of wasted space on the left margin. So the code within
+** the switch statement will break with convention and be flush-left. Another
+** big comment (similar to this one) will mark the point in the code where
+** we transition back to normal indentation.
+**
+** The formatting of each case is important. The makefile for SQLite
+** generates two C files "opcodes.h" and "opcodes.c" by scanning this
+** file looking for lines that begin with "case OP_". The opcodes.h files
+** will be filled with #defines that give unique integer values to each
+** opcode and the opcodes.c file is filled with an array of strings where
+** each string is the symbolic name for the corresponding opcode. If the
+** case statement is followed by a comment of the form "/# same as ... #/"
+** that comment is used to determine the particular value of the opcode.
+**
+** If a comment on the same line as the "case OP_" construction contains
+** the word "no-push", then the opcode is guarenteed not to grow the
+** vdbe stack when it is executed. See function opcode() in
+** vdbeaux.c for details.
+**
+** Documentation about VDBE opcodes is generated by scanning this file
+** for lines of that contain "Opcode:". That line and all subsequent
+** comment lines are used in the generation of the opcode.html documentation
+** file.
+**
+** SUMMARY:
+**
+** Formatting is important to scripts that scan this file.
+** Do not deviate from the formatting style currently in use.
+**
+*****************************************************************************/
+
+/* Opcode: Goto * P2 *
+**
+** An unconditional jump to address P2.
+** The next instruction executed will be
+** the one at index P2 from the beginning of
+** the program.
+*/
+case OP_Goto: { /* no-push */
+ CHECK_FOR_INTERRUPT;
+ pc = pOp->p2 - 1;
+ break;
+}
+
+/* Opcode: Gosub * P2 *
+**
+** Push the current address plus 1 onto the return address stack
+** and then jump to address P2.
+**
+** The return address stack is of limited depth. If too many
+** OP_Gosub operations occur without intervening OP_Returns, then
+** the return address stack will fill up and processing will abort
+** with a fatal error.
+*/
+case OP_Gosub: { /* no-push */
+ assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) );
+ p->returnStack[p->returnDepth++] = pc+1;
+ pc = pOp->p2 - 1;
+ break;
+}
+
+/* Opcode: Return * * *
+**
+** Jump immediately to the next instruction after the last unreturned
+** OP_Gosub. If an OP_Return has occurred for all OP_Gosubs, then
+** processing aborts with a fatal error.
+*/
+case OP_Return: { /* no-push */
+ assert( p->returnDepth>0 );
+ p->returnDepth--;
+ pc = p->returnStack[p->returnDepth] - 1;
+ break;
+}
+
+/* Opcode: Halt P1 P2 *
+**
+** Exit immediately. All open cursors, Lists, Sorts, etc are closed
+** automatically.
+**
+** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
+** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0).
+** For errors, it can be some other value. If P1!=0 then P2 will determine
+** whether or not to rollback the current transaction. Do not rollback
+** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort,
+** then back out all changes that have occurred during this execution of the
+** VDBE, but do not rollback the transaction.
+**
+** 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.
+*/
+case OP_Halt: { /* no-push */
+ p->pTos = pTos;
+ p->rc = pOp->p1;
+ p->pc = pc;
+ p->errorAction = pOp->p2;
+ if( pOp->p3 ){
+ sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
+ }
+ rc = sqlite3VdbeHalt(p);
+ assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
+ if( rc==SQLITE_BUSY ){
+ p->rc = SQLITE_BUSY;
+ return SQLITE_BUSY;
+ }
+ 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.
+**
+** If the value cannot be represented as a 32-bits then its value
+** will be in P3.
+*/
+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;
+ }
+ break;
+}
+
+/* Opcode: Real * * P3
+**
+** The string value P3 is converted to a real and pushed on to the stack.
+*/
+case OP_Real: { /* same as TK_FLOAT, */
+ pTos++;
+ pTos->flags = MEM_Str|MEM_Static|MEM_Term;
+ pTos->z = pOp->p3;
+ pTos->n = strlen(pTos->z);
+ pTos->enc = SQLITE_UTF8;
+ pTos->r = sqlite3VdbeRealValue(pTos);
+ pTos->flags |= MEM_Real;
+ sqlite3VdbeChangeEncoding(pTos, db->enc);
+ break;
+}
+
+/* Opcode: String8 * * P3
+**
+** P3 points to a nul terminated UTF-8 string. This opcode is transformed
+** into an OP_String before it is executed for the first time.
+*/
+case OP_String8: { /* same as TK_STRING */
+#ifndef SQLITE_OMIT_UTF16
+ pOp->opcode = OP_String;
+
+ assert( pOp->p3!=0 );
+ if( db->enc!=SQLITE_UTF8 ){
+ pTos++;
+ sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
+ if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem;
+ if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
+ pTos->flags &= ~(MEM_Dyn);
+ pTos->flags |= MEM_Static;
+ if( pOp->p3type==P3_DYNAMIC ){
+ sqliteFree(pOp->p3);
+ }
+ pOp->p3type = P3_DYNAMIC;
+ pOp->p3 = pTos->z;
+ break;
+ }
+#endif
+ /* Otherwise fall through to the next case, OP_String */
+}
+
+/* Opcode: String * * P3
+**
+** The string value P3 is pushed onto the stack. If P3==0 then a
+** NULL is pushed onto the stack. P3 is assumed to be a nul terminated
+** string encoded with the database native encoding.
+*/
+case OP_String: {
+ pTos++;
+ assert( pOp->p3!=0 );
+ pTos->flags = MEM_Str|MEM_Static|MEM_Term;
+ pTos->z = pOp->p3;
+#ifndef SQLITE_OMIT_UTF16
+ if( db->enc==SQLITE_UTF8 ){
+ pTos->n = strlen(pTos->z);
+ }else{
+ pTos->n = sqlite3utf16ByteLen(pTos->z, -1);
+ }
+#else
+ assert( db->enc==SQLITE_UTF8 );
+ pTos->n = strlen(pTos->z);
+#endif
+ pTos->enc = db->enc;
+ break;
+}
+
+/* Opcode: Null * * *
+**
+** Push a NULL onto the stack.
+*/
+case OP_Null: {
+ pTos++;
+ pTos->flags = MEM_Null;
+ break;
+}
+
+
+#ifndef SQLITE_OMIT_BLOB_LITERAL
+/* Opcode: HexBlob * * P3
+**
+** P3 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
+** vdbe stack.
+**
+** The first time this instruction executes, in transforms itself into a
+** 'Blob' opcode with a binary blob as P3.
+*/
+case OP_HexBlob: { /* same as TK_BLOB */
+ pOp->opcode = OP_Blob;
+ pOp->p1 = strlen(pOp->p3)/2;
+ if( pOp->p1 ){
+ char *zBlob = sqlite3HexToBlob(pOp->p3);
+ if( !zBlob ) goto no_mem;
+ if( pOp->p3type==P3_DYNAMIC ){
+ sqliteFree(pOp->p3);
+ }
+ pOp->p3 = zBlob;
+ pOp->p3type = P3_DYNAMIC;
+ }else{
+ if( pOp->p3type==P3_DYNAMIC ){
+ sqliteFree(pOp->p3);
+ }
+ pOp->p3type = P3_STATIC;
+ pOp->p3 = "";
+ }
+
+ /* Fall through to the next case, OP_Blob. */
+}
+
+/* Opcode: Blob P1 * P3
+**
+** P3 points to a blob of data P1 bytes long. Push this
+** value onto the stack. This instruction is not coded directly
+** by the compiler. Instead, the compiler layer specifies
+** an OP_HexBlob opcode, with the hex string representation of
+** the blob as P3. This opcode is transformed to an OP_Blob
+** the first time it is executed.
+*/
+case OP_Blob: {
+ pTos++;
+ sqlite3VdbeMemSetStr(pTos, pOp->p3, pOp->p1, 0, 0);
+ break;
+}
+#endif /* SQLITE_OMIT_BLOB_LITERAL */
+
+/* Opcode: Variable P1 * *
+**
+** Push the value of variable P1 onto the stack. A variable is
+** an unknown in the original SQL string as handed to sqlite3_compile().
+** Any occurance of the '?' character in the original SQL is considered
+** a variable. Variables in the SQL string are number from left to
+** right beginning with 1. The values of variables are set using the
+** sqlite3_bind() API.
+*/
+case OP_Variable: {
+ int j = pOp->p1 - 1;
+ assert( j>=0 && j<p->nVar );
+
+ pTos++;
+ sqlite3VdbeMemShallowCopy(pTos, &p->aVar[j], MEM_Static);
+ break;
+}
+
+/* Opcode: Pop P1 * *
+**
+** P1 elements are popped off of the top of stack and discarded.
+*/
+case OP_Pop: { /* no-push */
+ assert( pOp->p1>=0 );
+ popStack(&pTos, pOp->p1);
+ assert( pTos>=&p->aStack[-1] );
+ break;
+}
+
+/* Opcode: Dup P1 P2 *
+**
+** A copy of the P1-th element of the stack
+** is made and pushed onto the top of the stack.
+** The top of the stack is element 0. So the
+** instruction "Dup 0 0 0" will make a copy of the
+** top of the stack.
+**
+** If the content of the P1-th element is a dynamically
+** allocated string, then a new copy of that string
+** is made if P2==0. If P2!=0, then just a pointer
+** to the string is copied.
+**
+** Also see the Pull instruction.
+*/
+case OP_Dup: {
+ Mem *pFrom = &pTos[-pOp->p1];
+ assert( pFrom<=pTos && pFrom>=p->aStack );
+ pTos++;
+ sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem);
+ if( pOp->p2 ){
+ Deephemeralize(pTos);
+ }
+ break;
+}
+
+/* Opcode: Pull P1 * *
+**
+** The P1-th element is removed from its current location on
+** the stack and pushed back on top of the stack. The
+** top of the stack is element 0, so "Pull 0 0 0" is
+** a no-op. "Pull 1 0 0" swaps the top two elements of
+** the stack.
+**
+** See also the Dup instruction.
+*/
+case OP_Pull: { /* no-push */
+ Mem *pFrom = &pTos[-pOp->p1];
+ int i;
+ Mem ts;
+
+ ts = *pFrom;
+ Deephemeralize(pTos);
+ for(i=0; i<pOp->p1; i++, pFrom++){
+ Deephemeralize(&pFrom[1]);
+ assert( (pFrom->flags & MEM_Ephem)==0 );
+ *pFrom = pFrom[1];
+ if( pFrom->flags & MEM_Short ){
+ assert( pFrom->flags & (MEM_Str|MEM_Blob) );
+ assert( pFrom->z==pFrom[1].zShort );
+ pFrom->z = pFrom->zShort;
+ }
+ }
+ *pTos = ts;
+ if( pTos->flags & MEM_Short ){
+ assert( pTos->flags & (MEM_Str|MEM_Blob) );
+ assert( pTos->z==pTos[-pOp->p1].zShort );
+ pTos->z = pTos->zShort;
+ }
+ break;
+}
+
+/* Opcode: Push P1 * *
+**
+** Overwrite the value of the P1-th element down on the
+** stack (P1==0 is the top of the stack) with the value
+** of the top of the stack. Then pop the top of the stack.
+*/
+case OP_Push: { /* no-push */
+ Mem *pTo = &pTos[-pOp->p1];
+
+ assert( pTo>=p->aStack );
+ sqlite3VdbeMemMove(pTo, pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: Callback P1 * *
+**
+** Pop P1 values off the stack and form them into an array. Then
+** invoke the callback function using the newly formed array as the
+** 3rd parameter.
+*/
+case OP_Callback: { /* no-push */
+ int i;
+ assert( p->nResColumn==pOp->p1 );
+
+ for(i=0; i<pOp->p1; i++){
+ Mem *pVal = &pTos[0-i];
+ sqlite3VdbeMemNulTerminate(pVal);
+ storeTypeInfo(pVal, db->enc);
+ }
+
+ p->resOnStack = 1;
+ p->nCallback++;
+ p->popStack = pOp->p1;
+ p->pc = pc + 1;
+ p->pTos = pTos;
+ return SQLITE_ROW;
+}
+
+/* Opcode: Concat P1 P2 *
+**
+** Look at the first P1+2 elements of the stack. Append them all
+** together with the lowest element first. The original P1+2 elements
+** are popped from the stack if P2==0 and retained if P2==1. If
+** any element of the stack is NULL, then the result is NULL.
+**
+** When P1==1, this routine makes a copy of the top stack element
+** into memory obtained from sqliteMalloc().
+*/
+case OP_Concat: { /* same as TK_CONCAT */
+ char *zNew;
+ int nByte;
+ int nField;
+ int i, j;
+ Mem *pTerm;
+
+ /* Loop through the stack elements to see how long the result will be. */
+ nField = pOp->p1 + 2;
+ pTerm = &pTos[1-nField];
+ nByte = 0;
+ for(i=0; i<nField; i++, pTerm++){
+ assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );
+ if( pTerm->flags&MEM_Null ){
+ nByte = -1;
+ break;
+ }
+ Stringify(pTerm, db->enc);
+ nByte += pTerm->n;
+ }
+
+ if( nByte<0 ){
+ /* If nByte is less than zero, then there is a NULL value on the stack.
+ ** In this case just pop the values off the stack (if required) and
+ ** push on a NULL.
+ */
+ if( pOp->p2==0 ){
+ popStack(&pTos, nField);
+ }
+ pTos++;
+ pTos->flags = MEM_Null;
+ }else{
+ /* Otherwise malloc() space for the result and concatenate all the
+ ** stack values.
+ */
+ zNew = sqliteMallocRaw( nByte+2 );
+ if( zNew==0 ) goto no_mem;
+ j = 0;
+ pTerm = &pTos[1-nField];
+ for(i=j=0; i<nField; i++, pTerm++){
+ int n = pTerm->n;
+ assert( pTerm->flags & MEM_Str );
+ memcpy(&zNew[j], pTerm->z, n);
+ j += n;
+ }
+ zNew[j] = 0;
+ zNew[j+1] = 0;
+ assert( j==nByte );
+
+ if( pOp->p2==0 ){
+ popStack(&pTos, nField);
+ }
+ pTos++;
+ pTos->n = j;
+ pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
+ pTos->xDel = 0;
+ pTos->enc = db->enc;
+ pTos->z = zNew;
+ }
+ break;
+}
+
+/* Opcode: Add * * *
+**
+** Pop the top two elements from the stack, add them together,
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the addition.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Multiply * * *
+**
+** Pop the top two elements from the stack, multiply them together,
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the multiplication.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Subtract * * *
+**
+** Pop the top two elements from the stack, subtract the
+** first (what was on top of the stack) from the second (the
+** next on stack)
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the subtraction.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Divide * * *
+**
+** Pop the top two elements from the stack, divide the
+** first (what was on top of the stack) from the second (the
+** next on stack)
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the division. Division by zero returns NULL.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Remainder * * *
+**
+** Pop the top two elements from the stack, divide the
+** first (what was on top of the stack) from the second (the
+** next on stack)
+** and push the remainder after division onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the division. Division by zero returns NULL.
+** If either operand is NULL, the result is NULL.
+*/
+case OP_Add: /* same as TK_PLUS, no-push */
+case OP_Subtract: /* same as TK_MINUS, no-push */
+case OP_Multiply: /* same as TK_STAR, no-push */
+case OP_Divide: /* same as TK_SLASH, no-push */
+case OP_Remainder: { /* same as TK_REM, no-push */
+ Mem *pNos = &pTos[-1];
+ assert( pNos>=p->aStack );
+ if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->flags = MEM_Null;
+ }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
+ i64 a, b;
+ a = pTos->i;
+ b = pNos->i;
+ switch( pOp->opcode ){
+ case OP_Add: b += a; break;
+ case OP_Subtract: b -= a; break;
+ case OP_Multiply: b *= a; break;
+ case OP_Divide: {
+ if( a==0 ) goto divide_by_zero;
+ b /= a;
+ break;
+ }
+ default: {
+ if( a==0 ) goto divide_by_zero;
+ b %= a;
+ break;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->i = b;
+ pTos->flags = MEM_Int;
+ }else{
+ double a, b;
+ a = sqlite3VdbeRealValue(pTos);
+ b = sqlite3VdbeRealValue(pNos);
+ switch( pOp->opcode ){
+ case OP_Add: b += a; break;
+ case OP_Subtract: b -= a; break;
+ case OP_Multiply: b *= a; break;
+ case OP_Divide: {
+ if( a==0.0 ) goto divide_by_zero;
+ b /= a;
+ break;
+ }
+ default: {
+ int ia = (int)a;
+ int ib = (int)b;
+ if( ia==0.0 ) goto divide_by_zero;
+ b = ib % ia;
+ break;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->r = b;
+ pTos->flags = MEM_Real;
+ }
+ break;
+
+divide_by_zero:
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->flags = MEM_Null;
+ break;
+}
+
+/* Opcode: CollSeq * * P3
+**
+** P3 is a pointer to a CollSeq struct. If the next call to a user function
+** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
+** be returned. This is used by the built-in min(), max() and nullif()
+** functions.
+**
+** The interface used by the implementation of the aforementioned functions
+** to retrieve the collation sequence set by this opcode is not available
+** publicly, only to user functions defined in func.c.
+*/
+case OP_CollSeq: { /* no-push */
+ assert( pOp->p3type==P3_COLLSEQ );
+ break;
+}
+
+/* Opcode: Function P1 P2 P3
+**
+** Invoke a user function (P3 is a pointer to a Function structure that
+** defines the function) with P1 arguments taken from the stack. Pop all
+** arguments from the stack and push back the result.
+**
+** P2 is a 32-bit bitmask indicating whether or not each argument to the
+** function was determined to be constant at compile time. If the first
+** argument was constant then bit 0 of P2 is set. This is used to determine
+** whether meta data associated with a user function argument using the
+** sqlite3_set_auxdata() API may be safely retained until the next
+** invocation of this opcode.
+**
+** See also: AggFunc
+*/
+case OP_Function: {
+ int i;
+ Mem *pArg;
+ sqlite3_context ctx;
+ sqlite3_value **apVal;
+ int n = pOp->p1;
+
+ n = pOp->p1;
+ apVal = p->apArg;
+ assert( apVal || n==0 );
+
+ pArg = &pTos[1-n];
+ for(i=0; i<n; i++, pArg++){
+ apVal[i] = pArg;
+ storeTypeInfo(pArg, db->enc);
+ }
+
+ assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );
+ if( pOp->p3type==P3_FUNCDEF ){
+ ctx.pFunc = (FuncDef*)pOp->p3;
+ ctx.pVdbeFunc = 0;
+ }else{
+ ctx.pVdbeFunc = (VdbeFunc*)pOp->p3;
+ ctx.pFunc = ctx.pVdbeFunc->pFunc;
+ }
+
+ ctx.s.flags = MEM_Null;
+ ctx.s.z = 0;
+ ctx.s.xDel = 0;
+ ctx.isError = 0;
+ if( ctx.pFunc->needCollSeq ){
+ assert( pOp>p->aOp );
+ assert( pOp[-1].p3type==P3_COLLSEQ );
+ assert( pOp[-1].opcode==OP_CollSeq );
+ ctx.pColl = (CollSeq *)pOp[-1].p3;
+ }
+ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
+ (*ctx.pFunc->xFunc)(&ctx, n, apVal);
+ if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
+ if( sqlite3_malloc_failed ) goto no_mem;
+ popStack(&pTos, n);
+
+ /* If any auxilary data functions have been called by this user function,
+ ** immediately call the destructor for any non-static values.
+ */
+ if( ctx.pVdbeFunc ){
+ sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p2);
+ pOp->p3 = (char *)ctx.pVdbeFunc;
+ pOp->p3type = P3_VDBEFUNC;
+ }
+
+ /* Copy the result of the function to the top of the stack */
+ sqlite3VdbeChangeEncoding(&ctx.s, db->enc);
+ pTos++;
+ pTos->flags = 0;
+ sqlite3VdbeMemMove(pTos, &ctx.s);
+
+ /* If the function returned an error, throw an exception */
+ if( ctx.isError ){
+ if( !(pTos->flags&MEM_Str) ){
+ sqlite3SetString(&p->zErrMsg, "user function error", (char*)0);
+ }else{
+ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pTos), (char*)0);
+ sqlite3VdbeChangeEncoding(pTos, db->enc);
+ }
+ rc = SQLITE_ERROR;
+ }
+ break;
+}
+
+/* Opcode: BitAnd * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the bit-wise AND of the
+** two elements.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: BitOr * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the bit-wise OR of the
+** two elements.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: ShiftLeft * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the second element shifted
+** left by N bits where N is the top element on the stack.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: ShiftRight * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the second element shifted
+** right by N bits where N is the top element on the stack.
+** If either operand is NULL, the result is NULL.
+*/
+case OP_BitAnd: /* same as TK_BITAND, no-push */
+case OP_BitOr: /* same as TK_BITOR, no-push */
+case OP_ShiftLeft: /* same as TK_LSHIFT, no-push */
+case OP_ShiftRight: { /* same as TK_RSHIFT, no-push */
+ Mem *pNos = &pTos[-1];
+ int a, b;
+
+ assert( pNos>=p->aStack );
+ if( (pTos->flags | pNos->flags) & MEM_Null ){
+ popStack(&pTos, 2);
+ pTos++;
+ pTos->flags = MEM_Null;
+ break;
+ }
+ a = sqlite3VdbeIntValue(pNos);
+ b = sqlite3VdbeIntValue(pTos);
+ switch( pOp->opcode ){
+ case OP_BitAnd: a &= b; break;
+ case OP_BitOr: a |= b; break;
+ case OP_ShiftLeft: a <<= b; break;
+ case OP_ShiftRight: a >>= b; break;
+ default: /* CANT HAPPEN */ break;
+ }
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->i = a;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: AddImm P1 * *
+**
+** Add the value P1 to whatever is on top of the stack. The result
+** is always an integer.
+**
+** To force the top of the stack to be an integer, just add 0.
+*/
+case OP_AddImm: { /* no-push */
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ pTos->i += pOp->p1;
+ break;
+}
+
+/* Opcode: ForceInt P1 P2 *
+**
+** Convert the top of the stack into an integer. If the current top of
+** the stack is not numeric (meaning that is is a NULL or a string that
+** does not look like an integer or floating point number) then pop the
+** stack and jump to P2. If the top of the stack is numeric then
+** convert it into the least integer that is greater than or equal to its
+** current value if P1==0, or to the least integer that is strictly
+** greater than its current value if P1==1.
+*/
+case OP_ForceInt: { /* no-push */
+ i64 v;
+ assert( pTos>=p->aStack );
+ applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+ if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
+ Release(pTos);
+ pTos--;
+ pc = pOp->p2 - 1;
+ break;
+ }
+ if( pTos->flags & MEM_Int ){
+ v = pTos->i + (pOp->p1!=0);
+ }else{
+ Realify(pTos);
+ v = (int)pTos->r;
+ if( pTos->r>(double)v ) v++;
+ if( pOp->p1 && pTos->r==(double)v ) v++;
+ }
+ Release(pTos);
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: MustBeInt P1 P2 *
+**
+** Force the top of the stack to be an integer. If the top of the
+** stack is not an integer and cannot be converted into an integer
+** with out data loss, then jump immediately to P2, or if P2==0
+** raise an SQLITE_MISMATCH exception.
+**
+** If the top of the stack is not an integer and P2 is not zero and
+** P1 is 1, then the stack is popped. In all other cases, the depth
+** of the stack is unchanged.
+*/
+case OP_MustBeInt: { /* no-push */
+ assert( pTos>=p->aStack );
+ applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+ if( (pTos->flags & MEM_Int)==0 ){
+ if( pOp->p2==0 ){
+ rc = SQLITE_MISMATCH;
+ goto abort_due_to_error;
+ }else{
+ if( pOp->p1 ) popStack(&pTos, 1);
+ pc = pOp->p2 - 1;
+ }
+ }else{
+ Release(pTos);
+ pTos->flags = MEM_Int;
+ }
+ break;
+}
+
+/* Opcode: Eq P1 P2 P3
+**
+** Pop the top two elements from the stack. If they are equal, then
+** jump to instruction P2. Otherwise, continue to the next instruction.
+**
+** If the 0x100 bit of P1 is true and either operand is NULL then take the
+** jump. If the 0x100 bit of P1 is false then fall thru if either operand
+** is NULL.
+**
+** The least significant byte of P1 (mask 0xff) must be an affinity character -
+** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
+** according to the affinity before the comparison is made. If the byte is
+** 0x00, then numeric affinity is used.
+**
+** Once any conversions have taken place, and neither value is NULL,
+** the values are compared. If both values are blobs, or both are text,
+** then memcmp() is used to determine the results of the comparison. If
+** both values are numeric, then a numeric comparison is used. If the
+** two values are of different types, then they are inequal.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+**
+** If P3 is not NULL it is a pointer to a collating sequence (a CollSeq
+** structure) that defines how to compare text.
+*/
+/* Opcode: Ne P1 P2 P3
+**
+** This works just like the Eq opcode except that the jump is taken if
+** the operands from the stack are not equal. See the Eq opcode for
+** additional information.
+*/
+/* Opcode: Lt P1 P2 P3
+**
+** This works just like the Eq opcode except that the jump is taken if
+** the 2nd element down on the stack is less than the top of the stack.
+** See the Eq opcode for additional information.
+*/
+/* Opcode: Le P1 P2 P3
+**
+** This works just like the Eq opcode except that the jump is taken if
+** the 2nd element down on the stack is less than or equal to the
+** top of the stack. See the Eq opcode for additional information.
+*/
+/* Opcode: Gt P1 P2 P3
+**
+** This works just like the Eq opcode except that the jump is taken if
+** the 2nd element down on the stack is greater than the top of the stack.
+** See the Eq opcode for additional information.
+*/
+/* Opcode: Ge P1 P2 P3
+**
+** This works just like the Eq opcode except that the jump is taken if
+** the 2nd element down on the stack is greater than or equal to the
+** top of the stack. See the Eq opcode for additional information.
+*/
+case OP_Eq: /* same as TK_EQ, no-push */
+case OP_Ne: /* same as TK_NE, no-push */
+case OP_Lt: /* same as TK_LT, no-push */
+case OP_Le: /* same as TK_LE, no-push */
+case OP_Gt: /* same as TK_GT, no-push */
+case OP_Ge: { /* same as TK_GE, no-push */
+ Mem *pNos;
+ int flags;
+ int res;
+ char affinity;
+
+ pNos = &pTos[-1];
+ flags = pTos->flags|pNos->flags;
+
+ /* If either value is a NULL P2 is not zero, take the jump if the least
+ ** significant byte of P1 is true. If P2 is zero, then push a NULL onto
+ ** the stack.
+ */
+ if( flags&MEM_Null ){
+ popStack(&pTos, 2);
+ if( pOp->p2 ){
+ if( pOp->p1 & 0x100 ) pc = pOp->p2-1;
+ }else{
+ pTos++;
+ pTos->flags = MEM_Null;
+ }
+ break;
+ }
+
+ affinity = pOp->p1 & 0xFF;
+ if( affinity ){
+ applyAffinity(pNos, affinity, db->enc);
+ applyAffinity(pTos, affinity, db->enc);
+ }
+
+ assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
+ res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
+ switch( pOp->opcode ){
+ case OP_Eq: res = res==0; break;
+ case OP_Ne: res = res!=0; break;
+ case OP_Lt: res = res<0; break;
+ case OP_Le: res = res<=0; break;
+ case OP_Gt: res = res>0; break;
+ default: res = res>=0; break;
+ }
+
+ popStack(&pTos, 2);
+ if( pOp->p2 ){
+ if( res ){
+ pc = pOp->p2-1;
+ }
+ }else{
+ pTos++;
+ pTos->flags = MEM_Int;
+ pTos->i = res;
+ }
+ break;
+}
+
+/* Opcode: And * * *
+**
+** Pop two values off the stack. Take the logical AND of the
+** two values and push the resulting boolean value back onto the
+** stack.
+*/
+/* Opcode: Or * * *
+**
+** Pop two values off the stack. Take the logical OR of the
+** two values and push the resulting boolean value back onto the
+** stack.
+*/
+case OP_And: /* same as TK_AND, no-push */
+case OP_Or: { /* same as TK_OR, no-push */
+ Mem *pNos = &pTos[-1];
+ int v1, v2; /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */
+
+ assert( pNos>=p->aStack );
+ if( pTos->flags & MEM_Null ){
+ v1 = 2;
+ }else{
+ Integerify(pTos);
+ v1 = pTos->i==0;
+ }
+ if( pNos->flags & MEM_Null ){
+ v2 = 2;
+ }else{
+ Integerify(pNos);
+ v2 = pNos->i==0;
+ }
+ if( pOp->opcode==OP_And ){
+ static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
+ v1 = and_logic[v1*3+v2];
+ }else{
+ static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
+ v1 = or_logic[v1*3+v2];
+ }
+ popStack(&pTos, 2);
+ pTos++;
+ if( v1==2 ){
+ pTos->flags = MEM_Null;
+ }else{
+ pTos->i = v1==0;
+ pTos->flags = MEM_Int;
+ }
+ break;
+}
+
+/* Opcode: Negative * * *
+**
+** Treat the top of the stack as a numeric quantity. Replace it
+** with its additive inverse. If the top of the stack is NULL
+** its value is unchanged.
+*/
+/* Opcode: AbsValue * * *
+**
+** Treat the top of the stack as a numeric quantity. Replace it
+** with its absolute value. If the top of the stack is NULL
+** its value is unchanged.
+*/
+case OP_Negative: /* same as TK_UMINUS, no-push */
+case OP_AbsValue: {
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Real ){
+ Release(pTos);
+ if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
+ pTos->r = -pTos->r;
+ }
+ pTos->flags = MEM_Real;
+ }else if( pTos->flags & MEM_Int ){
+ Release(pTos);
+ if( pOp->opcode==OP_Negative || pTos->i<0 ){
+ pTos->i = -pTos->i;
+ }
+ pTos->flags = MEM_Int;
+ }else if( pTos->flags & MEM_Null ){
+ /* Do nothing */
+ }else{
+ Realify(pTos);
+ if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
+ pTos->r = -pTos->r;
+ }
+ pTos->flags = MEM_Real;
+ }
+ break;
+}
+
+/* Opcode: Not * * *
+**
+** Interpret the top of the stack as a boolean value. Replace it
+** with its complement. If the top of the stack is NULL its value
+** is unchanged.
+*/
+case OP_Not: { /* same as TK_NOT, no-push */
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
+ Integerify(pTos);
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ pTos->i = !pTos->i;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: BitNot * * *
+**
+** Interpret the top of the stack as an value. Replace it
+** with its ones-complement. If the top of the stack is NULL its
+** value is unchanged.
+*/
+case OP_BitNot: { /* same as TK_BITNOT, no-push */
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
+ Integerify(pTos);
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ pTos->i = ~pTos->i;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: Noop * * *
+**
+** Do nothing. This instruction is often useful as a jump
+** destination.
+*/
+case OP_Noop: { /* no-push */
+ break;
+}
+
+/* Opcode: If P1 P2 *
+**
+** Pop a single boolean from the stack. If the boolean popped is
+** true, then jump to p2. Otherwise continue to the next instruction.
+** An integer is false if zero and true otherwise. A string is
+** false if it has zero length and true otherwise.
+**
+** If the value popped of the stack is NULL, then take the jump if P1
+** is true and fall through if P1 is false.
+*/
+/* Opcode: IfNot P1 P2 *
+**
+** Pop a single boolean from the stack. If the boolean popped is
+** false, then jump to p2. Otherwise continue to the next instruction.
+** An integer is false if zero and true otherwise. A string is
+** false if it has zero length and true otherwise.
+**
+** If the value popped of the stack is NULL, then take the jump if P1
+** is true and fall through if P1 is false.
+*/
+case OP_If: /* no-push */
+case OP_IfNot: { /* no-push */
+ int c;
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Null ){
+ c = pOp->p1;
+ }else{
+#ifdef SQLITE_OMIT_FLOATING_POINT
+ c = sqlite3VdbeIntValue(pTos);
+#else
+ c = sqlite3VdbeRealValue(pTos)!=0.0;
+#endif
+ if( pOp->opcode==OP_IfNot ) c = !c;
+ }
+ Release(pTos);
+ pTos--;
+ if( c ) pc = pOp->p2-1;
+ break;
+}
+
+/* Opcode: IsNull P1 P2 *
+**
+** If any of the top abs(P1) values on the stack are NULL, then jump
+** to P2. Pop the stack P1 times if P1>0. If P1<0 leave the stack
+** unchanged.
+*/
+case OP_IsNull: { /* same as TK_ISNULL, no-push */
+ int i, cnt;
+ Mem *pTerm;
+ cnt = pOp->p1;
+ if( cnt<0 ) cnt = -cnt;
+ pTerm = &pTos[1-cnt];
+ assert( pTerm>=p->aStack );
+ for(i=0; i<cnt; i++, pTerm++){
+ if( pTerm->flags & MEM_Null ){
+ pc = pOp->p2-1;
+ break;
+ }
+ }
+ if( pOp->p1>0 ) popStack(&pTos, cnt);
+ break;
+}
+
+/* Opcode: NotNull P1 P2 *
+**
+** Jump to P2 if the top P1 values on the stack are all not NULL. Pop the
+** stack if P1 times if P1 is greater than zero. If P1 is less than
+** zero then leave the stack unchanged.
+*/
+case OP_NotNull: { /* same as TK_NOTNULL, no-push */
+ int i, cnt;
+ cnt = pOp->p1;
+ if( cnt<0 ) cnt = -cnt;
+ assert( &pTos[1-cnt] >= p->aStack );
+ for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
+ if( i>=cnt ) pc = pOp->p2-1;
+ if( pOp->p1>0 ) popStack(&pTos, cnt);
+ break;
+}
+
+/* Opcode: SetNumColumns P1 P2 *
+**
+** Before the OP_Column opcode can be executed on a cursor, this
+** opcode must be called to set the number of fields in the table.
+**
+** This opcode sets the number of columns for cursor P1 to P2.
+**
+** If OP_KeyAsData is to be applied to cursor P1, it must be executed
+** before this op-code.
+*/
+case OP_SetNumColumns: { /* no-push */
+ Cursor *pC;
+ assert( (pOp->p1)<p->nCursor );
+ assert( p->apCsr[pOp->p1]!=0 );
+ pC = p->apCsr[pOp->p1];
+ pC->nField = pOp->p2;
+ break;
+}
+
+/* Opcode: Column P1 P2 P3
+**
+** Interpret the data that cursor P1 points to as a structure built using
+** the MakeRecord instruction. (See the MakeRecord opcode for additional
+** information about the format of the data.) Push onto the stack the value
+** of the P2-th column contained in the data. If there are less that (P2+1)
+** values in the record, push a NULL onto the stack.
+**
+** If the KeyAsData opcode has previously executed on this cursor, then the
+** field might be extracted from the key rather than the data.
+**
+** If P1 is negative, then the record is stored on the stack rather than in
+** a table. For P1==-1, the top of the stack is used. For P1==-2, the
+** next on the stack is used. And so forth. The value pushed is always
+** 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.
+*/
+case OP_Column: {
+ u32 payloadSize; /* Number of bytes in the record */
+ int p1 = pOp->p1; /* P1 value of the opcode */
+ int p2 = pOp->p2; /* column number to retrieve */
+ Cursor *pC = 0; /* The VDBE cursor */
+ char *zRec; /* Pointer to complete record-data */
+ BtCursor *pCrsr; /* The BTree cursor */
+ u32 *aType; /* aType[i] holds the numeric type of the i-th column */
+ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
+ u32 nField; /* number of fields in the record */
+ u32 szHdr; /* Number of bytes in the record header */
+ int len; /* The length of the serialized data for the column */
+ int offset = 0; /* Offset into the data */
+ int idx; /* Index into the header */
+ int i; /* Loop counter */
+ char *zData; /* Part of the record being decoded */
+ Mem sMem; /* For storing the record being decoded */
+
+ sMem.flags = 0;
+ assert( p1<p->nCursor );
+ pTos++;
+ pTos->flags = MEM_Null;
+
+ /* This block sets the variable payloadSize to be the total number of
+ ** bytes in the record.
+ **
+ ** zRec is set to be the complete text of the record if it is available.
+ ** The complete record text is always available for pseudo-tables and
+ ** when we are decoded a record from the stack. If the record is stored
+ ** in a cursor, the complete record text might be available in the
+ ** pC->aRow cache. Or it might not be. If the data is unavailable,
+ ** zRec is set to NULL.
+ **
+ ** We also compute the number of columns in the record. For cursors,
+ ** the number of columns is stored in the Cursor.nField element. For
+ ** records on the stack, the next entry down on the stack is an integer
+ ** which is the number of records.
+ */
+ assert( p1<0 || p->apCsr[p1]!=0 );
+ if( p1<0 ){
+ /* Take the record off of the stack */
+ Mem *pRec = &pTos[p1];
+ Mem *pCnt = &pRec[-1];
+ assert( pRec>=p->aStack );
+ assert( pRec->flags & MEM_Blob );
+ payloadSize = pRec->n;
+ zRec = pRec->z;
+ assert( pCnt>=p->aStack );
+ assert( pCnt->flags & MEM_Int );
+ nField = pCnt->i;
+ pCrsr = 0;
+ }else if( (pC = p->apCsr[p1])->pCursor!=0 ){
+ /* The record is stored in a B-Tree */
+ rc = sqlite3VdbeCursorMoveto(pC);
+ if( rc ) goto abort_due_to_error;
+ zRec = 0;
+ pCrsr = pC->pCursor;
+ if( pC->nullRow ){
+ payloadSize = 0;
+ }else if( pC->cacheValid ){
+ payloadSize = pC->payloadSize;
+ zRec = pC->aRow;
+ }else if( pC->isIndex ){
+ i64 payloadSize64;
+ sqlite3BtreeKeySize(pCrsr, &payloadSize64);
+ payloadSize = payloadSize64;
+ }else{
+ sqlite3BtreeDataSize(pCrsr, &payloadSize);
+ }
+ nField = pC->nField;
+#ifndef SQLITE_OMIT_TRIGGER
+ }else if( pC->pseudoTable ){
+ /* The record is the sole entry of a pseudo-table */
+ payloadSize = pC->nData;
+ zRec = pC->pData;
+ pC->cacheValid = 0;
+ assert( payloadSize==0 || zRec!=0 );
+ nField = pC->nField;
+ pCrsr = 0;
+#endif
+ }else{
+ zRec = 0;
+ payloadSize = 0;
+ pCrsr = 0;
+ nField = 0;
+ }
+
+ /* If payloadSize is 0, then just push a NULL onto the stack. */
+ if( payloadSize==0 ){
+ pTos->flags = MEM_Null;
+ break;
+ }
+
+ assert( p2<nField );
+
+ /* Read and parse the table header. Store the results of the parse
+ ** into the record header cache fields of the cursor.
+ */
+ if( pC && pC->cacheValid ){
+ aType = pC->aType;
+ aOffset = pC->aOffset;
+ }else{
+ int avail; /* Number of bytes of available data */
+ if( pC && pC->aType ){
+ aType = pC->aType;
+ }else{
+ aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
+ }
+ aOffset = &aType[nField];
+ if( aType==0 ){
+ goto no_mem;
+ }
+
+ /* Figure out how many bytes are in the header */
+ if( zRec ){
+ zData = zRec;
+ }else{
+ if( pC->isIndex ){
+ zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
+ }else{
+ zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
+ }
+ /* If KeyFetch()/DataFetch() managed to get the entire payload,
+ ** save the payload in the pC->aRow cache. That will save us from
+ ** having to make additional calls to fetch the content portion of
+ ** the record.
+ */
+ if( avail>=payloadSize ){
+ zRec = pC->aRow = zData;
+ }else{
+ pC->aRow = 0;
+ }
+ }
+ idx = sqlite3GetVarint32(zData, &szHdr);
+
+
+ /* The KeyFetch() or DataFetch() above are fast and will get the entire
+ ** record header in most cases. But they will fail to get the complete
+ ** record header if the record header does not fit on a single page
+ ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
+ ** acquire the complete header text.
+ */
+ if( !zRec && avail<szHdr ){
+ rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->isIndex, &sMem);
+ if( rc!=SQLITE_OK ){
+ goto op_column_out;
+ }
+ zData = sMem.z;
+ }
+
+ /* Scan the header and use it to fill in the aType[] and aOffset[]
+ ** arrays. aType[i] will contain the type integer for the i-th
+ ** column and aOffset[i] will contain the offset from the beginning
+ ** of the record to the start of the data for the i-th column
+ */
+ offset = szHdr;
+ assert( offset>0 );
+ i = 0;
+ while( idx<szHdr && i<nField && offset<=payloadSize ){
+ aOffset[i] = offset;
+ idx += sqlite3GetVarint32(&zData[idx], &aType[i]);
+ offset += sqlite3VdbeSerialTypeLen(aType[i]);
+ i++;
+ }
+ Release(&sMem);
+ sMem.flags = MEM_Null;
+
+ /* If i is less that nField, then there are less fields in this
+ ** record than SetNumColumns indicated there are columns in the
+ ** table. Set the offset for any extra columns not present in
+ ** the record to 0. This tells code below to push a NULL onto the
+ ** stack instead of deserializing a value from the record.
+ */
+ while( i<nField ){
+ aOffset[i++] = 0;
+ }
+
+ /* The header should end at the start of data and the data should
+ ** end at last byte of the record. If this is not the case then
+ ** we are dealing with a malformed record.
+ */
+ if( idx!=szHdr || offset!=payloadSize ){
+ rc = SQLITE_CORRUPT;
+ goto op_column_out;
+ }
+
+ /* Remember all aType and aColumn information if we have a cursor
+ ** to remember it in. */
+ if( pC ){
+ pC->payloadSize = payloadSize;
+ pC->aType = aType;
+ pC->aOffset = aOffset;
+ pC->cacheValid = 1;
+ }
+ }
+
+ /* 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.
+ */
+ if( aOffset[p2] ){
+ assert( rc==SQLITE_OK );
+ if( zRec ){
+ zData = &zRec[aOffset[p2]];
+ }else{
+ len = sqlite3VdbeSerialTypeLen(aType[p2]);
+ rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex,&sMem);
+ if( rc!=SQLITE_OK ){
+ goto op_column_out;
+ }
+ zData = sMem.z;
+ }
+ sqlite3VdbeSerialGet(zData, aType[p2], pTos);
+ pTos->enc = db->enc;
+ }else{
+ if( pOp->p3 ){
+ sqlite3VdbeMemShallowCopy(pTos, (Mem *)(pOp->p3), MEM_Static);
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ }
+
+ /* If we dynamically allocated space to hold the data (in the
+ ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
+ ** dynamically allocated space over to the pTos structure rather.
+ ** This prevents a memory copy.
+ */
+ if( (sMem.flags & MEM_Dyn)!=0 ){
+ assert( pTos->flags & MEM_Ephem );
+ assert( pTos->flags & (MEM_Str|MEM_Blob) );
+ assert( pTos->z==sMem.z );
+ assert( sMem.flags & MEM_Term );
+ pTos->flags &= ~MEM_Ephem;
+ pTos->flags |= MEM_Dyn|MEM_Term;
+ }
+
+ /* pTos->z might be pointing to sMem.zShort[]. Fix that so that we
+ ** can abandon sMem */
+ rc = sqlite3VdbeMemMakeWriteable(pTos);
+
+op_column_out:
+ /* Release the aType[] memory if we are not dealing with cursor */
+ if( !pC || !pC->aType ){
+ sqliteFree(aType);
+ }
+ break;
+}
+
+/* Opcode: MakeRecord P1 P2 P3
+**
+** Convert the top abs(P1) entries of the stack into a single entry
+** suitable for use as a data record in a database table or as a key
+** in an index. The details of the format are irrelavant as long as
+** the OP_Column opcode can decode the record later and as long as the
+** sqlite3VdbeRecordCompare function will correctly compare two encoded
+** records. Refer to source code comments for the details of the record
+** format.
+**
+** 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.
+**
+** 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
+** field of the index key (i.e. the first character of P3 corresponds to the
+** lowest element on the stack).
+**
+** The mapping from character to affinity is as follows:
+** 'n' = NUMERIC.
+** 'i' = INTEGER.
+** 't' = TEXT.
+** 'o' = NONE.
+**
+** If P3 is NULL then all index fields have the affinity NONE.
+*/
+case OP_MakeRecord: {
+ /* Assuming the record contains N fields, the record format looks
+ ** like this:
+ **
+ ** ------------------------------------------------------------------------
+ ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
+ ** ------------------------------------------------------------------------
+ **
+ ** Data(0) is taken from the lowest element of the stack and data(N-1) is
+ ** the top of the stack.
+ **
+ ** Each type field is a varint representing the serial type of the
+ ** corresponding data element (see sqlite3VdbeSerialType()). The
+ ** hdr-size field is also a varint which is the offset from the beginning
+ ** of the record to data0.
+ */
+ unsigned char *zNewRecord;
+ unsigned char *zCsr;
+ Mem *pRec;
+ Mem *pRowid = 0;
+ int nData = 0; /* Number of bytes of data space */
+ int nHdr = 0; /* Number of bytes of header space */
+ int nByte = 0; /* Space required for this record */
+ int nVarint; /* Number of bytes in a varint */
+ u32 serial_type; /* Type field */
+ int containsNull = 0; /* True if any of the data fields are NULL */
+ char zTemp[NBFS]; /* Space to hold small records */
+ Mem *pData0;
+
+ int leaveOnStack; /* If true, leave the entries on the stack */
+ int nField; /* Number of fields in the record */
+ int jumpIfNull; /* Jump here if non-zero and any entries are NULL. */
+ int addRowid; /* True to append a rowid column at the end */
+ char *zAffinity; /* The affinity string for the record */
+
+ leaveOnStack = ((pOp->p1<0)?1:0);
+ nField = pOp->p1 * (leaveOnStack?-1:1);
+ jumpIfNull = (pOp->p2 & 0x00FFFFFF);
+ addRowid = ((pOp->p2>>24) & 0x0000FFFF)?1:0;
+ zAffinity = pOp->p3;
+
+ pData0 = &pTos[1-nField];
+ assert( pData0>=p->aStack );
+ containsNull = 0;
+
+ /* Loop through the elements that will make up the record to figure
+ ** out how much space is required for the new record.
+ */
+ for(pRec=pData0; pRec<=pTos; pRec++){
+ if( zAffinity ){
+ applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
+ }
+ if( pRec->flags&MEM_Null ){
+ containsNull = 1;
+ }
+ serial_type = sqlite3VdbeSerialType(pRec);
+ nData += sqlite3VdbeSerialTypeLen(serial_type);
+ nHdr += sqlite3VarintLen(serial_type);
+ }
+
+ /* If we have to append a varint rowid to this record, set 'rowid'
+ ** to the value of the rowid and increase nByte by the amount of space
+ ** required to store it and the 0x00 seperator byte.
+ */
+ if( addRowid ){
+ pRowid = &pTos[0-nField];
+ assert( pRowid>=p->aStack );
+ Integerify(pRowid);
+ serial_type = sqlite3VdbeSerialType(pRowid);
+ nData += sqlite3VdbeSerialTypeLen(serial_type);
+ nHdr += sqlite3VarintLen(serial_type);
+ }
+
+ /* Add the initial header varint and total the size */
+ nHdr += nVarint = sqlite3VarintLen(nHdr);
+ if( nVarint<sqlite3VarintLen(nHdr) ){
+ nHdr++;
+ }
+ nByte = nHdr+nData;
+
+ /* Allocate space for the new record. */
+ if( nByte>sizeof(zTemp) ){
+ zNewRecord = sqliteMallocRaw(nByte);
+ if( !zNewRecord ){
+ goto no_mem;
+ }
+ }else{
+ zNewRecord = zTemp;
+ }
+
+ /* Write the record */
+ zCsr = zNewRecord;
+ zCsr += sqlite3PutVarint(zCsr, nHdr);
+ for(pRec=pData0; pRec<=pTos; pRec++){
+ serial_type = sqlite3VdbeSerialType(pRec);
+ zCsr += sqlite3PutVarint(zCsr, serial_type); /* serial type */
+ }
+ if( addRowid ){
+ zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid));
+ }
+ for(pRec=pData0; pRec<=pTos; pRec++){
+ zCsr += sqlite3VdbeSerialPut(zCsr, pRec); /* serial data */
+ }
+ if( addRowid ){
+ zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
+ }
+ assert( zCsr==(zNewRecord+nByte) );
+
+ /* Pop entries off the stack if required. Push the new record on. */
+ if( !leaveOnStack ){
+ popStack(&pTos, nField+addRowid);
+ }
+ pTos++;
+ pTos->n = nByte;
+ if( nByte<=sizeof(zTemp) ){
+ assert( zNewRecord==(unsigned char *)zTemp );
+ pTos->z = pTos->zShort;
+ memcpy(pTos->zShort, zTemp, nByte);
+ pTos->flags = MEM_Blob | MEM_Short;
+ }else{
+ assert( zNewRecord!=(unsigned char *)zTemp );
+ pTos->z = zNewRecord;
+ pTos->flags = MEM_Blob | MEM_Dyn;
+ pTos->xDel = 0;
+ }
+
+ /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
+ if( jumpIfNull && containsNull ){
+ pc = jumpIfNull - 1;
+ }
+ break;
+}
+
+/* Opcode: Statement P1 * *
+**
+** Begin an individual statement transaction which is part of a larger
+** BEGIN..COMMIT transaction. This is needed so that the statement
+** can be rolled back after an error without having to roll back the
+** entire transaction. The statement transaction will automatically
+** commit when the VDBE halts.
+**
+** The statement is begun on the database file with index P1. The main
+** database file has an index of 0 and the file used for temporary tables
+** has an index of 1.
+*/
+case OP_Statement: { /* no-push */
+ int i = pOp->p1;
+ Btree *pBt;
+ if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt) && !(db->autoCommit) ){
+ assert( sqlite3BtreeIsInTrans(pBt) );
+ if( !sqlite3BtreeIsInStmt(pBt) ){
+ rc = sqlite3BtreeBeginStmt(pBt);
+ }
+ }
+ break;
+}
+
+/* Opcode: AutoCommit P1 P2 *
+**
+** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
+** back any currently active btree transactions. If there are any active
+** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
+**
+** This instruction causes the VM to halt.
+*/
+case OP_AutoCommit: { /* no-push */
+ u8 i = pOp->p1;
+ u8 rollback = pOp->p2;
+
+ assert( i==1 || i==0 );
+ assert( i==1 || rollback==0 );
+
+ assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
+
+ if( db->activeVdbeCnt>1 && i && !db->autoCommit ){
+ /* If this instruction implements a COMMIT or ROLLBACK, other VMs are
+ ** still running, and a transaction is active, return an error indicating
+ ** that the other VMs must complete first.
+ */
+ sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit",
+ " transaction - SQL statements in progress", 0);
+ rc = SQLITE_ERROR;
+ }else if( i!=db->autoCommit ){
+ db->autoCommit = i;
+ if( pOp->p2 ){
+ assert( i==1 );
+ sqlite3RollbackAll(db);
+ }else if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+ p->pTos = pTos;
+ p->pc = pc;
+ db->autoCommit = 1-i;
+ p->rc = SQLITE_BUSY;
+ return SQLITE_BUSY;
+ }
+ return SQLITE_DONE;
+ }else{
+ sqlite3SetString(&p->zErrMsg,
+ (!i)?"cannot start a transaction within a transaction":(
+ (rollback)?"cannot rollback - no transaction is active":
+ "cannot commit - no transaction is active"), 0);
+
+ rc = SQLITE_ERROR;
+ }
+ break;
+}
+
+/* Opcode: Transaction P1 P2 *
+**
+** Begin a transaction. The transaction ends when a Commit or Rollback
+** opcode is encountered. Depending on the ON CONFLICT setting, the
+** transaction might also be rolled back if an error is encountered.
+**
+** P1 is the index of the database file on which the transaction is
+** started. Index 0 is the main database file and index 1 is the
+** file used for temporary tables.
+**
+** If P2 is non-zero, then a write-transaction is started. A RESERVED lock is
+** obtained on the database file when a write-transaction is started. No
+** other process can start another write transaction while this transaction is
+** underway. Starting a write transaction also creates a rollback journal. A
+** write transaction must be started before any changes can be made to the
+** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
+** on the file.
+**
+** If P2 is zero, then a read-lock is obtained on the database file.
+*/
+case OP_Transaction: { /* no-push */
+ int i = pOp->p1;
+ Btree *pBt;
+
+ assert( i>=0 && i<db->nDb );
+ pBt = db->aDb[i].pBt;
+
+ if( pBt ){
+ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
+ if( rc==SQLITE_BUSY ){
+ p->pc = pc;
+ p->rc = SQLITE_BUSY;
+ p->pTos = pTos;
+ return SQLITE_BUSY;
+ }
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
+ goto abort_due_to_error;
+ }
+ }
+ break;
+}
+
+/* Opcode: ReadCookie P1 P2 *
+**
+** Read cookie number P2 from database P1 and push it onto the stack.
+** P2==0 is the schema version. P2==1 is the database format.
+** P2==2 is the recommended pager cache size, and so forth. P1==0 is
+** the main database file and P1==1 is the database file used to store
+** temporary tables.
+**
+** There must be a read-lock on the database (either a transaction
+** must be started or there must be an open cursor) before
+** executing this instruction.
+*/
+case OP_ReadCookie: {
+ int iMeta;
+ assert( pOp->p2<SQLITE_N_BTREE_META );
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ assert( db->aDb[pOp->p1].pBt!=0 );
+ /* The indexing of meta values at the schema layer is off by one from
+ ** the indexing in the btree layer. The btree considers meta[0] to
+ ** be the number of free pages in the database (a read-only value)
+ ** and meta[1] to be the schema cookie. The schema layer considers
+ ** meta[1] to be the schema cookie. So we have to shift the index
+ ** by one in the following statement.
+ */
+ rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1 + pOp->p2, (u32 *)&iMeta);
+ pTos++;
+ pTos->i = iMeta;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: SetCookie P1 P2 *
+**
+** Write the top of the stack into cookie number P2 of database P1.
+** P2==0 is the schema version. P2==1 is the database format.
+** P2==2 is the recommended pager cache size, and so forth. P1==0 is
+** the main database file and P1==1 is the database file used to store
+** temporary tables.
+**
+** A transaction must be started before executing this opcode.
+*/
+case OP_SetCookie: { /* no-push */
+ Db *pDb;
+ assert( pOp->p2<SQLITE_N_BTREE_META );
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ pDb = &db->aDb[pOp->p1];
+ assert( pDb->pBt!=0 );
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ /* See note about index shifting on OP_ReadCookie */
+ rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i);
+ if( pOp->p2==0 ){
+ /* When the schema cookie changes, record the new cookie internally */
+ pDb->schema_cookie = pTos->i;
+ db->flags |= SQLITE_InternChanges;
+ }
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ pTos--;
+ break;
+}
+
+/* Opcode: VerifyCookie P1 P2 *
+**
+** Check the value of global database parameter number 0 (the
+** schema version) and make sure it is equal to P2.
+** P1 is the database number which is 0 for the main database file
+** and 1 for the file holding temporary tables and some higher number
+** for auxiliary databases.
+**
+** The cookie changes its value whenever the database schema changes.
+** This operation is used to detect when that the cookie has changed
+** and that the current process needs to reread the schema.
+**
+** Either a transaction needs to have been started or an OP_Open needs
+** to be executed (to establish a read lock) before this opcode is
+** invoked.
+*/
+case OP_VerifyCookie: { /* no-push */
+ int iMeta;
+ Btree *pBt;
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ pBt = db->aDb[pOp->p1].pBt;
+ if( pBt ){
+ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta);
+ }else{
+ rc = SQLITE_OK;
+ iMeta = 0;
+ }
+ if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
+ sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0);
+ rc = SQLITE_SCHEMA;
+ }
+ break;
+}
+
+/* Opcode: OpenRead P1 P2 P3
+**
+** Open a read-only cursor for the database table whose root page is
+** P2 in a database file. The database file is determined by an
+** integer from the top of the stack. 0 means the main database and
+** 1 means the database used for temporary tables. Give the new
+** cursor an identifier of P1. The P1 values need not be contiguous
+** but all P1 values should be small integers. It is an error for
+** P1 to be negative.
+**
+** If P2==0 then take the root page number from the next of the stack.
+**
+** There will be a read lock on the database whenever there is an
+** open cursor. If the database was unlocked prior to this instruction
+** then a read lock is acquired as part of this instruction. A read
+** lock allows other processes to read the database but prohibits
+** any other process from modifying the database. The read lock is
+** released when all cursors are closed. If this instruction attempts
+** to get a read lock but fails, the script terminates with an
+** SQLITE_BUSY error code.
+**
+** The P3 value is a pointer to a KeyInfo structure that defines the
+** content and collating sequence of indices. P3 is NULL for cursors
+** that are not pointing to indices.
+**
+** See also OpenWrite.
+*/
+/* Opcode: OpenWrite P1 P2 P3
+**
+** Open a read/write cursor named P1 on the table or index whose root
+** page is P2. If P2==0 then take the root page number from the stack.
+**
+** The P3 value is a pointer to a KeyInfo structure that defines the
+** content and collating sequence of indices. P3 is NULL for cursors
+** that are not pointing to indices.
+**
+** This instruction works just like OpenRead except that it opens the cursor
+** in read/write mode. For a given table, there can be one or more read-only
+** cursors or a single read/write cursor but not both.
+**
+** See also OpenRead.
+*/
+case OP_OpenRead: /* no-push */
+case OP_OpenWrite: { /* no-push */
+ int i = pOp->p1;
+ int p2 = pOp->p2;
+ int wrFlag;
+ Btree *pX;
+ int iDb;
+ Cursor *pCur;
+
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ iDb = pTos->i;
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ pTos--;
+ assert( iDb>=0 && iDb<db->nDb );
+ pX = db->aDb[iDb].pBt;
+ assert( pX!=0 );
+ wrFlag = pOp->opcode==OP_OpenWrite;
+ if( p2<=0 ){
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ 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( i>=0 );
+ pCur = allocateCursor(p, i);
+ if( pCur==0 ) goto no_mem;
+ pCur->nullRow = 1;
+ if( pX==0 ) break;
+ /* We always provide a key comparison function. If the table being
+ ** opened is of type INTKEY, the comparision function will be ignored. */
+ rc = sqlite3BtreeCursor(pX, p2, wrFlag,
+ sqlite3VdbeRecordCompare, pOp->p3,
+ &pCur->pCursor);
+ if( pOp->p3type==P3_KEYINFO ){
+ pCur->pKeyInfo = (KeyInfo*)pOp->p3;
+ pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
+ pCur->pKeyInfo->enc = p->db->enc;
+ }else{
+ pCur->pKeyInfo = 0;
+ pCur->pIncrKey = &pCur->bogusIncrKey;
+ }
+ switch( rc ){
+ case SQLITE_BUSY: {
+ p->pc = pc;
+ p->rc = SQLITE_BUSY;
+ p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
+ return SQLITE_BUSY;
+ }
+ case SQLITE_OK: {
+ int flags = sqlite3BtreeFlags(pCur->pCursor);
+ /* Sanity checking. Only the lower four bits of the flags byte should
+ ** be used. Bit 3 (mask 0x08) is unpreditable. The lower 3 bits
+ ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
+ ** 2 (zerodata for indices). If these conditions are not met it can
+ ** only mean that we are dealing with a corrupt database file
+ */
+ if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
+ rc = SQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
+ pCur->isTable = (flags & BTREE_INTKEY)!=0;
+ pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
+ /* If P3==0 it means we are expected to open a table. If P3!=0 then
+ ** we expect to be opening an index. If this is not what happened,
+ ** then the database is corrupt
+ */
+ if( (pCur->isTable && pOp->p3type==P3_KEYINFO)
+ || (pCur->isIndex && pOp->p3type!=P3_KEYINFO) ){
+ rc = SQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
+ break;
+ }
+ case SQLITE_EMPTY: {
+ pCur->isTable = pOp->p3type!=P3_KEYINFO;
+ pCur->isIndex = !pCur->isTable;
+ rc = SQLITE_OK;
+ break;
+ }
+ default: {
+ goto abort_due_to_error;
+ }
+ }
+ break;
+}
+
+/* Opcode: OpenTemp 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.
+**
+** 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 */
+ int i = pOp->p1;
+ Cursor *pCx;
+ assert( i>=0 );
+ pCx = allocateCursor(p, i);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
+ }
+ if( rc==SQLITE_OK ){
+ /* If a transient index is required, create it by calling
+ ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
+ ** opening it. If a transient table is required, just use the
+ ** automatically created table with root-page 1 (an INTKEY table).
+ */
+ if( pOp->p3 ){
+ int pgno;
+ assert( pOp->p3type==P3_KEYINFO );
+ rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA);
+ if( rc==SQLITE_OK ){
+ assert( pgno==MASTER_ROOT+1 );
+ rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
+ pOp->p3, &pCx->pCursor);
+ pCx->pKeyInfo = (KeyInfo*)pOp->p3;
+ pCx->pKeyInfo->enc = p->db->enc;
+ pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
+ }
+ pCx->isTable = 0;
+ }else{
+ rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
+ pCx->isTable = 1;
+ pCx->pIncrKey = &pCx->bogusIncrKey;
+ }
+ }
+ pCx->isIndex = !pCx->isTable;
+ break;
+}
+
+#ifndef SQLITE_OMIT_TRIGGER
+/* Opcode: OpenPseudo P1 * *
+**
+** Open a new cursor that points to a fake table that contains a single
+** row of data. Any attempt to write a second row of data causes the
+** first row to be deleted. All data is deleted when the cursor is
+** closed.
+**
+** A pseudo-table created by this opcode is useful for holding the
+** NEW or OLD tables in a trigger.
+*/
+case OP_OpenPseudo: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pCx;
+ assert( i>=0 );
+ pCx = allocateCursor(p, i);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ pCx->pseudoTable = 1;
+ pCx->pIncrKey = &pCx->bogusIncrKey;
+ pCx->isTable = 1;
+ pCx->isIndex = 0;
+ break;
+}
+#endif
+
+/* Opcode: Close P1 * *
+**
+** Close a cursor previously opened as P1. If P1 is not
+** currently open, this instruction is a no-op.
+*/
+case OP_Close: { /* no-push */
+ int i = pOp->p1;
+ if( i>=0 && i<p->nCursor ){
+ sqlite3VdbeFreeCursor(p->apCsr[i]);
+ p->apCsr[i] = 0;
+ }
+ break;
+}
+
+/* Opcode: MoveGe P1 P2 *
+**
+** Pop the top of the stack and use its value as a key. Reposition
+** cursor P1 so that it points to the smallest entry that is greater
+** than or equal to the key that was popped ffrom the stack.
+** If there are no records greater than or equal to the key and P2
+** is not zero, then jump to P2.
+**
+** See also: Found, NotFound, Distinct, MoveLt, MoveGt, MoveLe
+*/
+/* Opcode: MoveGt P1 P2 *
+**
+** Pop the top of the stack and use its value as a key. Reposition
+** cursor P1 so that it points to the smallest entry that is greater
+** than the key from the stack.
+** If there are no records greater than the key and P2 is not zero,
+** then jump to P2.
+**
+** See also: Found, NotFound, Distinct, MoveLt, MoveGe, MoveLe
+*/
+/* Opcode: MoveLt P1 P2 *
+**
+** Pop the top of the stack and use its value as a key. Reposition
+** cursor P1 so that it points to the largest entry that is less
+** than the key from the stack.
+** If there are no records less than the key and P2 is not zero,
+** then jump to P2.
+**
+** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLe
+*/
+/* Opcode: MoveLe P1 P2 *
+**
+** Pop the top of the stack and use its value as a key. Reposition
+** cursor P1 so that it points to the largest entry that is less than
+** or equal to the key that was popped from the stack.
+** If there are no records less than or eqal to the key and P2 is not zero,
+** then jump to P2.
+**
+** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
+*/
+case OP_MoveLt: /* no-push */
+case OP_MoveLe: /* no-push */
+case OP_MoveGe: /* no-push */
+case OP_MoveGt: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ pC = p->apCsr[i];
+ assert( pC!=0 );
+ if( pC->pCursor!=0 ){
+ int res, oc;
+ oc = pOp->opcode;
+ pC->nullRow = 0;
+ *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
+ if( pC->isTable ){
+ i64 iKey;
+ Integerify(pTos);
+ iKey = intToKey(pTos->i);
+ if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){
+ pC->movetoTarget = iKey;
+ pC->deferredMoveto = 1;
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ pTos--;
+ break;
+ }
+ rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ pC->lastRowid = pTos->i;
+ pC->rowidIsValid = res==0;
+ }else{
+ Stringify(pTos, db->enc);
+ rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ pC->rowidIsValid = 0;
+ }
+ pC->deferredMoveto = 0;
+ pC->cacheValid = 0;
+ *pC->pIncrKey = 0;
+ sqlite3_search_count++;
+ if( oc==OP_MoveGe || oc==OP_MoveGt ){
+ if( res<0 ){
+ rc = sqlite3BtreeNext(pC->pCursor, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ pC->rowidIsValid = 0;
+ }else{
+ res = 0;
+ }
+ }else{
+ assert( oc==OP_MoveLt || oc==OP_MoveLe );
+ if( res>=0 ){
+ rc = sqlite3BtreePrevious(pC->pCursor, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ pC->rowidIsValid = 0;
+ }else{
+ /* res might be negative because the table is empty. Check to
+ ** see if this is the case.
+ */
+ res = sqlite3BtreeEof(pC->pCursor);
+ }
+ }
+ if( res ){
+ if( pOp->p2>0 ){
+ pc = pOp->p2 - 1;
+ }else{
+ pC->nullRow = 1;
+ }
+ }
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: Distinct P1 P2 *
+**
+** Use the top of the stack as a record created using MakeRecord. P1 is a
+** cursor on a table that declared as an index. If that table contains an
+** entry that matches the top of the stack fall thru. If the top of the stack
+** matches no entry in P1 then jump to P2.
+**
+** The cursor is left pointing at the matching entry if it exists. The
+** record on the top of the stack is not popped.
+**
+** This instruction is similar to NotFound except that this operation
+** does not pop the key from the stack.
+**
+** The instruction is used to implement the DISTINCT operator on SELECT
+** statements. The P1 table is not a true index but rather a record of
+** all results that have produced so far.
+**
+** See also: Found, NotFound, MoveTo, IsUnique, NotExists
+*/
+/* Opcode: Found P1 P2 *
+**
+** Top of the stack holds a blob constructed by MakeRecord. P1 is an index.
+** If an entry that matches the top of the stack exists in P1 then
+** jump to P2. If the top of the stack does not match any entry in P1
+** then fall thru. The P1 cursor is left pointing at the matching entry
+** if it exists. The blob is popped off the top of the stack.
+**
+** This instruction is used to implement the IN operator where the
+** left-hand side is a SELECT statement. P1 is not a true index but
+** is instead a temporary index that holds the results of the SELECT
+** statement. This instruction just checks to see if the left-hand side
+** of the IN operator (stored on the top of the stack) exists in the
+** result of the SELECT statement.
+**
+** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
+*/
+/* Opcode: NotFound P1 P2 *
+**
+** The top of the stack holds a blob constructed by MakeRecord. P1 is
+** an index. If no entry exists in P1 that matches the blob then jump
+** to P1. If an entry does existing, fall through. The cursor is left
+** pointing to the entry that matches. The blob is popped from the stack.
+**
+** The difference between this operation and Distinct is that
+** Distinct does not pop the key from the stack.
+**
+** See also: Distinct, Found, MoveTo, NotExists, IsUnique
+*/
+case OP_Distinct: /* no-push */
+case OP_NotFound: /* no-push */
+case OP_Found: { /* no-push */
+ int i = pOp->p1;
+ int alreadyExists = 0;
+ Cursor *pC;
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ if( (pC = p->apCsr[i])->pCursor!=0 ){
+ int res, rx;
+ assert( pC->isTable==0 );
+ Stringify(pTos, db->enc);
+ rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+ alreadyExists = rx==SQLITE_OK && res==0;
+ pC->deferredMoveto = 0;
+ pC->cacheValid = 0;
+ }
+ if( pOp->opcode==OP_Found ){
+ if( alreadyExists ) pc = pOp->p2 - 1;
+ }else{
+ if( !alreadyExists ) pc = pOp->p2 - 1;
+ }
+ if( pOp->opcode!=OP_Distinct ){
+ Release(pTos);
+ pTos--;
+ }
+ break;
+}
+
+/* Opcode: IsUnique P1 P2 *
+**
+** The top of the stack is an integer record number. Call this
+** record number R. The next on the stack is an index key created
+** using MakeIdxKey. Call it K. This instruction pops R from the
+** stack but it leaves K unchanged.
+**
+** P1 is an index. So it has no data and its key consists of a
+** record generated by OP_MakeRecord where the last field is the
+** rowid of the entry that the index refers to.
+**
+** This instruction asks if there is an entry in P1 where the
+** fields matches K but the rowid is different from R.
+** If there is no such entry, then there is an immediate
+** jump to P2. If any entry does exist where the index string
+** matches K but the record number is not R, then the record
+** number for that entry is pushed onto the stack and control
+** falls through to the next instruction.
+**
+** See also: Distinct, NotFound, NotExists, Found
+*/
+case OP_IsUnique: { /* no-push */
+ int i = pOp->p1;
+ Mem *pNos = &pTos[-1];
+ Cursor *pCx;
+ BtCursor *pCrsr;
+ i64 R;
+
+ /* Pop the value R off the top of the stack
+ */
+ assert( pNos>=p->aStack );
+ Integerify(pTos);
+ R = pTos->i;
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ pTos--;
+ assert( i>=0 && i<=p->nCursor );
+ pCx = p->apCsr[i];
+ assert( pCx!=0 );
+ pCrsr = pCx->pCursor;
+ if( pCrsr!=0 ){
+ int res, rc;
+ i64 v; /* The record number on the P1 entry that matches K */
+ char *zKey; /* The value of K */
+ int nKey; /* Number of bytes in K */
+ int len; /* Number of bytes in K without the rowid at the end */
+ int szRowid; /* Size of the rowid column at the end of zKey */
+
+ /* Make sure K is a string and make zKey point to K
+ */
+ Stringify(pNos, db->enc);
+ zKey = pNos->z;
+ nKey = pNos->n;
+
+ szRowid = sqlite3VdbeIdxRowidLen(nKey, zKey);
+ len = nKey-szRowid;
+
+ /* Search for an entry in P1 where all but the last four bytes match K.
+ ** If there is no such entry, jump immediately to P2.
+ */
+ assert( pCx->deferredMoveto==0 );
+ pCx->cacheValid = 0;
+ rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ if( res<0 ){
+ rc = sqlite3BtreeNext(pCrsr, &res);
+ if( res ){
+ pc = pOp->p2 - 1;
+ break;
+ }
+ }
+ rc = sqlite3VdbeIdxKeyCompare(pCx, len, zKey, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ if( res>0 ){
+ pc = pOp->p2 - 1;
+ break;
+ }
+
+ /* At this point, pCrsr is pointing to an entry in P1 where all but
+ ** the final entry (the rowid) matches K. Check to see if the
+ ** final rowid column is different from R. If it equals R then jump
+ ** immediately to P2.
+ */
+ rc = sqlite3VdbeIdxRowid(pCrsr, &v);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ if( v==R ){
+ pc = pOp->p2 - 1;
+ break;
+ }
+
+ /* The final varint of the key is different from R. Push it onto
+ ** the stack. (The record number of an entry that violates a UNIQUE
+ ** constraint.)
+ */
+ pTos++;
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ }
+ break;
+}
+
+/* Opcode: NotExists P1 P2 *
+**
+** Use the top of the stack as a integer key. If a record with that key
+** does not exist in table of P1, then jump to P2. If the record
+** does exist, then fall thru. The cursor is left pointing to the
+** record if it exists. The integer key is popped from the stack.
+**
+** The difference between this operation and NotFound is that this
+** operation assumes the key is an integer and that P1 is a table whereas
+** NotFound assumes key is a blob constructed from MakeRecord and
+** P1 is an index.
+**
+** See also: Distinct, Found, MoveTo, NotFound, IsUnique
+*/
+case OP_NotExists: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+ BtCursor *pCrsr;
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
+ int res;
+ u64 iKey;
+ assert( pTos->flags & MEM_Int );
+ assert( p->apCsr[i]->isTable );
+ iKey = intToKey(pTos->i);
+ rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
+ pC->lastRowid = pTos->i;
+ pC->rowidIsValid = res==0;
+ pC->nullRow = 0;
+ pC->cacheValid = 0;
+ if( res!=0 ){
+ pc = pOp->p2 - 1;
+ pC->rowidIsValid = 0;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: NewRowid P1 P2 *
+**
+** Get a new integer record number (a.k.a "rowid") used as the key to a table.
+** The record number is not previously used as a key in the database
+** table that cursor P1 points to. The new record number is pushed
+** onto the stack.
+**
+** If P2>0 then P2 is a memory cell that holds the largest previously
+** generated record number. No new record numbers are allowed to be less
+** than this value. When this value reaches its maximum, a SQLITE_FULL
+** error is generated. The P2 memory cell is updated with the generated
+** record number. This P2 mechanism is used to help implement the
+** AUTOINCREMENT feature.
+*/
+case OP_NewRowid: {
+ int i = pOp->p1;
+ i64 v = 0;
+ Cursor *pC;
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ if( (pC = p->apCsr[i])->pCursor==0 ){
+ /* The zero initialization above is all that is needed */
+ }else{
+ /* The next rowid or record number (different terms for the same
+ ** thing) is obtained in a two-step algorithm.
+ **
+ ** First we attempt to find the largest existing rowid and add one
+ ** to that. But if the largest existing rowid is already the maximum
+ ** positive integer, we have to fall through to the second
+ ** probabilistic algorithm
+ **
+ ** The second algorithm is to select a rowid at random and see if
+ ** it already exists in the table. If it does not exist, we have
+ ** succeeded. If the random rowid does exist, we select a new one
+ ** and try again, up to 1000 times.
+ **
+ ** For a table with less than 2 billion entries, the probability
+ ** of not finding a unused rowid is about 1.0e-300. This is a
+ ** non-zero probability, but it is still vanishingly small and should
+ ** never cause a problem. You are much, much more likely to have a
+ ** hardware failure than for this algorithm to fail.
+ **
+ ** The analysis in the previous paragraph assumes that you have a good
+ ** source of random numbers. Is a library function like lrand48()
+ ** good enough? Maybe. Maybe not. It's hard to know whether there
+ ** might be subtle bugs is some implementations of lrand48() that
+ ** could cause problems. To avoid uncertainty, SQLite uses its own
+ ** random number generator based on the RC4 algorithm.
+ **
+ ** To promote locality of reference for repetitive inserts, the
+ ** first few attempts at chosing a random rowid pick values just a little
+ ** larger than the previous rowid. This has been shown experimentally
+ ** to double the speed of the COPY operation.
+ */
+ int res, rx=SQLITE_OK, cnt;
+ i64 x;
+ cnt = 0;
+ if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
+ BTREE_INTKEY ){
+ rc = SQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
+ assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
+ assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );
+
+#ifdef SQLITE_32BIT_ROWID
+# define MAX_ROWID 0x7fffffff
+#else
+ /* Some compilers complain about constants of the form 0x7fffffffffffffff.
+ ** Others complain about 0x7ffffffffffffffffLL. The following macro seems
+ ** to provide the constant while making all compilers happy.
+ */
+# define MAX_ROWID ( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
+#endif
+
+ if( !pC->useRandomRowid ){
+ if( pC->nextRowidValid ){
+ v = pC->nextRowid;
+ }else{
+ rx = sqlite3BtreeLast(pC->pCursor, &res);
+ if( res ){
+ v = 1;
+ }else{
+ sqlite3BtreeKeySize(pC->pCursor, &v);
+ v = keyToInt(v);
+ if( v==MAX_ROWID ){
+ pC->useRandomRowid = 1;
+ }else{
+ v++;
+ }
+ }
+ }
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+ if( pOp->p2 ){
+ Mem *pMem;
+ assert( pOp->p2>0 && pOp->p2<p->nMem ); /* P2 is a valid memory cell */
+ pMem = &p->aMem[pOp->p2];
+ Integerify(pMem);
+ assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P2) holds an integer */
+ if( pMem->i==MAX_ROWID || pC->useRandomRowid ){
+ rc = SQLITE_FULL;
+ goto abort_due_to_error;
+ }
+ if( v<pMem->i+1 ){
+ v = pMem->i + 1;
+ }
+ pMem->i = v;
+ }
+#endif
+
+ if( v<MAX_ROWID ){
+ pC->nextRowidValid = 1;
+ pC->nextRowid = v+1;
+ }else{
+ pC->nextRowidValid = 0;
+ }
+ }
+ if( pC->useRandomRowid ){
+ assert( pOp->p2==0 ); /* SQLITE_FULL must have occurred prior to this */
+ v = db->priorNewRowid;
+ cnt = 0;
+ do{
+ if( v==0 || cnt>2 ){
+ sqlite3Randomness(sizeof(v), &v);
+ if( cnt<5 ) v &= 0xffffff;
+ }else{
+ unsigned char r;
+ sqlite3Randomness(1, &r);
+ v += r + 1;
+ }
+ if( v==0 ) continue;
+ x = intToKey(v);
+ rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, &res);
+ cnt++;
+ }while( cnt<1000 && rx==SQLITE_OK && res==0 );
+ db->priorNewRowid = v;
+ if( rx==SQLITE_OK && res==0 ){
+ rc = SQLITE_FULL;
+ goto abort_due_to_error;
+ }
+ }
+ pC->rowidIsValid = 0;
+ pC->deferredMoveto = 0;
+ pC->cacheValid = 0;
+ }
+ pTos++;
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: Insert P1 P2 *
+**
+** Write an entry into the table of cursor P1. A new entry is
+** created if it doesn't already exist or the data for an existing
+** entry is overwritten. The data is the value on the top of the
+** stack. The key is the next value down on the stack. The key must
+** be an integer. The stack is popped twice by this instruction.
+**
+** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
+** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P2 is set,
+** then rowid is stored for subsequent return by the
+** sqlite3_last_insert_rowid() function (otherwise it's unmodified).
+**
+** This instruction only works on tables. The equivalent instruction
+** for indices is OP_IdxInsert.
+*/
+case OP_Insert: { /* no-push */
+ Mem *pNos = &pTos[-1];
+ int i = pOp->p1;
+ Cursor *pC;
+ assert( pNos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
+ i64 iKey; /* The integer ROWID or key for the record to be inserted */
+
+ assert( pNos->flags & MEM_Int );
+ assert( pC->isTable );
+ iKey = intToKey(pNos->i);
+
+ if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
+ if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
+ if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
+ pC->nextRowidValid = 0;
+ }
+ if( pTos->flags & MEM_Null ){
+ pTos->z = 0;
+ pTos->n = 0;
+ }else{
+ assert( pTos->flags & (MEM_Blob|MEM_Str) );
+ }
+#ifndef SQLITE_OMIT_TRIGGER
+ if( pC->pseudoTable ){
+ sqliteFree(pC->pData);
+ pC->iKey = iKey;
+ pC->nData = pTos->n;
+ if( pTos->flags & MEM_Dyn ){
+ pC->pData = pTos->z;
+ pTos->flags = MEM_Null;
+ }else{
+ pC->pData = sqliteMallocRaw( pC->nData+2 );
+ if( !pC->pData ) goto no_mem;
+ memcpy(pC->pData, pTos->z, pC->nData);
+ pC->pData[pC->nData] = 0;
+ pC->pData[pC->nData+1] = 0;
+ }
+ pC->nullRow = 0;
+ }else{
+#endif
+ rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
+#ifndef SQLITE_OMIT_TRIGGER
+ }
+#endif
+
+ pC->rowidIsValid = 0;
+ pC->deferredMoveto = 0;
+ pC->cacheValid = 0;
+ }
+ popStack(&pTos, 2);
+ break;
+}
+
+/* Opcode: Delete P1 P2 *
+**
+** Delete the record at which the P1 cursor is currently pointing.
+**
+** The cursor will be left pointing at either the next or the previous
+** record in the table. If it is left pointing at the next record, then
+** the next Next instruction will be a no-op. Hence it is OK to delete
+** a record from within an Next loop.
+**
+** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
+** incremented (otherwise not).
+**
+** If P1 is a pseudo-table, then this instruction is a no-op.
+*/
+case OP_Delete: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+ assert( i>=0 && i<p->nCursor );
+ pC = p->apCsr[i];
+ assert( pC!=0 );
+ if( pC->pCursor!=0 ){
+ rc = sqlite3VdbeCursorMoveto(pC);
+ if( rc ) goto abort_due_to_error;
+ rc = sqlite3BtreeDelete(pC->pCursor);
+ pC->nextRowidValid = 0;
+ pC->cacheValid = 0;
+ }
+ if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
+ break;
+}
+
+/* Opcode: ResetCount P1 * *
+**
+** This opcode resets the VMs internal change counter to 0. If P1 is true,
+** then the value of the change counter is copied to the database handle
+** change counter (returned by subsequent calls to sqlite3_changes())
+** before it is reset. This is used by trigger programs.
+*/
+case OP_ResetCount: { /* no-push */
+ if( pOp->p1 ){
+ sqlite3VdbeSetChanges(db, p->nChange);
+ }
+ p->nChange = 0;
+ break;
+}
+
+/* Opcode: RowData P1 * *
+**
+** Push onto the stack the complete row data for cursor P1.
+** There is no interpretation of the data. It is just copied
+** onto the stack exactly as it is found in the database file.
+**
+** If the cursor is not pointing to a valid row, a NULL is pushed
+** onto the stack.
+*/
+/* Opcode: RowKey P1 * *
+**
+** Push onto the stack the complete row key for cursor P1.
+** There is no interpretation of the key. It is just copied
+** onto the stack exactly as it is found in the database file.
+**
+** If the cursor is not pointing to a valid row, a NULL is pushed
+** onto the stack.
+*/
+case OP_RowKey:
+case OP_RowData: {
+ int i = pOp->p1;
+ Cursor *pC;
+ u32 n;
+
+ /* Note that RowKey and RowData are really exactly the same instruction */
+ pTos++;
+ assert( i>=0 && i<p->nCursor );
+ pC = p->apCsr[i];
+ assert( pC->isTable || pOp->opcode==OP_RowKey );
+ assert( pC->isIndex || pOp->opcode==OP_RowData );
+ assert( pC!=0 );
+ if( pC->nullRow ){
+ pTos->flags = MEM_Null;
+ }else if( pC->pCursor!=0 ){
+ BtCursor *pCrsr = pC->pCursor;
+ rc = sqlite3VdbeCursorMoveto(pC);
+ if( rc ) goto abort_due_to_error;
+ if( pC->nullRow ){
+ pTos->flags = MEM_Null;
+ break;
+ }else if( pC->isIndex ){
+ i64 n64;
+ assert( !pC->isTable );
+ sqlite3BtreeKeySize(pCrsr, &n64);
+ n = n64;
+ }else{
+ sqlite3BtreeDataSize(pCrsr, &n);
+ }
+ pTos->n = n;
+ if( n<=NBFS ){
+ pTos->flags = MEM_Blob | MEM_Short;
+ pTos->z = pTos->zShort;
+ }else{
+ char *z = sqliteMallocRaw( n );
+ if( z==0 ) goto no_mem;
+ pTos->flags = MEM_Blob | MEM_Dyn;
+ pTos->xDel = 0;
+ pTos->z = z;
+ }
+ if( pC->isIndex ){
+ sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
+ }else{
+ sqlite3BtreeData(pCrsr, 0, n, pTos->z);
+ }
+#ifndef SQLITE_OMIT_TRIGGER
+ }else if( pC->pseudoTable ){
+ pTos->n = pC->nData;
+ pTos->z = pC->pData;
+ pTos->flags = MEM_Blob|MEM_Ephem;
+#endif
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+/* Opcode: Rowid P1 * *
+**
+** Push onto the stack an integer which is the key of the table entry that
+** P1 is currently point to.
+*/
+case OP_Rowid: {
+ int i = pOp->p1;
+ Cursor *pC;
+ i64 v;
+
+ assert( i>=0 && i<p->nCursor );
+ pC = p->apCsr[i];
+ assert( pC!=0 );
+ rc = sqlite3VdbeCursorMoveto(pC);
+ if( rc ) goto abort_due_to_error;
+ pTos++;
+ if( pC->rowidIsValid ){
+ v = pC->lastRowid;
+ }else if( pC->pseudoTable ){
+ v = keyToInt(pC->iKey);
+ }else if( pC->nullRow || pC->pCursor==0 ){
+ pTos->flags = MEM_Null;
+ break;
+ }else{
+ assert( pC->pCursor!=0 );
+ sqlite3BtreeKeySize(pC->pCursor, &v);
+ v = keyToInt(v);
+ }
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: NullRow P1 * *
+**
+** Move the cursor P1 to a null row. Any OP_Column operations
+** that occur while the cursor is on the null row will always push
+** a NULL onto the stack.
+*/
+case OP_NullRow: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+
+ assert( i>=0 && i<p->nCursor );
+ pC = p->apCsr[i];
+ assert( pC!=0 );
+ pC->nullRow = 1;
+ pC->rowidIsValid = 0;
+ break;
+}
+
+/* Opcode: Last P1 P2 *
+**
+** The next use of the Rowid or Column or Next instruction for P1
+** will refer to the last entry in the database table or index.
+** If the table or index is empty and P2>0, then jump immediately to P2.
+** If P2 is 0 or if the table or index is not empty, fall through
+** to the following instruction.
+*/
+case OP_Last: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+ BtCursor *pCrsr;
+
+ assert( i>=0 && i<p->nCursor );
+ pC = p->apCsr[i];
+ assert( pC!=0 );
+ if( (pCrsr = pC->pCursor)!=0 ){
+ int res;
+ rc = sqlite3BtreeLast(pCrsr, &res);
+ pC->nullRow = res;
+ pC->deferredMoveto = 0;
+ pC->cacheValid = 0;
+ if( res && pOp->p2>0 ){
+ pc = pOp->p2 - 1;
+ }
+ }else{
+ pC->nullRow = 0;
+ }
+ break;
+}
+
+/* Opcode: Rewind P1 P2 *
+**
+** The next use of the Rowid or Column or Next instruction for P1
+** will refer to the first entry in the database table or index.
+** If the table or index is empty and P2>0, then jump immediately to P2.
+** If P2 is 0 or if the table or index is not empty, fall through
+** to the following instruction.
+*/
+case OP_Rewind: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+ BtCursor *pCrsr;
+ int res;
+
+ assert( i>=0 && i<p->nCursor );
+ pC = p->apCsr[i];
+ assert( pC!=0 );
+ if( (pCrsr = pC->pCursor)!=0 ){
+ rc = sqlite3BtreeFirst(pCrsr, &res);
+ pC->atFirst = res==0;
+ pC->deferredMoveto = 0;
+ pC->cacheValid = 0;
+ }else{
+ res = 1;
+ }
+ pC->nullRow = res;
+ if( res && pOp->p2>0 ){
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: Next P1 P2 *
+**
+** Advance cursor P1 so that it points to the next key/data pair in its
+** table or index. If there are no more key/value pairs then fall through
+** to the following instruction. But if the cursor advance was successful,
+** jump immediately to P2.
+**
+** See also: Prev
+*/
+/* Opcode: Prev P1 P2 *
+**
+** Back up cursor P1 so that it points to the previous key/data pair in its
+** table or index. If there is no previous key/value pairs then fall through
+** to the following instruction. But if the cursor backup was successful,
+** jump immediately to P2.
+*/
+case OP_Prev: /* no-push */
+case OP_Next: { /* no-push */
+ Cursor *pC;
+ BtCursor *pCrsr;
+
+ CHECK_FOR_INTERRUPT;
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ if( (pCrsr = pC->pCursor)!=0 ){
+ int res;
+ if( pC->nullRow ){
+ res = 1;
+ }else{
+ assert( pC->deferredMoveto==0 );
+ rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
+ sqlite3BtreePrevious(pCrsr, &res);
+ pC->nullRow = res;
+ pC->cacheValid = 0;
+ }
+ if( res==0 ){
+ pc = pOp->p2 - 1;
+ sqlite3_search_count++;
+ }
+ }else{
+ pC->nullRow = 1;
+ }
+ pC->rowidIsValid = 0;
+ break;
+}
+
+/* Opcode: IdxInsert P1 P2 P3
+**
+** 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.
+*/
+case OP_IdxInsert: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+ BtCursor *pCrsr;
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ assert( pTos->flags & MEM_Blob );
+ 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 );
+ pC->cacheValid = 0;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: IdxDelete P1 * *
+**
+** The top of the stack is an index key built using the MakeIdxKey opcode.
+** This opcode removes that entry from the index.
+*/
+case OP_IdxDelete: { /* no-push */
+ int i = pOp->p1;
+ Cursor *pC;
+ BtCursor *pCrsr;
+ assert( pTos>=p->aStack );
+ assert( pTos->flags & MEM_Blob );
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
+ int rx, res;
+ rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
+ if( rx==SQLITE_OK && res==0 ){
+ rc = sqlite3BtreeDelete(pCrsr);
+ }
+ assert( pC->deferredMoveto==0 );
+ pC->cacheValid = 0;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: IdxRowid P1 * *
+**
+** Push onto the stack an integer which is the last entry in the record at
+** the end of the index key pointed to by cursor P1. This integer should be
+** the rowid of the table entry to which this index entry points.
+**
+** See also: Rowid, MakeIdxKey.
+*/
+case OP_IdxRowid: {
+ int i = pOp->p1;
+ BtCursor *pCrsr;
+ Cursor *pC;
+
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ pTos++;
+ pTos->flags = MEM_Null;
+ if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
+ i64 rowid;
+
+ assert( pC->deferredMoveto==0 );
+ assert( pC->isTable==0 );
+ if( pC->nullRow ){
+ pTos->flags = MEM_Null;
+ }else{
+ rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ pTos->flags = MEM_Int;
+ pTos->i = rowid;
+ }
+ }
+ break;
+}
+
+/* Opcode: IdxGT P1 P2 *
+**
+** The top of the stack is an index entry that omits the ROWID. Compare
+** the top of stack against the index that P1 is currently pointing to.
+** Ignore the ROWID on the P1 index.
+**
+** The top of the stack might have fewer columns that P1.
+**
+** If the P1 index entry is greater than the top of the stack
+** then jump to P2. Otherwise fall through to the next instruction.
+** In either case, the stack is popped once.
+*/
+/* Opcode: IdxGE P1 P2 P3
+**
+** The top of the stack is an index entry that omits the ROWID. Compare
+** the top of stack against the index that P1 is currently pointing to.
+** Ignore the ROWID on the P1 index.
+**
+** If the P1 index entry is greater than or equal to the top of the stack
+** then jump to P2. Otherwise fall through to the next instruction.
+** In either case, the stack is popped once.
+**
+** If P3 is the "+" string (or any other non-NULL string) then the
+** index taken from the top of the stack is temporarily increased by
+** an epsilon prior to the comparison. This make the opcode work
+** like IdxGT except that if the key from the stack is a prefix of
+** the key in the cursor, the result is false whereas it would be
+** true with IdxGT.
+*/
+/* Opcode: IdxLT P1 P2 P3
+**
+** The top of the stack is an index entry that omits the ROWID. Compare
+** the top of stack against the index that P1 is currently pointing to.
+** Ignore the ROWID on the P1 index.
+**
+** If the P1 index entry is less than the top of the stack
+** then jump to P2. Otherwise fall through to the next instruction.
+** In either case, the stack is popped once.
+**
+** If P3 is the "+" string (or any other non-NULL string) then the
+** index taken from the top of the stack is temporarily increased by
+** an epsilon prior to the comparison. This makes the opcode work
+** like IdxLE.
+*/
+case OP_IdxLT: /* no-push */
+case OP_IdxGT: /* no-push */
+case OP_IdxGE: { /* no-push */
+ int i= pOp->p1;
+ BtCursor *pCrsr;
+ Cursor *pC;
+
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
+ assert( pTos>=p->aStack );
+ if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
+ int res, rc;
+
+ assert( pTos->flags & MEM_Blob ); /* Created using OP_Make*Key */
+ Stringify(pTos, db->enc);
+ assert( pC->deferredMoveto==0 );
+ *pC->pIncrKey = pOp->p3!=0;
+ assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT );
+ rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, &res);
+ *pC->pIncrKey = 0;
+ if( rc!=SQLITE_OK ){
+ break;
+ }
+ if( pOp->opcode==OP_IdxLT ){
+ res = -res;
+ }else if( pOp->opcode==OP_IdxGE ){
+ res++;
+ }
+ if( res>0 ){
+ pc = pOp->p2 - 1 ;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: IdxIsNull P1 P2 *
+**
+** The top of the stack contains an index entry such as might be generated
+** by the MakeIdxKey opcode. This routine looks at the first P1 fields of
+** that key. If any of the first P1 fields are NULL, then a jump is made
+** to address P2. Otherwise we fall straight through.
+**
+** The index entry is always popped from the stack.
+*/
+case OP_IdxIsNull: { /* no-push */
+ int i = pOp->p1;
+ int k, n;
+ const char *z;
+ u32 serial_type;
+
+ assert( pTos>=p->aStack );
+ assert( pTos->flags & MEM_Blob );
+ z = pTos->z;
+ n = pTos->n;
+ k = sqlite3GetVarint32(z, &serial_type);
+ for(; k<n && i>0; i--){
+ k += sqlite3GetVarint32(&z[k], &serial_type);
+ if( serial_type==0 ){ /* Serial type 0 is a NULL */
+ pc = pOp->p2-1;
+ break;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: Destroy P1 P2 *
+**
+** Delete an entire database table or index whose root page in the database
+** file is given by P1.
+**
+** The table being destroyed is in the main database file if P2==0. If
+** P2==1 then the table to be clear is in the auxiliary database file
+** that is used to store tables create using CREATE TEMPORARY TABLE.
+**
+** If AUTOVACUUM is enabled then it is possible that another root page
+** might be moved into the newly deleted root page in order to keep all
+** root pages contiguous at the beginning of the database. The former
+** value of the root page that moved - its value before the move occurred -
+** is pushed onto the stack. If no page movement was required (because
+** the table being dropped was already the last one in the database) then
+** a zero is pushed onto the stack. If AUTOVACUUM is disabled
+** then a zero is pushed onto the stack.
+**
+** See also: Clear
+*/
+case OP_Destroy: {
+ int iMoved;
+ if( db->activeVdbeCnt>1 ){
+ rc = SQLITE_LOCKED;
+ }else{
+ assert( db->activeVdbeCnt==1 );
+ rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1, &iMoved);
+ pTos++;
+ pTos->flags = MEM_Int;
+ pTos->i = iMoved;
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+ if( rc==SQLITE_OK && iMoved!=0 ){
+ sqlite3RootPageMoved(&db->aDb[pOp->p2], iMoved, pOp->p1);
+ }
+ #endif
+ }
+ break;
+}
+
+/* Opcode: Clear P1 P2 *
+**
+** Delete all contents of the database table or index whose root page
+** in the database file is given by P1. But, unlike Destroy, do not
+** remove the table or index from the database file.
+**
+** The table being clear is in the main database file if P2==0. If
+** P2==1 then the table to be clear is in the auxiliary database file
+** that is used to store tables create using CREATE TEMPORARY TABLE.
+**
+** See also: Destroy
+*/
+case OP_Clear: { /* no-push */
+ rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
+ break;
+}
+
+/* Opcode: CreateTable P1 * *
+**
+** Allocate a new table in the main database file if P2==0 or in the
+** auxiliary database file if P2==1. Push the page number
+** for the root page of the new table onto the stack.
+**
+** The difference between a table and an index is this: A table must
+** have a 4-byte integer key and can have arbitrary data. An index
+** has an arbitrary key but no data.
+**
+** See also: CreateIndex
+*/
+/* Opcode: CreateIndex P1 * *
+**
+** Allocate a new index in the main database file if P2==0 or in the
+** auxiliary database file if P2==1. Push the page number of the
+** root page of the new index onto the stack.
+**
+** See documentation on OP_CreateTable for additional information.
+*/
+case OP_CreateIndex:
+case OP_CreateTable: {
+ int pgno;
+ int flags;
+ Db *pDb;
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ pDb = &db->aDb[pOp->p1];
+ assert( pDb->pBt!=0 );
+ if( pOp->opcode==OP_CreateTable ){
+ /* flags = BTREE_INTKEY; */
+ flags = BTREE_LEAFDATA|BTREE_INTKEY;
+ }else{
+ flags = BTREE_ZERODATA;
+ }
+ rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
+ pTos++;
+ if( rc==SQLITE_OK ){
+ pTos->i = pgno;
+ pTos->flags = MEM_Int;
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+/* Opcode: ParseSchema P1 * P3
+**
+** Read and parse all entries from the SQLITE_MASTER table of database P1
+** that match the WHERE clause P3.
+**
+** This opcode invokes the parser to create a new virtual machine,
+** then runs the new virtual machine. It is thus a reentrant opcode.
+*/
+case OP_ParseSchema: { /* no-push */
+ char *zSql;
+ int iDb = pOp->p1;
+ const char *zMaster;
+ InitData initData;
+
+ assert( iDb>=0 && iDb<db->nDb );
+ if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
+ zMaster = SCHEMA_TABLE(iDb);
+ initData.db = db;
+ initData.pzErrMsg = &p->zErrMsg;
+ zSql = sqlite3MPrintf(
+ "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
+ pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
+ if( zSql==0 ) goto no_mem;
+ sqlite3SafetyOff(db);
+ assert( db->init.busy==0 );
+ db->init.busy = 1;
+ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+ db->init.busy = 0;
+ sqlite3SafetyOn(db);
+ sqliteFree(zSql);
+ break;
+}
+
+/* Opcode: DropTable P1 * P3
+**
+** Remove the internal (in-memory) data structures that describe
+** the table named P3 in database P1. This is called after a table
+** is dropped in order to keep the internal representation of the
+** schema consistent with what is on disk.
+*/
+case OP_DropTable: { /* no-push */
+ sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p3);
+ break;
+}
+
+/* Opcode: DropIndex P1 * P3
+**
+** Remove the internal (in-memory) data structures that describe
+** the index named P3 in database P1. This is called after an index
+** is dropped in order to keep the internal representation of the
+** schema consistent with what is on disk.
+*/
+case OP_DropIndex: { /* no-push */
+ sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p3);
+ break;
+}
+
+/* Opcode: DropTrigger P1 * P3
+**
+** Remove the internal (in-memory) data structures that describe
+** the trigger named P3 in database P1. This is called after a trigger
+** is dropped in order to keep the internal representation of the
+** schema consistent with what is on disk.
+*/
+case OP_DropTrigger: { /* no-push */
+ sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p3);
+ break;
+}
+
+
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
+/* Opcode: IntegrityCk * P2 *
+**
+** Do an analysis of the currently open database. Push onto the
+** stack the text of an error message describing any problems.
+** If there are no errors, push a "ok" onto the stack.
+**
+** The root page numbers of all tables in the database are integer
+** values on the stack. This opcode pulls as many integers as it
+** can off of the stack and uses those numbers as the root pages.
+**
+** If P2 is not zero, the check is done on the auxiliary database
+** file, not the main database file.
+**
+** This opcode is used for testing purposes only.
+*/
+case OP_IntegrityCk: {
+ int nRoot;
+ int *aRoot;
+ int j;
+ char *z;
+
+ for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){
+ if( (pTos[-nRoot].flags & MEM_Int)==0 ) break;
+ }
+ assert( nRoot>0 );
+ aRoot = sqliteMallocRaw( sizeof(int*)*(nRoot+1) );
+ if( aRoot==0 ) goto no_mem;
+ for(j=0; j<nRoot; j++){
+ Mem *pMem = &pTos[-j];
+ aRoot[j] = pMem->i;
+ }
+ aRoot[j] = 0;
+ popStack(&pTos, nRoot);
+ pTos++;
+ z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
+ if( z==0 || z[0]==0 ){
+ if( z ) sqliteFree(z);
+ pTos->z = "ok";
+ pTos->n = 2;
+ pTos->flags = MEM_Str | MEM_Static | MEM_Term;
+ }else{
+ pTos->z = z;
+ pTos->n = strlen(z);
+ pTos->flags = MEM_Str | MEM_Dyn | MEM_Term;
+ pTos->xDel = 0;
+ }
+ pTos->enc = SQLITE_UTF8;
+ sqlite3VdbeChangeEncoding(pTos, db->enc);
+ sqliteFree(aRoot);
+ break;
+}
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+
+/* Opcode: ListWrite * * *
+**
+** Write the integer on the top of the stack
+** into the temporary storage list.
+*/
+case OP_ListWrite: { /* no-push */
+ Keylist *pKeylist;
+ 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;
+ 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 *
+**
+** Attempt to read an integer from the temporary storage buffer
+** and push it onto the stack. If the storage buffer is empty,
+** push nothing but instead jump to P2.
+*/
+case OP_ListRead: {
+ Keylist *pKeylist;
+ CHECK_FOR_INTERRUPT;
+ pKeylist = p->pList;
+ if( pKeylist!=0 ){
+ assert( pKeylist->nRead>=0 );
+ assert( pKeylist->nRead<pKeylist->nUsed );
+ assert( pKeylist->nRead<pKeylist->nKey );
+ pTos++;
+ pTos->i = pKeylist->aKey[pKeylist->nRead++];
+ 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;
+}
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/* Opcode: AggContextPush * * *
+**
+** Save the state of the current aggregator. It is restored an
+** AggContextPop opcode.
+**
+*/
+case OP_AggContextPush: { /* no-push */
+ p->pAgg++;
+ assert( p->pAgg<&p->apAgg[p->nAgg] );
+ break;
+}
+
+/* Opcode: AggContextPop * * *
+**
+** Restore the aggregator to the state it was in when AggContextPush
+** was last called. Any data in the current aggregator is deleted.
+*/
+case OP_AggContextPop: { /* no-push */
+ p->pAgg--;
+ assert( p->pAgg>=p->apAgg );
+ break;
+}
+#endif
+
+#ifndef SQLITE_OMIT_TRIGGER
+/* Opcode: ContextPush * * *
+**
+** Save the current Vdbe context such that it can be restored by a ContextPop
+** opcode. The context stores the last insert row id, the last statement change
+** count, and the current statement change count.
+*/
+case OP_ContextPush: { /* no-push */
+ int i = p->contextStackTop++;
+ Context *pContext;
+
+ assert( i>=0 );
+ /* FIX ME: This should be allocated as part of the vdbe at compile-time */
+ if( i>=p->contextStackDepth ){
+ p->contextStackDepth = i+1;
+ p->contextStack = sqliteRealloc(p->contextStack, sizeof(Context)*(i+1));
+ if( p->contextStack==0 ) goto no_mem;
+ }
+ pContext = &p->contextStack[i];
+ pContext->lastRowid = db->lastRowid;
+ pContext->nChange = p->nChange;
+ pContext->pList = p->pList;
+ p->pList = 0;
+ break;
+}
+
+/* Opcode: ContextPop * * *
+**
+** Restore the Vdbe context to the state it was in when contextPush was last
+** executed. The context stores the last insert row id, the last statement
+** change count, and the current statement change count.
+*/
+case OP_ContextPop: { /* no-push */
+ Context *pContext = &p->contextStack[--p->contextStackTop];
+ assert( p->contextStackTop>=0 );
+ db->lastRowid = pContext->lastRowid;
+ p->nChange = pContext->nChange;
+ sqlite3VdbeKeylistFree(p->pList);
+ p->pList = pContext->pList;
+ break;
+}
+#endif /* #ifndef SQLITE_OMIT_TRIGGER */
+
+/* Opcode: SortInsert * * *
+**
+** The TOS is the key and the NOS is the data. Pop both from the stack
+** and put them on the sorter. The key and data should have been
+** made using the MakeRecord opcode.
+*/
+case OP_SortInsert: { /* no-push */
+ Mem *pNos = &pTos[-1];
+ Sorter *pSorter;
+ assert( pNos>=p->aStack );
+ if( Dynamicify(pTos, db->enc) ) goto no_mem;
+ pSorter = sqliteMallocRaw( sizeof(Sorter) );
+ if( pSorter==0 ) goto no_mem;
+ pSorter->pNext = 0;
+ if( p->pSortTail ){
+ p->pSortTail->pNext = pSorter;
+ }else{
+ p->pSort = pSorter;
+ }
+ p->pSortTail = pSorter;
+ assert( pTos->flags & MEM_Dyn );
+ pSorter->nKey = pTos->n;
+ pSorter->zKey = pTos->z;
+ pSorter->data.flags = MEM_Null;
+ rc = sqlite3VdbeMemMove(&pSorter->data, pNos);
+ pTos -= 2;
+ break;
+}
+
+/* Opcode: Sort * * P3
+**
+** Sort all elements on the sorter. The algorithm is a
+** mergesort. The P3 argument is a pointer to a KeyInfo structure
+** that describes the keys to be sorted.
+*/
+case OP_Sort: { /* no-push */
+ int i;
+ KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
+ Sorter *pElem;
+ Sorter *apSorter[NSORT];
+ sqlite3_sort_count++;
+ pKeyInfo->enc = p->db->enc;
+ for(i=0; i<NSORT; i++){
+ apSorter[i] = 0;
+ }
+ while( p->pSort ){
+ pElem = p->pSort;
+ p->pSort = pElem->pNext;
+ pElem->pNext = 0;
+ for(i=0; i<NSORT-1; i++){
+ if( apSorter[i]==0 ){
+ apSorter[i] = pElem;
+ break;
+ }else{
+ pElem = Merge(apSorter[i], pElem, pKeyInfo);
+ apSorter[i] = 0;
+ }
+ }
+ if( i>=NSORT-1 ){
+ apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem, pKeyInfo);
+ }
+ }
+ pElem = 0;
+ for(i=0; i<NSORT; i++){
+ pElem = Merge(apSorter[i], pElem, pKeyInfo);
+ }
+ p->pSort = pElem;
+ break;
+}
+
+/* Opcode: SortNext * P2 *
+**
+** Push the data for the topmost element in the sorter onto the
+** stack, then remove the element from the sorter. If the sorter
+** is empty, push nothing on the stack and instead jump immediately
+** to instruction P2.
+*/
+case OP_SortNext: {
+ Sorter *pSorter = p->pSort;
+ CHECK_FOR_INTERRUPT;
+ if( pSorter!=0 ){
+ p->pSort = pSorter->pNext;
+ pTos++;
+ pTos->flags = MEM_Null;
+ rc = sqlite3VdbeMemMove(pTos, &pSorter->data);
+ sqliteFree(pSorter->zKey);
+ sqliteFree(pSorter);
+ }else{
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: SortReset * * *
+**
+** Remove any elements that remain on the sorter.
+*/
+case OP_SortReset: { /* no-push */
+ sqlite3VdbeSorterReset(p);
+ break;
+}
+
+/* Opcode: MemStore P1 P2 *
+**
+** Write the top of the stack into memory location P1.
+** P1 should be a small integer since space is allocated
+** for all memory locations between 0 and P1 inclusive.
+**
+** After the data is stored in the memory location, the
+** stack is popped once if P2 is 1. If P2 is zero, then
+** the original data remains on the stack.
+*/
+case OP_MemStore: { /* no-push */
+ assert( pTos>=p->aStack );
+ assert( pOp->p1>=0 && pOp->p1<p->nMem );
+ rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos);
+ pTos--;
+
+ /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will
+ ** restore the top of the stack to its original value.
+ */
+ if( pOp->p2 ){
+ break;
+ }
+}
+/* Opcode: MemLoad P1 * *
+**
+** Push a copy of the value in memory location P1 onto the stack.
+**
+** If the value is a string, then the value pushed is a pointer to
+** the string that is stored in the memory location. If the memory
+** location is subsequently changed (using OP_MemStore) then the
+** value pushed onto the stack will change too.
+*/
+case OP_MemLoad: {
+ int i = pOp->p1;
+ assert( i>=0 && i<p->nMem );
+ pTos++;
+ sqlite3VdbeMemShallowCopy(pTos, &p->aMem[i], MEM_Ephem);
+ break;
+}
+
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+/* Opcode: MemMax P1 * *
+**
+** Set the value of memory cell P1 to the maximum of its current value
+** and the value on the top of the stack. The stack is unchanged.
+**
+** This instruction throws an error if the memory cell is not initially
+** an integer.
+*/
+case OP_MemMax: { /* no-push */
+ int i = pOp->p1;
+ Mem *pMem;
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nMem );
+ pMem = &p->aMem[i];
+ Integerify(pMem);
+ Integerify(pTos);
+ if( pMem->i<pTos->i){
+ pMem->i = pTos->i;
+ }
+ break;
+}
+#endif /* SQLITE_OMIT_AUTOINCREMENT */
+
+/* Opcode: MemIncr P1 P2 *
+**
+** Increment the integer valued memory cell P1 by 1. If P2 is not zero
+** and the result after the increment is exactly 1, then jump
+** to P2.
+**
+** This instruction throws an error if the memory cell is not initially
+** an integer.
+*/
+case OP_MemIncr: { /* no-push */
+ int i = pOp->p1;
+ Mem *pMem;
+ assert( i>=0 && i<p->nMem );
+ pMem = &p->aMem[i];
+ assert( pMem->flags==MEM_Int );
+ pMem->i++;
+ if( pOp->p2>0 && pMem->i==1 ){
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: IfMemPos P1 P2 *
+**
+** If the value of memory cell P1 is 1 or greater, jump to P2. This
+** opcode assumes that memory cell P1 holds an integer value.
+*/
+case OP_IfMemPos: { /* no-push */
+ int i = pOp->p1;
+ Mem *pMem;
+ assert( i>=0 && i<p->nMem );
+ pMem = &p->aMem[i];
+ assert( pMem->flags==MEM_Int );
+ if( pMem->i>0 ){
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: AggReset P1 P2 P3
+**
+** Reset the current aggregator context so that it no longer contains any
+** data. Future aggregator elements will contain P2 values each and be sorted
+** using the KeyInfo structure pointed to by P3.
+**
+** If P1 is non-zero, then only a single aggregator row is available (i.e.
+** there is no GROUP BY expression). In this case it is illegal to invoke
+** OP_AggFocus.
+*/
+case OP_AggReset: { /* no-push */
+ assert( !pOp->p3 || pOp->p3type==P3_KEYINFO );
+ if( pOp->p1 ){
+ rc = sqlite3VdbeAggReset(0, p->pAgg, (KeyInfo *)pOp->p3);
+ p->pAgg->nMem = pOp->p2; /* Agg.nMem is used by AggInsert() */
+ rc = AggInsert(p->pAgg, 0, 0);
+ }else{
+ rc = sqlite3VdbeAggReset(db, p->pAgg, (KeyInfo *)pOp->p3);
+ p->pAgg->nMem = pOp->p2;
+ }
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ p->pAgg->apFunc = sqliteMalloc( p->pAgg->nMem*sizeof(p->pAgg->apFunc[0]) );
+ if( p->pAgg->apFunc==0 ) goto no_mem;
+ break;
+}
+
+/* Opcode: AggInit P1 P2 P3
+**
+** Initialize the function parameters for an aggregate function.
+** The aggregate will operate out of aggregate column P2.
+** P3 is a pointer to the FuncDef structure for the function.
+**
+** The P1 argument is not used by this opcode. However if the SSE
+** extension is compiled in, P1 is set to the number of arguments that
+** will be passed to the aggregate function, if any. This is used
+** by SSE to select the correct function when (de)serializing statements.
+*/
+case OP_AggInit: { /* no-push */
+ int i = pOp->p2;
+ assert( i>=0 && i<p->pAgg->nMem );
+ p->pAgg->apFunc[i] = (FuncDef*)pOp->p3;
+ break;
+}
+
+/* Opcode: AggFunc * P2 P3
+**
+** Execute the step function for an aggregate. The
+** function has P2 arguments. P3 is a pointer to the FuncDef
+** structure that specifies the function.
+**
+** The top of the stack must be an integer which is the index of
+** the aggregate column that corresponds to this aggregate function.
+** Ideally, this index would be another parameter, but there are
+** no free parameters left. The integer is popped from the stack.
+*/
+case OP_AggFunc: { /* no-push */
+ int n = pOp->p2;
+ int i;
+ Mem *pMem, *pRec;
+ sqlite3_context ctx;
+ sqlite3_value **apVal;
+
+ assert( n>=0 );
+ assert( pTos->flags==MEM_Int );
+ pRec = &pTos[-n];
+ assert( pRec>=p->aStack );
+
+ apVal = p->apArg;
+ assert( apVal || n==0 );
+
+ for(i=0; i<n; i++, pRec++){
+ apVal[i] = pRec;
+ storeTypeInfo(pRec, db->enc);
+ }
+ i = pTos->i;
+ assert( i>=0 && i<p->pAgg->nMem );
+ ctx.pFunc = (FuncDef*)pOp->p3;
+ pMem = &p->pAgg->pCurrent->aMem[i];
+ ctx.s.z = pMem->zShort; /* Space used for small aggregate contexts */
+ ctx.pAgg = pMem->z;
+ ctx.cnt = ++pMem->i;
+ ctx.isError = 0;
+ ctx.pColl = 0;
+ if( ctx.pFunc->needCollSeq ){
+ assert( pOp>p->aOp );
+ assert( pOp[-1].p3type==P3_COLLSEQ );
+ assert( pOp[-1].opcode==OP_CollSeq );
+ ctx.pColl = (CollSeq *)pOp[-1].p3;
+ }
+ (ctx.pFunc->xStep)(&ctx, n, apVal);
+ pMem->z = ctx.pAgg;
+ pMem->flags = MEM_AggCtx;
+ popStack(&pTos, n+1);
+ if( ctx.isError ){
+ rc = SQLITE_ERROR;
+ }
+ break;
+}
+
+/* Opcode: AggFocus * P2 *
+**
+** Pop the top of the stack and use that as an aggregator key. If
+** an aggregator with that same key already exists, then make the
+** aggregator the current aggregator and jump to P2. If no aggregator
+** with the given key exists, create one and make it current but
+** do not jump.
+**
+** The order of aggregator opcodes is important. The order is:
+** AggReset AggFocus AggNext. In other words, you must execute
+** AggReset first, then zero or more AggFocus operations, then
+** zero or more AggNext operations. You must not execute an AggFocus
+** in between an AggNext and an AggReset.
+*/
+case OP_AggFocus: { /* no-push */
+ char *zKey;
+ int nKey;
+ int res;
+ assert( pTos>=p->aStack );
+ Stringify(pTos, db->enc);
+ zKey = pTos->z;
+ nKey = pTos->n;
+ assert( p->pAgg->pBtree );
+ assert( p->pAgg->pCsr );
+ rc = sqlite3BtreeMoveto(p->pAgg->pCsr, zKey, nKey, &res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ if( res==0 ){
+ rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
+ (char *)&p->pAgg->pCurrent);
+ pc = pOp->p2 - 1;
+ }else{
+ rc = AggInsert(p->pAgg, zKey, nKey);
+ }
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: AggSet * P2 *
+**
+** Move the top of the stack into the P2-th field of the current
+** aggregate. String values are duplicated into new memory.
+*/
+case OP_AggSet: { /* no-push */
+ AggElem *pFocus;
+ int i = pOp->p2;
+ pFocus = p->pAgg->pCurrent;
+ assert( pTos>=p->aStack );
+ if( pFocus==0 ) goto no_mem;
+ assert( i>=0 && i<p->pAgg->nMem );
+ rc = sqlite3VdbeMemMove(&pFocus->aMem[i], pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: AggGet P1 P2 *
+**
+** Push a new entry onto the stack which is a copy of the P2-th field
+** of the current aggregate. Strings are not duplicated so
+** string values will be ephemeral.
+**
+** If P1 is zero, then the value is pulled out of the current aggregate
+** in the current aggregate context. If P1 is greater than zero, then
+** the value is taken from the P1th outer aggregate context. (i.e. if
+** P1==1 then read from the aggregate context that will be restored
+** by the next OP_AggContextPop opcode).
+*/
+case OP_AggGet: {
+ AggElem *pFocus;
+ int i = pOp->p2;
+ Agg *pAgg = &p->pAgg[-pOp->p1];
+ assert( pAgg>=p->apAgg );
+ pFocus = pAgg->pCurrent;
+ if( pFocus==0 ){
+ int res;
+ if( sqlite3_malloc_failed ) goto no_mem;
+ rc = sqlite3BtreeFirst(pAgg->pCsr, &res);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ if( res!=0 ){
+ rc = AggInsert(pAgg, "", 1);
+ pFocus = pAgg->pCurrent;
+ }else{
+ rc = sqlite3BtreeData(pAgg->pCsr, 0, 4, (char *)&pFocus);
+ }
+ }
+ assert( i>=0 && i<pAgg->nMem );
+ pTos++;
+ sqlite3VdbeMemShallowCopy(pTos, &pFocus->aMem[i], MEM_Ephem);
+ if( pTos->flags&MEM_Str ){
+ sqlite3VdbeChangeEncoding(pTos, db->enc);
+ }
+ break;
+}
+
+/* Opcode: AggNext * P2 *
+**
+** Make the next aggregate value the current aggregate. The prior
+** aggregate is deleted. If all aggregate values have been consumed,
+** jump to P2.
+**
+** The order of aggregator opcodes is important. The order is:
+** AggReset AggFocus AggNext. In other words, you must execute
+** AggReset first, then zero or more AggFocus operations, then
+** zero or more AggNext operations. You must not execute an AggFocus
+** in between an AggNext and an AggReset.
+*/
+case OP_AggNext: { /* no-push */
+ int res;
+ assert( rc==SQLITE_OK );
+ CHECK_FOR_INTERRUPT;
+ if( p->pAgg->searching==0 ){
+ p->pAgg->searching = 1;
+ if( p->pAgg->pCsr ){
+ rc = sqlite3BtreeFirst(p->pAgg->pCsr, &res);
+ }else{
+ res = 0;
+ }
+ }else{
+ if( p->pAgg->pCsr ){
+ rc = sqlite3BtreeNext(p->pAgg->pCsr, &res);
+ }else{
+ res = 1;
+ }
+ }
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ if( res!=0 ){
+ pc = pOp->p2 - 1;
+ }else{
+ int i;
+ sqlite3_context ctx;
+ Mem *aMem;
+
+ if( p->pAgg->pCsr ){
+ rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
+ (char *)&p->pAgg->pCurrent);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ }
+ aMem = p->pAgg->pCurrent->aMem;
+ for(i=0; i<p->pAgg->nMem; i++){
+ FuncDef *pFunc = p->pAgg->apFunc[i];
+ Mem *pMem = &aMem[i];
+ if( pFunc==0 || pFunc->xFinalize==0 ) continue;
+ ctx.s.flags = MEM_Null;
+ ctx.s.z = pMem->zShort;
+ ctx.pAgg = (void*)pMem->z;
+ ctx.cnt = pMem->i;
+ ctx.pFunc = pFunc;
+ pFunc->xFinalize(&ctx);
+ pMem->z = ctx.pAgg;
+ if( pMem->z && pMem->z!=pMem->zShort ){
+ sqliteFree( pMem->z );
+ }
+ *pMem = ctx.s;
+ if( pMem->flags & MEM_Short ){
+ pMem->z = pMem->zShort;
+ }
+ }
+ }
+ break;
+}
+
+/* Opcode: Vacuum * * *
+**
+** Vacuum the entire database. This opcode will cause other virtual
+** machines to be created and run. It may not be called from within
+** a transaction.
+*/
+case OP_Vacuum: { /* no-push */
+ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
+ rc = sqlite3RunVacuum(&p->zErrMsg, db);
+ if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
+ break;
+}
+
+/* Opcode: Expire P1 * *
+**
+** Cause precompiled statements to become expired. An expired statement
+** fails with an error code of SQLITE_SCHEMA if it is ever executed
+** (via sqlite3_step()).
+**
+** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
+** then only the currently executing statement is affected.
+*/
+case OP_Expire: { /* no-push */
+ if( !pOp->p1 ){
+ sqlite3ExpirePreparedStatements(db);
+ }else{
+ p->expired = 1;
+ }
+ break;
+}
+
+
+/* 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;
+ break;
+}
+
+/*****************************************************************************
+** The cases of the switch statement above this line should all be indented
+** by 6 spaces. But the left-most 6 spaces have been removed to improve the
+** readability. From this point on down, the normal indentation rules are
+** restored.
+*****************************************************************************/
+ }
+
+ /* Make sure the stack limit was not exceeded */
+ assert( pTos<=pStackLimit );
+
+#ifdef VDBE_PROFILE
+ {
+ long long elapse = hwtime() - start;
+ pOp->cycles += elapse;
+ pOp->cnt++;
+#if 0
+ fprintf(stdout, "%10lld ", elapse);
+ sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
+#endif
+ }
+#endif
+
+ /* The following code adds nothing to the actual functionality
+ ** of the program. It is only here for testing and debugging.
+ ** On the other hand, it does burn CPU cycles every time through
+ ** the evaluator loop. So we can leave it out when NDEBUG is defined.
+ */
+#ifndef NDEBUG
+ /* Sanity checking on the top element of the stack */
+ 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;
+ }
+#ifdef SQLITE_DEBUG
+ /* Code for tracing the vdbe stack. */
+ if( p->trace && pTos>=p->aStack ){
+ int i;
+ fprintf(p->trace, "Stack:");
+ for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
+ if( pTos[i].flags & MEM_Null ){
+ fprintf(p->trace, " NULL");
+ }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
+ fprintf(p->trace, " si:%lld", pTos[i].i);
+ }else if( pTos[i].flags & MEM_Int ){
+ fprintf(p->trace, " i:%lld", pTos[i].i);
+ }else if( pTos[i].flags & MEM_Real ){
+ fprintf(p->trace, " r:%g", pTos[i].r);
+ }else{
+ char zBuf[100];
+ sqlite3VdbeMemPrettyPrint(&pTos[i], zBuf, 100);
+ fprintf(p->trace, " ");
+ fprintf(p->trace, "%s", zBuf);
+ }
+ }
+ if( rc!=0 ) fprintf(p->trace," rc=%d",rc);
+ fprintf(p->trace,"\n");
+ }
+#endif /* SQLITE_DEBUG */
+#endif /* NDEBUG */
+ } /* The end of the for(;;) loop the loops through opcodes */
+
+ /* If we reach this point, it means that execution is finished.
+ */
+vdbe_halt:
+ if( rc ){
+ p->rc = rc;
+ rc = SQLITE_ERROR;
+ }else{
+ rc = SQLITE_DONE;
+ }
+ sqlite3VdbeHalt(p);
+ p->pTos = pTos;
+ return rc;
+
+ /* Jump to here if a malloc() fails. It's hard to get a malloc()
+ ** to fail on a modern VM computer, so this code is untested.
+ */
+no_mem:
+ sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
+ rc = SQLITE_NOMEM;
+ goto vdbe_halt;
+
+ /* Jump to here for an SQLITE_MISUSE error.
+ */
+abort_due_to_misuse:
+ rc = SQLITE_MISUSE;
+ /* Fall thru into abort_due_to_error */
+
+ /* Jump to here for any other kind of fatal error. The "rc" variable
+ ** should hold the error number.
+ */
+abort_due_to_error:
+ if( p->zErrMsg==0 ){
+ if( sqlite3_malloc_failed ) rc = SQLITE_NOMEM;
+ sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
+ }
+ goto vdbe_halt;
+
+ /* Jump to here if the sqlite3_interrupt() API sets the interrupt
+ ** flag.
+ */
+abort_due_to_interrupt:
+ assert( db->flags & SQLITE_Interrupt );
+ db->flags &= ~SQLITE_Interrupt;
+ if( db->magic!=SQLITE_MAGIC_BUSY ){
+ rc = SQLITE_MISUSE;
+ }else{
+ rc = SQLITE_INTERRUPT;
+ }
+ p->rc = rc;
+ sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
+ goto vdbe_halt;
+}
diff --git a/src/sqlite/vdbe.h b/src/sqlite/vdbe.h
new file mode 100644
index 0000000..ff27df5
--- /dev/null
+++ b/src/sqlite/vdbe.h
@@ -0,0 +1,132 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Header file for the Virtual DataBase Engine (VDBE)
+**
+** This header defines the interface to the virtual database engine
+** or VDBE. The VDBE implements an abstract machine that runs a
+** simple program to access and modify the underlying database.
+**
+** $Id: vdbe.h,v 1.1.1.1 2006/02/03 20:35:15 hoganrobert Exp $
+*/
+#ifndef _SQLITE_VDBE_H_
+#define _SQLITE_VDBE_H_
+#include <stdio.h>
+
+/*
+** A single VDBE is an opaque structure named "Vdbe". Only routines
+** in the source file sqliteVdbe.c are allowed to see the insides
+** of this structure.
+*/
+typedef struct Vdbe Vdbe;
+
+/*
+** A single instruction of the virtual machine has an opcode
+** and as many as three operands. The instruction is recorded
+** as an instance of the following structure:
+*/
+struct VdbeOp {
+ u8 opcode; /* What operation to perform */
+ int p1; /* First operand */
+ int p2; /* Second parameter (often the jump destination) */
+ char *p3; /* Third parameter */
+ int p3type; /* One of the P3_xxx constants defined below */
+#ifdef VDBE_PROFILE
+ int cnt; /* Number of times this instruction was executed */
+ long long cycles; /* Total time spend executing this instruction */
+#endif
+};
+typedef struct VdbeOp VdbeOp;
+
+/*
+** A smaller version of VdbeOp used for the VdbeAddOpList() function because
+** it takes up less space.
+*/
+struct VdbeOpList {
+ u8 opcode; /* What operation to perform */
+ signed char p1; /* First operand */
+ short int p2; /* Second parameter (often the jump destination) */
+ char *p3; /* Third parameter */
+};
+typedef struct VdbeOpList VdbeOpList;
+
+/*
+** Allowed values of VdbeOp.p3type
+*/
+#define P3_NOTUSED 0 /* The P3 parameter is not used */
+#define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
+#define P3_STATIC (-2) /* Pointer to a static string */
+#define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */
+#define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */
+#define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */
+#define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */
+#define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */
+
+/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
+** is made. That copy is freed when the Vdbe is finalized. But if the
+** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still
+** gets freed when the Vdbe is finalized so it still should be obtained
+** from a single sqliteMalloc(). But no copy is made and the calling
+** function should *not* try to free the KeyInfo.
+*/
+#define P3_KEYINFO_HANDOFF (-9)
+
+/*
+** The following macro converts a relative address in the p2 field
+** of a VdbeOp structure into a negative number so that
+** sqlite3VdbeAddOpList() knows that the address is relative. Calling
+** the macro again restores the address.
+*/
+#define ADDR(X) (-1-(X))
+
+/*
+** The makefile scans the vdbe.c source file and creates the "opcodes.h"
+** header file that defines a number for each opcode used by the VDBE.
+*/
+#include "opcodes.h"
+
+/*
+** Prototypes for the VDBE interface. See comments on the implementation
+** for a description of what each of these routines does.
+*/
+Vdbe *sqlite3VdbeCreate(sqlite3*);
+void sqlite3VdbeCreateCallback(Vdbe*, int*);
+int sqlite3VdbeAddOp(Vdbe*,int,int,int);
+int sqlite3VdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
+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*);
+void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int);
+int sqlite3VdbeFinalize(Vdbe*);
+void sqlite3VdbeResolveLabel(Vdbe*, int);
+int sqlite3VdbeCurrentAddr(Vdbe*);
+void sqlite3VdbeTrace(Vdbe*,FILE*);
+int sqlite3VdbeReset(Vdbe*);
+int sqliteVdbeSetVariables(Vdbe*,int,const char**);
+void sqlite3VdbeSetNumCols(Vdbe*,int);
+int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
+void sqlite3VdbeCountChanges(Vdbe*);
+sqlite3 *sqlite3VdbeDb(Vdbe*);
+
+#ifndef NDEBUG
+ void sqlite3VdbeComment(Vdbe*, const char*, ...);
+# define VdbeComment(X) sqlite3VdbeComment X
+#else
+# define VdbeComment(X)
+#endif
+
+#endif
diff --git a/src/sqlite/vdbeInt.h b/src/sqlite/vdbeInt.h
new file mode 100644
index 0000000..1feb9ba
--- /dev/null
+++ b/src/sqlite/vdbeInt.h
@@ -0,0 +1,413 @@
+/*
+** 2003 September 6
+**
+** 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 is the header file for information that is private to the
+** VDBE. This information used to all be at the top of the single
+** source code file "vdbe.c". When that file became too big (over
+** 6000 lines long) it was split up into several smaller files and
+** this header information was factored out.
+*/
+
+/*
+** intToKey() and keyToInt() used to transform the rowid. But with
+** the latest versions of the design they are no-ops.
+*/
+#define keyToInt(X) (X)
+#define intToKey(X) (X)
+
+/*
+** The makefile scans the vdbe.c source file and creates the following
+** array of string constants which are the names of all VDBE opcodes. This
+** array is defined in a separate source code file named opcode.c which is
+** automatically generated by the makefile.
+*/
+extern char *sqlite3OpcodeNames[];
+
+/*
+** SQL is translated into a sequence of instructions to be
+** executed by a virtual machine. Each instruction is an instance
+** of the following structure.
+*/
+typedef struct VdbeOp Op;
+
+/*
+** Boolean values
+*/
+typedef unsigned char Bool;
+
+/*
+** A cursor is a pointer into a single BTree within a database file.
+** The cursor can seek to a BTree entry with a particular key, or
+** loop over all entries of the Btree. You can also insert new BTree
+** entries or retrieve the key or data from the entry that the cursor
+** is currently pointing to.
+**
+** Every cursor that the virtual machine has open is represented by an
+** instance of the following structure.
+**
+** If the Cursor.isTriggerRow flag is set it means that this cursor is
+** really a single row that represents the NEW or OLD pseudo-table of
+** a row trigger. The data for the row is stored in Cursor.pData and
+** the rowid is in Cursor.iKey.
+*/
+struct Cursor {
+ BtCursor *pCursor; /* The cursor structure of the backend */
+ i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
+ i64 nextRowid; /* Next rowid returned by OP_NewRowid */
+ Bool zeroed; /* True if zeroed out and ready for reuse */
+ Bool rowidIsValid; /* True if lastRowid is valid */
+ Bool atFirst; /* True if pointing to first entry */
+ Bool useRandomRowid; /* Generate new record numbers semi-randomly */
+ Bool nullRow; /* True if pointing to a row with no data */
+ Bool nextRowidValid; /* True if the nextRowid field is valid */
+ Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */
+ Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
+ Bool isTable; /* True if a table requiring integer keys */
+ Bool isIndex; /* True if an index containing keys only - no data */
+ u8 bogusIncrKey; /* Something for pIncrKey to point to if pKeyInfo==0 */
+ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
+ Btree *pBt; /* Separate file holding temporary table */
+ int nData; /* Number of bytes in pData */
+ char *pData; /* Data for a NEW or OLD pseudo-table */
+ i64 iKey; /* Key for the NEW or OLD pseudo-table row */
+ u8 *pIncrKey; /* Pointer to pKeyInfo->incrKey */
+ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
+ int nField; /* Number of fields in the header */
+
+ /* Cached information about the header for the data record that the
+ ** cursor is currently pointing to. Only valid if cacheValid is true.
+ ** zRow might point to (ephemeral) data for the current row, or it might
+ ** be NULL. */
+ Bool cacheValid; /* True if the cache is valid */
+ int payloadSize; /* Total number of bytes in the record */
+ u32 *aType; /* Type values for all entries in the record */
+ u32 *aOffset; /* Cached offsets to the start of each columns data */
+ u8 *aRow; /* Data for the current row, if all on one page */
+};
+typedef struct Cursor Cursor;
+
+/*
+** Number of bytes of string storage space available to each stack
+** layer without having to malloc. NBFS is short for Number of Bytes
+** For Strings.
+*/
+#define NBFS 32
+
+/*
+** Internally, the vdbe manipulates nearly all SQL values as Mem
+** structures. Each Mem struct may cache multiple representations (string,
+** integer etc.) of the same value. A value (and therefore Mem structure)
+** has the following properties:
+**
+** Each value has a manifest type. The manifest type of the value stored
+** in a Mem struct is returned by the MemType(Mem*) macro. The type is
+** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
+** SQLITE_BLOB.
+*/
+struct Mem {
+ i64 i; /* Integer value */
+ int n; /* Number of characters in string value, including '\0' */
+ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
+ u8 type; /* One of MEM_Null, MEM_Str, etc. */
+ u8 enc; /* TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be */
+ double r; /* Real value */
+ char *z; /* String or BLOB value */
+ void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
+ char zShort[NBFS]; /* Space for short strings */
+};
+typedef struct Mem Mem;
+
+/*
+** A sorter builds a list of elements to be sorted. Each element of
+** the list is an instance of the following structure.
+*/
+typedef struct Sorter Sorter;
+struct Sorter {
+ int nKey; /* Number of bytes in the key */
+ char *zKey; /* The key by which we will sort */
+ Mem data;
+ Sorter *pNext; /* Next in the list */
+};
+
+/*
+** Number of buckets used for merge-sort.
+*/
+#define NSORT 30
+
+/* One or more of the following flags are set to indicate the validOK
+** representations of the value stored in the Mem struct.
+**
+** If the MEM_Null flag is set, then the value is an SQL NULL value.
+** No other flags may be set in this case.
+**
+** If the MEM_Str flag is set then Mem.z points at a string representation.
+** Usually this is encoded in the same unicode encoding as the main
+** database (see below for exceptions). If the MEM_Term flag is also
+** set, then the string is nul terminated. The MEM_Int and MEM_Real
+** flags may coexist with the MEM_Str flag.
+**
+** Multiple of these values can appear in Mem.flags. But only one
+** at a time can appear in Mem.type.
+*/
+#define MEM_Null 0x0001 /* Value is NULL */
+#define MEM_Str 0x0002 /* Value is a string */
+#define MEM_Int 0x0004 /* Value is an integer */
+#define MEM_Real 0x0008 /* Value is a real number */
+#define MEM_Blob 0x0010 /* Value is a BLOB */
+
+/* Whenever Mem contains a valid string or blob representation, one of
+** the following flags must be set to determine the memory management
+** policy for Mem.z. The MEM_Term flag tells us whether or not the
+** string is \000 or \u0000 terminated
+*/
+#define MEM_Term 0x0020 /* String rep is nul terminated */
+#define MEM_Dyn 0x0040 /* Need to call sqliteFree() on Mem.z */
+#define MEM_Static 0x0080 /* Mem.z points to a static string */
+#define MEM_Ephem 0x0100 /* Mem.z points to an ephemeral string */
+#define MEM_Short 0x0200 /* Mem.z points to Mem.zShort */
+
+/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
+** It indicates that the corresponding AggElem.aMem.z points to a
+** aggregate function context that needs to be finalized.
+*/
+#define MEM_AggCtx 0x0400 /* Mem.z points to an agg function context */
+
+
+/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
+** additional information about auxiliary information bound to arguments
+** of the function. This is used to implement the sqlite3_get_auxdata()
+** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data
+** that can be associated with a constant argument to a function. This
+** allows functions such as "regexp" to compile their constant regular
+** expression argument once and reused the compiled code for multiple
+** invocations.
+*/
+struct VdbeFunc {
+ FuncDef *pFunc; /* The definition of the function */
+ int nAux; /* Number of entries allocated for apAux[] */
+ struct AuxData {
+ void *pAux; /* Aux data for the i-th argument */
+ void (*xDelete)(void *); /* Destructor for the aux data */
+ } apAux[1]; /* One slot for each function argument */
+};
+typedef struct VdbeFunc VdbeFunc;
+
+/*
+** The "context" argument for a installable function. A pointer to an
+** instance of this structure is the first argument to the routines used
+** implement the SQL functions.
+**
+** There is a typedef for this structure in sqlite.h. So all routines,
+** even the public interface to SQLite, can use a pointer to this structure.
+** But this file is the only place where the internal details of this
+** structure are known.
+**
+** This structure is defined inside of vdbe.c because it uses substructures
+** (Mem) which are only defined there.
+*/
+struct sqlite3_context {
+ FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
+ VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
+ Mem s; /* The return value is stored here */
+ void *pAgg; /* Aggregate context */
+ u8 isError; /* Set to true for an error */
+ int cnt; /* Number of times that the step function has been called */
+ CollSeq *pColl;
+};
+
+/*
+** An Agg structure describes an Aggregator. Each Agg consists of
+** zero or more Aggregator elements (AggElem). Each AggElem contains
+** a key and one or more values. The values are used in processing
+** aggregate functions in a SELECT. The key is used to implement
+** the GROUP BY clause of a select.
+*/
+typedef struct Agg Agg;
+typedef struct AggElem AggElem;
+struct Agg {
+ int nMem; /* Number of values stored in each AggElem */
+ AggElem *pCurrent; /* The AggElem currently in focus */
+ FuncDef **apFunc; /* Information about aggregate functions */
+ Btree *pBtree; /* The tmp. btree used to group elements, if required. */
+ BtCursor *pCsr; /* Read/write cursor to the table in pBtree */
+ int nTab; /* Root page of the table in pBtree */
+ u8 searching; /* True between the first AggNext and AggReset */
+};
+struct AggElem {
+ char *zKey; /* The key to this AggElem */
+ int nKey; /* Number of bytes in the key, including '\0' at end */
+ Mem aMem[1]; /* The values for this AggElem */
+};
+
+/*
+** A Set structure is used for quick testing to see if a value
+** is part of a small set. Sets are used to implement code like
+** this:
+** x.y IN ('hi','hoo','hum')
+*/
+typedef struct Set Set;
+struct Set {
+ Hash hash; /* A set is just a hash table */
+ HashElem *prev; /* Previously accessed hash elemen */
+};
+
+/*
+** 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.
+*/
+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 */
+};
+
+/*
+** A Context stores the last insert rowid, the last statement change count,
+** and the current statement change count (i.e. changes since last statement).
+** The current keylist is also stored in the context.
+** Elements of Context structure type make up the ContextStack, which is
+** updated by the ContextPush and ContextPop opcodes (used by triggers).
+** The context is pushed before executing a trigger a popped when the
+** trigger finishes.
+*/
+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 */
+};
+
+/*
+** An instance of the virtual machine. This structure contains the complete
+** state of the virtual machine.
+**
+** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
+** is really a pointer to an instance of this structure.
+*/
+struct Vdbe {
+ sqlite3 *db; /* The whole database */
+ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
+ FILE *trace; /* Write an execution trace here, if not NULL */
+ int nOp; /* Number of instructions in the program */
+ int nOpAlloc; /* Number of slots allocated for aOp[] */
+ Op *aOp; /* Space to hold the virtual machine's program */
+ int nLabel; /* Number of labels used */
+ int nLabelAlloc; /* Number of slots allocated in aLabel[] */
+ int *aLabel; /* Space to hold the labels */
+ Mem *aStack; /* The operand stack, except string values */
+ Mem *pTos; /* Top entry in the operand stack */
+ Mem **apArg; /* Arguments to currently executing user function */
+ Mem *aColName; /* Column names to return */
+ int nCursor; /* Number of slots in apCsr[] */
+ Cursor **apCsr; /* One element of this array for each open cursor */
+ Sorter *pSort; /* A linked list of objects to be sorted */
+ Sorter *pSortTail; /* Last element on the pSort list */
+ int nVar; /* Number of entries in aVar[] */
+ Mem *aVar; /* Values for the OP_Variable opcode. */
+ char **azVar; /* Name of variables */
+ int okVar; /* True if azVar[] has been initialized */
+ int magic; /* Magic number for sanity checking */
+ int nMem; /* Number of memory locations currently allocated */
+ Mem *aMem; /* The memory locations */
+ int nAgg; /* Number of elements in apAgg */
+ 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 */
+ 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*/
+ int pc; /* The program counter */
+ int rc; /* Value to return */
+ unsigned uniqueCnt; /* Used by OP_MakeRecord when P2!=0 */
+ int errorAction; /* Recovery action to do in case of an error */
+ int inTempTrans; /* True if temp database is transactioned */
+ int returnStack[100]; /* Return address stack for OP_Gosub & OP_Return */
+ int returnDepth; /* Next unused element in returnStack[] */
+ int nResColumn; /* Number of columns in one row of the result set */
+ char **azResColumn; /* Values for one row of result */
+ int popStack; /* Pop the stack this much on entry to VdbeExec() */
+ char *zErrMsg; /* Error message written here */
+ u8 resOnStack; /* True if there are result values on the stack */
+ u8 explain; /* True if EXPLAIN present on SQL command */
+ u8 changeCntOn; /* True to update the change-counter */
+ u8 aborted; /* True if ROLLBACK in another VM causes an abort */
+ u8 expired; /* True if the VM needs to be recompiled */
+ int nChange; /* Number of db changes made since last reset */
+};
+
+/*
+** The following are allowed values for Vdbe.magic
+*/
+#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
+#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
+#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
+#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
+
+/*
+** Function prototypes
+*/
+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)
+void sqlite3VdbePrintOp(FILE*, int, Op*);
+#endif
+#ifdef SQLITE_DEBUG
+void sqlite3VdbePrintSql(Vdbe*);
+#endif
+int sqlite3VdbeSerialTypeLen(u32);
+u32 sqlite3VdbeSerialType(Mem*);
+int sqlite3VdbeSerialPut(unsigned char*, Mem*);
+int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
+void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
+
+int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
+int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
+int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
+int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
+int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*);
+int sqlite3VdbeIdxRowidLen(int,const u8*);
+int sqlite3VdbeExec(Vdbe*);
+int sqlite3VdbeList(Vdbe*);
+int sqlite3VdbeHalt(Vdbe*);
+int sqlite3VdbeChangeEncoding(Mem *, int);
+int sqlite3VdbeMemCopy(Mem*, const Mem*);
+void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
+int sqlite3VdbeMemMove(Mem*, Mem*);
+int sqlite3VdbeMemNulTerminate(Mem*);
+int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
+void sqlite3VdbeMemSetInt64(Mem*, i64);
+void sqlite3VdbeMemSetDouble(Mem*, double);
+void sqlite3VdbeMemSetNull(Mem*);
+int sqlite3VdbeMemMakeWriteable(Mem*);
+int sqlite3VdbeMemDynamicify(Mem*);
+int sqlite3VdbeMemStringify(Mem*, int);
+i64 sqlite3VdbeIntValue(Mem*);
+int sqlite3VdbeMemIntegerify(Mem*);
+double sqlite3VdbeRealValue(Mem*);
+int sqlite3VdbeMemRealify(Mem*);
+int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
+void sqlite3VdbeMemRelease(Mem *p);
+#ifndef NDEBUG
+void sqlite3VdbeMemSanity(Mem*, u8);
+int sqlite3VdbeOpcodeNoPush(u8);
+#endif
+int sqlite3VdbeMemTranslate(Mem*, u8);
+void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
+int sqlite3VdbeMemHandleBom(Mem *pMem);
diff --git a/src/sqlite/vdbeapi.c b/src/sqlite/vdbeapi.c
new file mode 100644
index 0000000..f07bc88
--- /dev/null
+++ b/src/sqlite/vdbeapi.c
@@ -0,0 +1,701 @@
+/*
+** 2004 May 26
+**
+** 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 use to implement APIs that are part of the
+** VDBE.
+*/
+#include "sqliteInt.h"
+#include "vdbeInt.h"
+
+/*
+** Return TRUE (non-zero) of the statement supplied as an argument needs
+** to be recompiled. A statement needs to be recompiled whenever the
+** execution environment changes in a way that would alter the program
+** that sqlite3_prepare() generates. For example, if new functions or
+** collating sequences are registered or if an authorizer function is
+** added or changed.
+*/
+int sqlite3_expired(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe*)pStmt;
+ return p==0 || p->expired;
+}
+
+/**************************** sqlite3_value_ *******************************
+** The following routines extract information from a Mem or sqlite3_value
+** structure.
+*/
+const void *sqlite3_value_blob(sqlite3_value *pVal){
+ Mem *p = (Mem*)pVal;
+ if( p->flags & (MEM_Blob|MEM_Str) ){
+ return p->z;
+ }else{
+ return sqlite3_value_text(pVal);
+ }
+}
+int sqlite3_value_bytes(sqlite3_value *pVal){
+ return sqlite3ValueBytes(pVal, SQLITE_UTF8);
+}
+int sqlite3_value_bytes16(sqlite3_value *pVal){
+ return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
+}
+double sqlite3_value_double(sqlite3_value *pVal){
+ return sqlite3VdbeRealValue((Mem*)pVal);
+}
+int sqlite3_value_int(sqlite3_value *pVal){
+ return sqlite3VdbeIntValue((Mem*)pVal);
+}
+sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
+ return sqlite3VdbeIntValue((Mem*)pVal);
+}
+const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
+ return (const char *)sqlite3ValueText(pVal, SQLITE_UTF8);
+}
+#ifndef SQLITE_OMIT_UTF16
+const void *sqlite3_value_text16(sqlite3_value* pVal){
+ return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
+}
+const void *sqlite3_value_text16be(sqlite3_value *pVal){
+ return sqlite3ValueText(pVal, SQLITE_UTF16BE);
+}
+const void *sqlite3_value_text16le(sqlite3_value *pVal){
+ return sqlite3ValueText(pVal, SQLITE_UTF16LE);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+int sqlite3_value_type(sqlite3_value* pVal){
+ return pVal->type;
+}
+
+/**************************** sqlite3_result_ *******************************
+** The following routines are used by user-defined functions to specify
+** the function result.
+*/
+void sqlite3_result_blob(
+ sqlite3_context *pCtx,
+ const void *z,
+ int n,
+ void (*xDel)(void *)
+){
+ assert( n>0 );
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
+}
+void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+ sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
+}
+void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+ pCtx->isError = 1;
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
+}
+void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+ pCtx->isError = 1;
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
+}
+void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+ sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
+}
+void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+ sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
+}
+void sqlite3_result_null(sqlite3_context *pCtx){
+ sqlite3VdbeMemSetNull(&pCtx->s);
+}
+void sqlite3_result_text(
+ sqlite3_context *pCtx,
+ const char *z,
+ int n,
+ void (*xDel)(void *)
+){
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);
+}
+#ifndef SQLITE_OMIT_UTF16
+void sqlite3_result_text16(
+ sqlite3_context *pCtx,
+ const void *z,
+ int n,
+ void (*xDel)(void *)
+){
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
+}
+void sqlite3_result_text16be(
+ sqlite3_context *pCtx,
+ const void *z,
+ int n,
+ void (*xDel)(void *)
+){
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);
+}
+void sqlite3_result_text16le(
+ sqlite3_context *pCtx,
+ const void *z,
+ int n,
+ void (*xDel)(void *)
+){
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+ sqlite3VdbeMemCopy(&pCtx->s, pValue);
+}
+
+
+/*
+** Execute the statement pStmt, either until a row of data is ready, the
+** statement is completely executed or an error occurs.
+*/
+int sqlite3_step(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe*)pStmt;
+ sqlite3 *db;
+ int rc;
+
+ if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
+ return SQLITE_MISUSE;
+ }
+ if( p->aborted ){
+ return SQLITE_ABORT;
+ }
+ if( p->pc<=0 && p->expired ){
+ if( p->rc==SQLITE_OK ){
+ p->rc = SQLITE_SCHEMA;
+ }
+ return SQLITE_ERROR;
+ }
+ db = p->db;
+ if( sqlite3SafetyOn(db) ){
+ p->rc = SQLITE_MISUSE;
+ return SQLITE_MISUSE;
+ }
+ if( p->pc<0 ){
+ /* Invoke the trace callback if there is one
+ */
+ if( (db = p->db)->xTrace && !db->init.busy ){
+ assert( p->nOp>0 );
+ assert( p->aOp[p->nOp-1].opcode==OP_Noop );
+ assert( p->aOp[p->nOp-1].p3!=0 );
+ assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
+ sqlite3SafetyOff(db);
+ db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3);
+ if( sqlite3SafetyOn(db) ){
+ p->rc = SQLITE_MISUSE;
+ return SQLITE_MISUSE;
+ }
+ }
+
+ /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned
+ ** on in debugging mode.
+ */
+#ifdef SQLITE_DEBUG
+ if( (db->flags & SQLITE_SqlTrace)!=0 ){
+ sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3);
+ }
+#endif /* SQLITE_DEBUG */
+
+ db->activeVdbeCnt++;
+ p->pc = 0;
+ }
+#ifndef SQLITE_OMIT_EXPLAIN
+ if( p->explain ){
+ rc = sqlite3VdbeList(p);
+ }else
+#endif /* SQLITE_OMIT_EXPLAIN */
+ {
+ rc = sqlite3VdbeExec(p);
+ }
+
+ if( sqlite3SafetyOff(db) ){
+ rc = SQLITE_MISUSE;
+ }
+
+ sqlite3Error(p->db, rc, p->zErrMsg);
+ return rc;
+}
+
+/*
+** Extract the user data from a sqlite3_context structure and return a
+** pointer to it.
+*/
+void *sqlite3_user_data(sqlite3_context *p){
+ assert( p && p->pFunc );
+ return p->pFunc->pUserData;
+}
+
+/*
+** 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 );
+ if( p->pAgg==0 ){
+ if( nByte<=NBFS ){
+ p->pAgg = (void*)p->s.z;
+ memset(p->pAgg, 0, nByte);
+ }else{
+ p->pAgg = sqliteMalloc( nByte );
+ }
+ }
+ return p->pAgg;
+}
+
+/*
+** Return the auxilary data pointer, if any, for the iArg'th argument to
+** the user-function defined by pCtx.
+*/
+void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+ VdbeFunc *pVdbeFunc = pCtx->pVdbeFunc;
+ if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
+ return 0;
+ }
+ return pVdbeFunc->apAux[iArg].pAux;
+}
+
+/*
+** Set the auxilary data pointer and delete function, for the iArg'th
+** argument to the user-function defined by pCtx. Any previous value is
+** deleted by calling the delete function specified when it was set.
+*/
+void sqlite3_set_auxdata(
+ sqlite3_context *pCtx,
+ int iArg,
+ void *pAux,
+ void (*xDelete)(void*)
+){
+ struct AuxData *pAuxData;
+ VdbeFunc *pVdbeFunc;
+ if( iArg<0 ) return;
+
+ pVdbeFunc = pCtx->pVdbeFunc;
+ if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
+ int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
+ pCtx->pVdbeFunc = pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc);
+ if( !pVdbeFunc ) return;
+ memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0,
+ sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux));
+ pVdbeFunc->nAux = iArg+1;
+ pVdbeFunc->pFunc = pCtx->pFunc;
+ }
+
+ pAuxData = &pVdbeFunc->apAux[iArg];
+ if( pAuxData->pAux && pAuxData->xDelete ){
+ pAuxData->xDelete(pAuxData->pAux);
+ }
+ pAuxData->pAux = pAux;
+ pAuxData->xDelete = xDelete;
+}
+
+/*
+** Return the number of times the Step function of a aggregate has been
+** called.
+**
+** 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.
+*/
+int sqlite3_aggregate_count(sqlite3_context *p){
+ assert( p && p->pFunc && p->pFunc->xStep );
+ return p->cnt;
+}
+
+/*
+** Return the number of columns in the result set for the statement pStmt.
+*/
+int sqlite3_column_count(sqlite3_stmt *pStmt){
+ Vdbe *pVm = (Vdbe *)pStmt;
+ return pVm ? pVm->nResColumn : 0;
+}
+
+/*
+** Return the number of values available from the current row of the
+** currently executing statement pStmt.
+*/
+int sqlite3_data_count(sqlite3_stmt *pStmt){
+ Vdbe *pVm = (Vdbe *)pStmt;
+ if( pVm==0 || !pVm->resOnStack ) return 0;
+ return pVm->nResColumn;
+}
+
+
+/*
+** Check to see if column iCol of the given statement is valid. If
+** it is, return a pointer to the Mem for the value of that column.
+** If iCol is not valid, return a pointer to a Mem which has a value
+** of NULL.
+*/
+static Mem *columnMem(sqlite3_stmt *pStmt, int i){
+ Vdbe *pVm = (Vdbe *)pStmt;
+ int vals = sqlite3_data_count(pStmt);
+ if( i>=vals || i<0 ){
+ static Mem nullMem;
+ if( nullMem.flags==0 ){ nullMem.flags = MEM_Null; }
+ sqlite3Error(pVm->db, SQLITE_RANGE, 0);
+ return &nullMem;
+ }
+ return &pVm->pTos[(1-vals)+i];
+}
+
+/**************************** sqlite3_column_ *******************************
+** The following routines are used to access elements of the current row
+** in the result set.
+*/
+const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_blob( columnMem(pStmt,i) );
+}
+int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_bytes( columnMem(pStmt,i) );
+}
+int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_bytes16( columnMem(pStmt,i) );
+}
+double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_double( columnMem(pStmt,i) );
+}
+int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_int( columnMem(pStmt,i) );
+}
+sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_int64( columnMem(pStmt,i) );
+}
+const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_text( columnMem(pStmt,i) );
+}
+#ifndef SQLITE_OMIT_UTF16
+const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_text16( columnMem(pStmt,i) );
+}
+#endif /* SQLITE_OMIT_UTF16 */
+int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_type( columnMem(pStmt,i) );
+}
+
+/*
+** Convert the N-th element of pStmt->pColName[] into a string using
+** xFunc() then return that string. If N is out of range, return 0.
+**
+** There are up to 5 names for each column. useType determines which
+** name is returned. Here are the names:
+**
+** 0 The column name as it should be displayed for output
+** 1 The datatype name for the column
+** 2 The name of the database that the column derives from
+** 3 The name of the table that the column derives from
+** 4 The name of the table column that the result column derives from
+**
+** If the result is not a simple column reference (if it is an expression
+** or a constant) then useTypes 2, 3, and 4 return NULL.
+*/
+static const void *columnName(
+ sqlite3_stmt *pStmt,
+ int N,
+ const void *(*xFunc)(Mem*),
+ int useType
+){
+ Vdbe *p = (Vdbe *)pStmt;
+ int n = sqlite3_column_count(pStmt);
+
+ if( p==0 || N>=n || N<0 ){
+ return 0;
+ }
+ N += useType*n;
+ return xFunc(&p->aColName[N]);
+}
+
+
+/*
+** Return the name of the Nth column of the result set returned by SQL
+** statement pStmt.
+*/
+const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0);
+}
+#ifndef SQLITE_OMIT_UTF16
+const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0);
+}
+#endif
+
+/*
+** Return the column declaration type (if applicable) of the 'i'th column
+** of the result set of SQL statement pStmt.
+*/
+const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1);
+}
+#ifndef SQLITE_OMIT_UTF16
+const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+#if !defined(SQLITE_OMIT_ORIGIN_NAMES) && 0
+/*
+** Return the name of the database from which a result column derives.
+** NULL is returned if the result column is an expression or constant or
+** anything else which is not an unabiguous reference to a database column.
+*/
+const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 2);
+}
+#ifndef SQLITE_OMIT_UTF16
+const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 2);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+/*
+** Return the name of the table from which a result column derives.
+** NULL is returned if the result column is an expression or constant or
+** anything else which is not an unabiguous reference to a database column.
+*/
+const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 3);
+}
+#ifndef SQLITE_OMIT_UTF16
+const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 3);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+/*
+** Return the name of the table column from which a result column derives.
+** NULL is returned if the result column is an expression or constant or
+** anything else which is not an unabiguous reference to a database column.
+*/
+const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 4);
+}
+#ifndef SQLITE_OMIT_UTF16
+const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
+ return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 4);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+#endif /* SQLITE_OMIT_ORIGIN_NAMES */
+
+
+
+
+/******************************* sqlite3_bind_ ***************************
+**
+** Routines used to attach values to wildcards in a compiled SQL statement.
+*/
+/*
+** Unbind the value bound to variable i in virtual machine p. This is the
+** the same as binding a NULL value to the column. If the "i" parameter is
+** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
+**
+** The error code stored in database p->db is overwritten with the return
+** value in any case.
+*/
+static int vdbeUnbind(Vdbe *p, int i){
+ Mem *pVar;
+ if( p==0 || p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
+ if( p ) sqlite3Error(p->db, SQLITE_MISUSE, 0);
+ return SQLITE_MISUSE;
+ }
+ if( i<1 || i>p->nVar ){
+ sqlite3Error(p->db, SQLITE_RANGE, 0);
+ return SQLITE_RANGE;
+ }
+ i--;
+ pVar = &p->aVar[i];
+ sqlite3VdbeMemRelease(pVar);
+ pVar->flags = MEM_Null;
+ sqlite3Error(p->db, SQLITE_OK, 0);
+ return SQLITE_OK;
+}
+
+/*
+** Bind a text or BLOB value.
+*/
+static int bindText(
+ sqlite3_stmt *pStmt,
+ int i,
+ const void *zData,
+ int nData,
+ void (*xDel)(void*),
+ int encoding
+){
+ Vdbe *p = (Vdbe *)pStmt;
+ Mem *pVar;
+ int rc;
+
+ rc = vdbeUnbind(p, i);
+ if( rc || zData==0 ){
+ return rc;
+ }
+ pVar = &p->aVar[i-1];
+ rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
+ if( rc ){
+ return rc;
+ }
+ if( rc==SQLITE_OK && encoding!=0 ){
+ rc = sqlite3VdbeChangeEncoding(pVar, p->db->enc);
+ }
+ return rc;
+}
+
+
+/*
+** Bind a blob value to an SQL statement variable.
+*/
+int sqlite3_bind_blob(
+ sqlite3_stmt *pStmt,
+ int i,
+ const void *zData,
+ int nData,
+ void (*xDel)(void*)
+){
+ return bindText(pStmt, i, zData, nData, xDel, 0);
+}
+int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+ int rc;
+ Vdbe *p = (Vdbe *)pStmt;
+ rc = vdbeUnbind(p, i);
+ if( rc==SQLITE_OK ){
+ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
+ }
+ return rc;
+}
+int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+ return sqlite3_bind_int64(p, i, (i64)iValue);
+}
+int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
+ int rc;
+ Vdbe *p = (Vdbe *)pStmt;
+ rc = vdbeUnbind(p, i);
+ if( rc==SQLITE_OK ){
+ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
+ }
+ return rc;
+}
+int sqlite3_bind_null(sqlite3_stmt* p, int i){
+ return vdbeUnbind((Vdbe *)p, i);
+}
+int sqlite3_bind_text(
+ sqlite3_stmt *pStmt,
+ int i,
+ const char *zData,
+ int nData,
+ void (*xDel)(void*)
+){
+ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
+}
+#ifndef SQLITE_OMIT_UTF16
+int sqlite3_bind_text16(
+ sqlite3_stmt *pStmt,
+ int i,
+ const void *zData,
+ int nData,
+ void (*xDel)(void*)
+){
+ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+
+/*
+** Return the number of wildcards that can be potentially bound to.
+** This routine is added to support DBD::SQLite.
+*/
+int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe*)pStmt;
+ return p ? p->nVar : 0;
+}
+
+/*
+** Create a mapping from variable numbers to variable names
+** in the Vdbe.azVar[] array, if such a mapping does not already
+** exist.
+*/
+static void createVarMap(Vdbe *p){
+ if( !p->okVar ){
+ int j;
+ Op *pOp;
+ for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
+ if( pOp->opcode==OP_Variable ){
+ assert( pOp->p1>0 && pOp->p1<=p->nVar );
+ p->azVar[pOp->p1-1] = pOp->p3;
+ }
+ }
+ p->okVar = 1;
+ }
+}
+
+/*
+** Return the name of a wildcard parameter. Return NULL if the index
+** is out of range or if the wildcard is unnamed.
+**
+** The result is always UTF-8.
+*/
+const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
+ Vdbe *p = (Vdbe*)pStmt;
+ if( p==0 || i<1 || i>p->nVar ){
+ return 0;
+ }
+ createVarMap(p);
+ return p->azVar[i-1];
+}
+
+/*
+** Given a wildcard parameter name, return the index of the variable
+** with that name. If there is no variable with the given name,
+** return 0.
+*/
+int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
+ Vdbe *p = (Vdbe*)pStmt;
+ int i;
+ if( p==0 ){
+ return 0;
+ }
+ createVarMap(p);
+ if( zName ){
+ for(i=0; i<p->nVar; i++){
+ const char *z = p->azVar[i];
+ if( z && strcmp(z,zName)==0 ){
+ return i+1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Transfer all bindings from the first statement over to the second.
+** If the two statements contain a different number of bindings, then
+** an SQLITE_ERROR is returned.
+*/
+int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
+ Vdbe *pFrom = (Vdbe*)pFromStmt;
+ Vdbe *pTo = (Vdbe*)pToStmt;
+ int i, rc = SQLITE_OK;
+ if( (pFrom->magic!=VDBE_MAGIC_RUN && pFrom->magic!=VDBE_MAGIC_HALT)
+ || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){
+ return SQLITE_MISUSE;
+ }
+ if( pFrom->nVar!=pTo->nVar ){
+ return SQLITE_ERROR;
+ }
+ for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
+ rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
+ }
+ return rc;
+}
+
+/*
+** Return the sqlite3* database handle to which the prepared statement given
+** in the argument belongs. This is the same database handle that was
+** the first argument to the sqlite3_prepare() that was used to create
+** the statement in the first place.
+*/
+sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
+ return pStmt ? ((Vdbe*)pStmt)->db : 0;
+}
diff --git a/src/sqlite/vdbeaux.c b/src/sqlite/vdbeaux.c
new file mode 100644
index 0000000..e64831e
--- /dev/null
+++ b/src/sqlite/vdbeaux.c
@@ -0,0 +1,1997 @@
+/*
+** 2003 September 6
+**
+** 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 used for creating, destroying, and populating
+** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
+** to version 2.8.7, all this code was combined into the vdbe.c source file.
+** But that file was getting too big so this subroutines were split out.
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include "vdbeInt.h"
+
+
+/*
+** When debugging the code generator in a symbolic debugger, one can
+** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed
+** as they are added to the instruction stream.
+*/
+#ifndef NDEBUG
+int sqlite3_vdbe_addop_trace = 0;
+#endif
+
+
+/*
+** Create a new virtual database engine.
+*/
+Vdbe *sqlite3VdbeCreate(sqlite3 *db){
+ Vdbe *p;
+ p = sqliteMalloc( sizeof(Vdbe) );
+ if( p==0 ) return 0;
+ p->db = db;
+ if( db->pVdbe ){
+ db->pVdbe->pPrev = p;
+ }
+ p->pNext = db->pVdbe;
+ p->pPrev = 0;
+ db->pVdbe = p;
+ p->magic = VDBE_MAGIC_INIT;
+ return p;
+}
+
+/*
+** Turn tracing on or off
+*/
+void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
+ p->trace = trace;
+}
+
+/*
+** Resize the Vdbe.aOp array so that it contains at least N
+** elements. If the Vdbe is in VDBE_MAGIC_RUN state, then
+** the Vdbe.aOp array will be sized to contain exactly N
+** elements.
+*/
+static void resizeOpArray(Vdbe *p, int N){
+ if( p->magic==VDBE_MAGIC_RUN ){
+ assert( N==p->nOp );
+ p->nOpAlloc = N;
+ p->aOp = sqliteRealloc(p->aOp, N*sizeof(Op));
+ }else if( p->nOpAlloc<N ){
+ int oldSize = p->nOpAlloc;
+ p->nOpAlloc = N+100;
+ p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
+ if( p->aOp ){
+ memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+ }
+ }
+}
+
+/*
+** Add a new instruction to the list of instructions current in the
+** VDBE. Return the address of the new instruction.
+**
+** Parameters:
+**
+** p Pointer to the VDBE
+**
+** op The opcode for this instruction
+**
+** p1, p2 First two of the three possible operands.
+**
+** Use the sqlite3VdbeResolveLabel() function to fix an address and
+** the sqlite3VdbeChangeP3() function to change the value of the P3
+** operand.
+*/
+int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
+ int i;
+ VdbeOp *pOp;
+
+ i = p->nOp;
+ p->nOp++;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ resizeOpArray(p, i+1);
+ if( p->aOp==0 ){
+ return 0;
+ }
+ pOp = &p->aOp[i];
+ pOp->opcode = op;
+ pOp->p1 = p1;
+ pOp->p2 = p2;
+ pOp->p3 = 0;
+ pOp->p3type = P3_NOTUSED;
+#ifdef SQLITE_DEBUG
+ if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
+#endif
+ return i;
+}
+
+/*
+** Add an opcode that includes the p3 value.
+*/
+int sqlite3VdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3,int p3type){
+ int addr = sqlite3VdbeAddOp(p, op, p1, p2);
+ sqlite3VdbeChangeP3(p, addr, zP3, p3type);
+ return addr;
+}
+
+/*
+** Create a new symbolic label for an instruction that has yet to be
+** coded. The symbolic label is really just a negative number. The
+** label can be used as the P2 value of an operation. Later, when
+** the label is resolved to a specific address, the VDBE will scan
+** through its operation list and change all values of P2 which match
+** the label into the resolved address.
+**
+** The VDBE knows that a P2 value is a label because labels are
+** always negative and P2 values are suppose to be non-negative.
+** Hence, a negative P2 value is a label that has yet to be resolved.
+**
+** Zero is returned if a malloc() fails.
+*/
+int sqlite3VdbeMakeLabel(Vdbe *p){
+ int i;
+ i = p->nLabel++;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( i>=p->nLabelAlloc ){
+ p->nLabelAlloc = p->nLabelAlloc*2 + 10;
+ p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
+ }
+ if( p->aLabel ){
+ p->aLabel[i] = -1;
+ }
+ return -1-i;
+}
+
+/*
+** Resolve label "x" to be the address of the next instruction to
+** be inserted. The parameter "x" must have been obtained from
+** a prior call to sqlite3VdbeMakeLabel().
+*/
+void sqlite3VdbeResolveLabel(Vdbe *p, int x){
+ int j = -1-x;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ assert( j>=0 && j<p->nLabel );
+ if( p->aLabel ){
+ p->aLabel[j] = p->nOp;
+ }
+}
+
+/*
+** Return non-zero if opcode 'op' is guarenteed not to push more values
+** onto the VDBE stack than it pops off.
+*/
+static int opcodeNoPush(u8 op){
+ /* The 10 NOPUSH_MASK_n constants are defined in the automatically
+ ** generated header file opcodes.h. Each is a 16-bit bitmask, one
+ ** bit corresponding to each opcode implemented by the virtual
+ ** machine in vdbe.c. The bit is true if the word "no-push" appears
+ ** in a comment on the same line as the "case OP_XXX:" in
+ ** sqlite3VdbeExec() in vdbe.c.
+ **
+ ** If the bit is true, then the corresponding opcode is guarenteed not
+ ** to grow the stack when it is executed. Otherwise, it may grow the
+ ** stack by at most one entry.
+ **
+ ** NOPUSH_MASK_0 corresponds to opcodes 0 to 15. NOPUSH_MASK_1 contains
+ ** one bit for opcodes 16 to 31, and so on.
+ **
+ ** 16-bit bitmasks (rather than 32-bit) are specified in opcodes.h
+ ** because the file is generated by an awk program. Awk manipulates
+ ** all numbers as floating-point and we don't want to risk a rounding
+ ** error if someone builds with an awk that uses (for example) 32-bit
+ ** IEEE floats.
+ */
+ static const u32 masks[5] = {
+ NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16),
+ NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16),
+ NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16),
+ NOPUSH_MASK_6 + (NOPUSH_MASK_7<<16),
+ NOPUSH_MASK_8 + (NOPUSH_MASK_9<<16)
+ };
+ return (masks[op>>5] & (1<<(op&0x1F)));
+}
+
+#ifndef NDEBUG
+int sqlite3VdbeOpcodeNoPush(u8 op){
+ return opcodeNoPush(op);
+}
+#endif
+
+/*
+** Loop through the program looking for P2 values that are negative.
+** Each such value is a label. Resolve the label by setting the P2
+** value to its correct non-zero value.
+**
+** This routine is called once after all opcodes have been inserted.
+**
+** Variable *pMaxFuncArgs is set to the maximum value of any P1 argument
+** to an OP_Function or P2 to an OP_AggFunc opcode. This is used by
+** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
+**
+** The integer *pMaxStack is set to the maximum number of vdbe stack
+** entries that static analysis reveals this program might need.
+**
+** This routine also does the following optimization: It scans for
+** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for
+** IdxInsert instructions where P2!=0. If no such instruction is
+** found, then every Statement instruction is changed to a Noop. In
+** this way, we avoid creating the statement journal file unnecessarily.
+*/
+static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
+ int i;
+ int nMaxArgs = 0;
+ int nMaxStack = p->nOp;
+ Op *pOp;
+ int *aLabel = p->aLabel;
+ int doesStatementRollback = 0;
+ int hasStatementBegin = 0;
+ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
+ u8 opcode = pOp->opcode;
+
+ /* Todo: Maybe OP_AggFunc should change to use P1 in the same
+ * way as OP_Function.
+ */
+ if( opcode==OP_Function ){
+ if( pOp->p1>nMaxArgs ) nMaxArgs = pOp->p1;
+ }else if( opcode==OP_AggFunc ){
+ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+ }else if( opcode==OP_Halt ){
+ if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
+ doesStatementRollback = 1;
+ }
+ }else if( opcode==OP_IdxInsert ){
+ if( pOp->p2 ){
+ doesStatementRollback = 1;
+ }
+ }else if( opcode==OP_Statement ){
+ hasStatementBegin = 1;
+ }
+
+ if( opcodeNoPush(opcode) ){
+ nMaxStack--;
+ }
+
+ if( pOp->p2>=0 ) continue;
+ assert( -1-pOp->p2<p->nLabel );
+ pOp->p2 = aLabel[-1-pOp->p2];
+ }
+ sqliteFree(p->aLabel);
+ p->aLabel = 0;
+
+ *pMaxFuncArgs = nMaxArgs;
+ *pMaxStack = nMaxStack;
+
+ /* If we never rollback a statement transaction, then statement
+ ** transactions are not needed. So change every OP_Statement
+ ** opcode into an OP_Noop. This avoid a call to sqlite3OsOpenExclusive()
+ ** which can be expensive on some platforms.
+ */
+ if( hasStatementBegin && !doesStatementRollback ){
+ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
+ if( pOp->opcode==OP_Statement ){
+ pOp->opcode = OP_Noop;
+ }
+ }
+ }
+}
+
+/*
+** Return the address of the next instruction to be inserted.
+*/
+int sqlite3VdbeCurrentAddr(Vdbe *p){
+ assert( p->magic==VDBE_MAGIC_INIT );
+ return p->nOp;
+}
+
+/*
+** Add a whole list of operations to the operation stack. Return the
+** address of the first operation added.
+*/
+int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
+ int addr;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ resizeOpArray(p, p->nOp + nOp);
+ if( p->aOp==0 ){
+ return 0;
+ }
+ addr = p->nOp;
+ if( nOp>0 ){
+ int i;
+ VdbeOpList const *pIn = aOp;
+ for(i=0; i<nOp; i++, pIn++){
+ int p2 = pIn->p2;
+ VdbeOp *pOut = &p->aOp[i+addr];
+ pOut->opcode = pIn->opcode;
+ pOut->p1 = pIn->p1;
+ pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
+ pOut->p3 = pIn->p3;
+ pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
+#ifdef SQLITE_DEBUG
+ if( sqlite3_vdbe_addop_trace ){
+ sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
+ }
+#endif
+ }
+ p->nOp += nOp;
+ }
+ return addr;
+}
+
+/*
+** Change the value of the P1 operand for a specific instruction.
+** This routine is useful when a large program is loaded from a
+** static array using sqlite3VdbeAddOpList but we want to make a
+** few minor changes to the program.
+*/
+void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p && addr>=0 && p->nOp>addr && p->aOp ){
+ p->aOp[addr].p1 = val;
+ }
+}
+
+/*
+** Change the value of the P2 operand for a specific instruction.
+** This routine is useful for setting a jump destination.
+*/
+void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
+ assert( val>=0 );
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p && addr>=0 && p->nOp>addr && p->aOp ){
+ p->aOp[addr].p2 = val;
+ }
+}
+
+/*
+** Change the value of the P3 operand for a specific instruction.
+** This routine is useful when a large program is loaded from a
+** static array using sqlite3VdbeAddOpList but we want to make a
+** few minor changes to the program.
+**
+** If n>=0 then the P3 operand is dynamic, meaning that a copy of
+** the string is made into memory obtained from sqliteMalloc().
+** A value of n==0 means copy bytes of zP3 up to and including the
+** first null byte. If n>0 then copy n+1 bytes of zP3.
+**
+** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure.
+** A copy is made of the KeyInfo structure into memory obtained from
+** sqliteMalloc, to be freed when the Vdbe is finalized.
+** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure
+** stored in memory that the caller has obtained from sqliteMalloc. The
+** caller should not free the allocation, it will be freed when the Vdbe is
+** finalized.
+**
+** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points
+** to a string or structure that is guaranteed to exist for the lifetime of
+** the Vdbe. In these cases we can just copy the pointer.
+**
+** If addr<0 then change P3 on the most recently inserted instruction.
+*/
+void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
+ Op *pOp;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p==0 || p->aOp==0 ){
+ if( n==P3_DYNAMIC || n==P3_KEYINFO_HANDOFF ){
+ sqliteFree((void*)zP3);
+ }
+ if( n==P3_MEM ){
+ sqlite3ValueFree((sqlite3_value *)zP3);
+ }
+ return;
+ }
+ if( addr<0 || addr>=p->nOp ){
+ addr = p->nOp - 1;
+ if( addr<0 ) return;
+ }
+ pOp = &p->aOp[addr];
+ if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
+ sqliteFree(pOp->p3);
+ pOp->p3 = 0;
+ }
+ if( zP3==0 ){
+ pOp->p3 = 0;
+ pOp->p3type = P3_NOTUSED;
+ }else if( n==P3_KEYINFO ){
+ KeyInfo *pKeyInfo;
+ int nField, nByte;
+ nField = ((KeyInfo*)zP3)->nField;
+ nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]);
+ pKeyInfo = sqliteMallocRaw( nByte );
+ pOp->p3 = (char*)pKeyInfo;
+ if( pKeyInfo ){
+ memcpy(pKeyInfo, zP3, nByte);
+ pOp->p3type = P3_KEYINFO;
+ }else{
+ pOp->p3type = P3_NOTUSED;
+ }
+ }else if( n==P3_KEYINFO_HANDOFF ){
+ pOp->p3 = (char*)zP3;
+ pOp->p3type = P3_KEYINFO;
+ }else if( n<0 ){
+ pOp->p3 = (char*)zP3;
+ pOp->p3type = n;
+ }else{
+ if( n==0 ) n = strlen(zP3);
+ pOp->p3 = sqliteStrNDup(zP3, n);
+ pOp->p3type = P3_DYNAMIC;
+ }
+}
+
+#ifndef NDEBUG
+/*
+** Replace the P3 field of the most recently coded instruction with
+** comment text.
+*/
+void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
+ va_list ap;
+ assert( p->nOp>0 );
+ assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 );
+ va_start(ap, zFormat);
+ sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
+ va_end(ap);
+}
+#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; i<p->nOp; i++){
+ if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1;
+ }
+ return 0;
+}
+
+/*
+** Return the opcode for a given address.
+*/
+VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
+ assert( p->magic==VDBE_MAGIC_INIT );
+ assert( addr>=0 && addr<p->nOp );
+ return &p->aOp[addr];
+}
+
+#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
+ || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+/*
+** Compute a string that describes the P3 parameter for an opcode.
+** Use zTemp for any required temporary buffer space.
+*/
+static char *displayP3(Op *pOp, char *zTemp, int nTemp){
+ char *zP3;
+ assert( nTemp>=20 );
+ switch( pOp->p3type ){
+ case P3_KEYINFO: {
+ int i, j;
+ KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
+ sprintf(zTemp, "keyinfo(%d", pKeyInfo->nField);
+ i = strlen(zTemp);
+ for(j=0; j<pKeyInfo->nField; j++){
+ CollSeq *pColl = pKeyInfo->aColl[j];
+ if( pColl ){
+ int n = strlen(pColl->zName);
+ if( i+n>nTemp-6 ){
+ strcpy(&zTemp[i],",...");
+ break;
+ }
+ zTemp[i++] = ',';
+ if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
+ zTemp[i++] = '-';
+ }
+ strcpy(&zTemp[i], pColl->zName);
+ i += n;
+ }else if( i+4<nTemp-6 ){
+ strcpy(&zTemp[i],",nil");
+ i += 4;
+ }
+ }
+ zTemp[i++] = ')';
+ zTemp[i] = 0;
+ assert( i<nTemp );
+ zP3 = zTemp;
+ break;
+ }
+ case P3_COLLSEQ: {
+ CollSeq *pColl = (CollSeq*)pOp->p3;
+ sprintf(zTemp, "collseq(%.20s)", pColl->zName);
+ zP3 = zTemp;
+ break;
+ }
+ case P3_FUNCDEF: {
+ FuncDef *pDef = (FuncDef*)pOp->p3;
+ char zNum[30];
+ sprintf(zTemp, "%.*s", nTemp, pDef->zName);
+ sprintf(zNum,"(%d)", pDef->nArg);
+ if( strlen(zTemp)+strlen(zNum)+1<=nTemp ){
+ strcat(zTemp, zNum);
+ }
+ zP3 = zTemp;
+ break;
+ }
+ default: {
+ zP3 = pOp->p3;
+ if( zP3==0 || pOp->opcode==OP_Noop ){
+ zP3 = "";
+ }
+ }
+ }
+ return zP3;
+}
+#endif
+
+
+#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+/*
+** Print a single opcode. This routine is used for debugging only.
+*/
+void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
+ char *zP3;
+ char zPtr[50];
+ static const char *zFormat1 = "%4d %-13s %4d %4d %s\n";
+ if( pOut==0 ) pOut = stdout;
+ zP3 = displayP3(pOp, zPtr, sizeof(zPtr));
+ fprintf(pOut, zFormat1,
+ pc, sqlite3OpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3);
+ fflush(pOut);
+}
+#endif
+
+/*
+** Release an array of N Mem elements
+*/
+static void releaseMemArray(Mem *p, int N){
+ if( p ){
+ while( N-->0 ){
+ sqlite3VdbeMemRelease(p++);
+ }
+ }
+}
+
+#ifndef SQLITE_OMIT_EXPLAIN
+/*
+** Give a listing of the program in the virtual machine.
+**
+** The interface is the same as sqlite3VdbeExec(). But instead of
+** running the code, it invokes the callback once for each instruction.
+** This feature is used to implement "EXPLAIN".
+*/
+int sqlite3VdbeList(
+ Vdbe *p /* The VDBE */
+){
+ sqlite3 *db = p->db;
+ int i;
+ int rc = SQLITE_OK;
+
+ assert( p->explain );
+ if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
+ assert( db->magic==SQLITE_MAGIC_BUSY );
+ assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+
+ /* Even though this opcode does not put dynamic strings onto the
+ ** the stack, they may become dynamic if the user calls
+ ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
+ */
+ if( p->pTos==&p->aStack[4] ){
+ releaseMemArray(p->aStack, 5);
+ }
+ p->resOnStack = 0;
+
+
+ i = p->pc++;
+ if( i>=p->nOp ){
+ p->rc = SQLITE_OK;
+ rc = SQLITE_DONE;
+ }else if( db->flags & SQLITE_Interrupt ){
+ db->flags &= ~SQLITE_Interrupt;
+ p->rc = SQLITE_INTERRUPT;
+ rc = SQLITE_ERROR;
+ sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);
+ }else{
+ Op *pOp = &p->aOp[i];
+ Mem *pMem = p->aStack;
+ pMem->flags = MEM_Int;
+ pMem->type = SQLITE_INTEGER;
+ pMem->i = i; /* Program counter */
+ pMem++;
+
+ pMem->flags = MEM_Static|MEM_Str|MEM_Term;
+ pMem->z = sqlite3OpcodeNames[pOp->opcode]; /* Opcode */
+ pMem->n = strlen(pMem->z);
+ pMem->type = SQLITE_TEXT;
+ pMem->enc = SQLITE_UTF8;
+ pMem++;
+
+ pMem->flags = MEM_Int;
+ pMem->i = pOp->p1; /* P1 */
+ pMem->type = SQLITE_INTEGER;
+ pMem++;
+
+ pMem->flags = MEM_Int;
+ pMem->i = pOp->p2; /* P2 */
+ pMem->type = SQLITE_INTEGER;
+ pMem++;
+
+ pMem->flags = MEM_Short|MEM_Str|MEM_Term; /* P3 */
+ pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
+ pMem->type = SQLITE_TEXT;
+ pMem->enc = SQLITE_UTF8;
+
+ p->nResColumn = 5;
+ p->pTos = pMem;
+ p->rc = SQLITE_OK;
+ p->resOnStack = 1;
+ rc = SQLITE_ROW;
+ }
+ return rc;
+}
+#endif /* SQLITE_OMIT_EXPLAIN */
+
+/*
+** Print the SQL that was used to generate a VDBE program.
+*/
+void sqlite3VdbePrintSql(Vdbe *p){
+#ifdef SQLITE_DEBUG
+ int nOp = p->nOp;
+ VdbeOp *pOp;
+ if( nOp<1 ) return;
+ pOp = &p->aOp[nOp-1];
+ if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
+ const char *z = pOp->p3;
+ while( isspace(*(u8*)z) ) z++;
+ printf("SQL: [%s]\n", z);
+ }
+#endif
+}
+
+/*
+** Prepare a virtual machine for execution. This involves things such
+** as allocating stack space and initializing the program counter.
+** After the VDBE has be prepped, it can be executed by one or more
+** calls to sqlite3VdbeExec().
+**
+** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
+** VDBE_MAGIC_RUN.
+*/
+void sqlite3VdbeMakeReady(
+ Vdbe *p, /* The VDBE */
+ int nVar, /* Number of '?' see in the SQL statement */
+ int nMem, /* Number of memory cells to allocate */
+ int nCursor, /* Number of cursors to allocate */
+ int nAgg, /* Number of aggregate contexts required */
+ int isExplain /* True if the EXPLAIN keywords is present */
+){
+ int n;
+
+ assert( p!=0 );
+ assert( p->magic==VDBE_MAGIC_INIT );
+
+ /* There should be at least one opcode.
+ */
+ assert( p->nOp>0 );
+
+ /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. This
+ * is because the call to resizeOpArray() below may shrink the
+ * p->aOp[] array to save memory if called when in VDBE_MAGIC_RUN
+ * state.
+ */
+ p->magic = VDBE_MAGIC_RUN;
+
+ /* No instruction ever pushes more than a single element onto the
+ ** stack. And the stack never grows on successive executions of the
+ ** same loop. So the total number of instructions is an upper bound
+ ** on the maximum stack depth required. (Added later:) The
+ ** resolveP2Values() call computes a tighter upper bound on the
+ ** stack size.
+ **
+ ** Allocation all the stack space we will ever need.
+ */
+ if( p->aStack==0 ){
+ int nArg; /* Maximum number of args passed to a user function. */
+ int nStack; /* Maximum number of stack entries required */
+ resolveP2Values(p, &nArg, &nStack);
+ resizeOpArray(p, p->nOp);
+ assert( nVar>=0 );
+ assert( nStack<p->nOp );
+ nStack = isExplain ? 10 : nStack;
+ p->aStack = sqliteMalloc(
+ nStack*sizeof(p->aStack[0]) /* aStack */
+ + nArg*sizeof(Mem*) /* apArg */
+ + nVar*sizeof(Mem) /* aVar */
+ + nVar*sizeof(char*) /* azVar */
+ + nMem*sizeof(Mem) /* aMem */
+ + nCursor*sizeof(Cursor*) /* apCsr */
+ + nAgg*sizeof(Agg) /* Aggregate contexts */
+ );
+ if( !sqlite3_malloc_failed ){
+ p->aMem = &p->aStack[nStack];
+ p->nMem = nMem;
+ p->aVar = &p->aMem[nMem];
+ p->nVar = nVar;
+ p->okVar = 0;
+ p->apArg = (Mem**)&p->aVar[nVar];
+ p->azVar = (char**)&p->apArg[nArg];
+ p->apCsr = (Cursor**)&p->azVar[nVar];
+ if( nAgg>0 ){
+ p->nAgg = nAgg;
+ p->apAgg = (Agg*)&p->apCsr[nCursor];
+ }
+ p->nCursor = nCursor;
+ for(n=0; n<nVar; n++){
+ p->aVar[n].flags = MEM_Null;
+ }
+ }
+ }
+ p->pAgg = p->apAgg;
+ for(n=0; n<p->nMem; n++){
+ p->aMem[n].flags = MEM_Null;
+ }
+
+#ifdef SQLITE_DEBUG
+ if( (p->db->flags & SQLITE_VdbeListing)!=0
+ || sqlite3OsFileExists("vdbe_explain")
+ ){
+ int i;
+ printf("VDBE Program Listing:\n");
+ sqlite3VdbePrintSql(p);
+ for(i=0; i<p->nOp; i++){
+ sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
+ }
+ }
+ if( sqlite3OsFileExists("vdbe_trace") ){
+ p->trace = stdout;
+ }
+#endif
+ p->pTos = &p->aStack[-1];
+ p->pc = -1;
+ p->rc = SQLITE_OK;
+ p->uniqueCnt = 0;
+ p->returnDepth = 0;
+ p->errorAction = OE_Abort;
+ p->popStack = 0;
+ p->explain |= isExplain;
+ p->magic = VDBE_MAGIC_RUN;
+ p->nChange = 0;
+#ifdef VDBE_PROFILE
+ {
+ int i;
+ for(i=0; i<p->nOp; i++){
+ p->aOp[i].cnt = 0;
+ p->aOp[i].cycles = 0;
+ }
+ }
+#endif
+}
+
+
+/*
+** Remove any elements that remain on the sorter for the VDBE given.
+*/
+void sqlite3VdbeSorterReset(Vdbe *p){
+ while( p->pSort ){
+ Sorter *pSorter = p->pSort;
+ p->pSort = pSorter->pNext;
+ sqliteFree(pSorter->zKey);
+ sqlite3VdbeMemRelease(&pSorter->data);
+ sqliteFree(pSorter);
+ }
+ p->pSortTail = 0;
+}
+
+/*
+** Free all resources allociated with AggElem pElem, an element of
+** aggregate pAgg.
+*/
+static void freeAggElem(AggElem *pElem, Agg *pAgg){
+ int i;
+ for(i=0; i<pAgg->nMem; i++){
+ Mem *pMem = &pElem->aMem[i];
+ if( pAgg->apFunc && pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
+ sqlite3_context ctx;
+ ctx.pFunc = pAgg->apFunc[i];
+ ctx.s.flags = MEM_Null;
+ ctx.pAgg = pMem->z;
+ ctx.cnt = pMem->i;
+ ctx.isError = 0;
+ (*ctx.pFunc->xFinalize)(&ctx);
+ pMem->z = ctx.pAgg;
+ if( pMem->z!=0 && pMem->z!=pMem->zShort ){
+ sqliteFree(pMem->z);
+ }
+ sqlite3VdbeMemRelease(&ctx.s);
+ }else{
+ sqlite3VdbeMemRelease(pMem);
+ }
+ }
+ sqliteFree(pElem);
+}
+
+/*
+** Reset an Agg structure. Delete all its contents.
+**
+** For installable aggregate functions, if the step function has been
+** called, make sure the finalizer function has also been called. The
+** finalizer might need to free memory that was allocated as part of its
+** private context. If the finalizer has not been called yet, call it
+** now.
+**
+** If db is NULL, then this is being called from sqliteVdbeReset(). In
+** this case clean up all references to the temp-table used for
+** aggregates (if it was ever opened).
+**
+** If db is not NULL, then this is being called from with an OP_AggReset
+** opcode. Open the temp-table, if it has not already been opened and
+** delete the contents of the table used for aggregate information, ready
+** for the next round of aggregate processing.
+*/
+int sqlite3VdbeAggReset(sqlite3 *db, Agg *pAgg, KeyInfo *pKeyInfo){
+ int rc = 0;
+ BtCursor *pCsr;
+
+ if( !pAgg ) return SQLITE_OK;
+ pCsr = pAgg->pCsr;
+ assert( (pCsr && pAgg->nTab>0) || (!pCsr && pAgg->nTab==0)
+ || sqlite3_malloc_failed );
+
+ /* If pCsr is not NULL, then the table used for aggregate information
+ ** is open. Loop through it and free the AggElem* structure pointed at
+ ** by each entry. If the finalizer has not been called for an AggElem,
+ ** do that too. Finally, clear the btree table itself.
+ */
+ if( pCsr ){
+ int res;
+ assert( pAgg->pBtree );
+ assert( pAgg->nTab>0 );
+
+ rc=sqlite3BtreeFirst(pCsr, &res);
+ while( res==0 && rc==SQLITE_OK ){
+ AggElem *pElem;
+ rc = sqlite3BtreeData(pCsr, 0, sizeof(AggElem*), (char *)&pElem);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ assert( pAgg->apFunc!=0 );
+ freeAggElem(pElem, pAgg);
+ rc=sqlite3BtreeNext(pCsr, &res);
+ }
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ sqlite3BtreeCloseCursor(pCsr);
+ sqlite3BtreeClearTable(pAgg->pBtree, pAgg->nTab);
+ }else{
+ /* The cursor may not be open because the aggregator was never used,
+ ** or it could be that it was used but there was no GROUP BY clause.
+ */
+ if( pAgg->pCurrent ){
+ freeAggElem(pAgg->pCurrent, pAgg);
+ }
+ }
+
+ /* If db is not NULL and we have not yet and we have not yet opened
+ ** the temporary btree then do so and create the table to store aggregate
+ ** information.
+ **
+ ** If db is NULL, then close the temporary btree if it is open.
+ */
+ if( db ){
+ if( !pAgg->pBtree ){
+ assert( pAgg->nTab==0 );
+#ifndef SQLITE_OMIT_MEMORYDB
+ rc = sqlite3BtreeFactory(db, ":memory:", 0, TEMP_PAGES, &pAgg->pBtree);
+#else
+ rc = sqlite3BtreeFactory(db, 0, 0, TEMP_PAGES, &pAgg->pBtree);
+#endif
+ if( rc!=SQLITE_OK ) return rc;
+ sqlite3BtreeBeginTrans(pAgg->pBtree, 1);
+ rc = sqlite3BtreeCreateTable(pAgg->pBtree, &pAgg->nTab, 0);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ assert( pAgg->nTab!=0 );
+
+ rc = sqlite3BtreeCursor(pAgg->pBtree, pAgg->nTab, 1,
+ sqlite3VdbeRecordCompare, pKeyInfo, &pAgg->pCsr);
+ if( rc!=SQLITE_OK ) return rc;
+ }else{
+ if( pAgg->pBtree ){
+ sqlite3BtreeClose(pAgg->pBtree);
+ pAgg->pBtree = 0;
+ pAgg->nTab = 0;
+ }
+ pAgg->pCsr = 0;
+ }
+
+ if( pAgg->apFunc ){
+ sqliteFree(pAgg->apFunc);
+ pAgg->apFunc = 0;
+ }
+ pAgg->pCurrent = 0;
+ pAgg->nMem = 0;
+ pAgg->searching = 0;
+ 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.
+*/
+void sqlite3VdbeFreeCursor(Cursor *pCx){
+ if( pCx==0 ){
+ return;
+ }
+ if( pCx->pCursor ){
+ sqlite3BtreeCloseCursor(pCx->pCursor);
+ }
+ if( pCx->pBt ){
+ sqlite3BtreeClose(pCx->pBt);
+ }
+ sqliteFree(pCx->pData);
+ sqliteFree(pCx->aType);
+ sqliteFree(pCx);
+}
+
+/*
+** Close all cursors
+*/
+static void closeAllCursors(Vdbe *p){
+ int i;
+ if( p->apCsr==0 ) return;
+ for(i=0; i<p->nCursor; i++){
+ sqlite3VdbeFreeCursor(p->apCsr[i]);
+ p->apCsr[i] = 0;
+ }
+}
+
+/*
+** Clean up the VM after execution.
+**
+** This routine will automatically close any cursors, lists, and/or
+** sorters that were left open. It also deletes the values of
+** variables in the aVar[] array.
+*/
+static void Cleanup(Vdbe *p){
+ int i;
+ if( p->aStack ){
+ releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack));
+ p->pTos = &p->aStack[-1];
+ }
+ closeAllCursors(p);
+ releaseMemArray(p->aMem, p->nMem);
+ if( p->pList ){
+ sqlite3VdbeKeylistFree(p->pList);
+ p->pList = 0;
+ }
+ if( p->contextStack ){
+ for(i=0; i<p->contextStackTop; i++){
+ sqlite3VdbeKeylistFree(p->contextStack[i].pList);
+ }
+ sqliteFree(p->contextStack);
+ }
+ sqlite3VdbeSorterReset(p);
+ for(i=0; i<p->nAgg; i++){
+ sqlite3VdbeAggReset(0, &p->apAgg[i], 0);
+ }
+ p->contextStack = 0;
+ p->contextStackDepth = 0;
+ p->contextStackTop = 0;
+ sqliteFree(p->zErrMsg);
+ p->zErrMsg = 0;
+}
+
+/*
+** Set the number of result columns that will be returned by this SQL
+** statement. This is now set at compile time, rather than during
+** execution of the vdbe program so that sqlite3_column_count() can
+** be called on an SQL statement before sqlite3_step().
+*/
+void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
+ Mem *pColName;
+ int n;
+ assert( 0==p->nResColumn );
+ p->nResColumn = nResColumn;
+ n = nResColumn*2;
+ p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
+ if( p->aColName==0 ) return;
+ while( n-- > 0 ){
+ (pColName++)->flags = MEM_Null;
+ }
+}
+
+/*
+** Set the name of the idx'th column to be returned by the SQL statement.
+** zName must be a pointer to a nul terminated string.
+**
+** This call must be made after a call to sqlite3VdbeSetNumCols().
+**
+** If N==P3_STATIC it means that zName is a pointer to a constant static
+** string and we can just copy the pointer. If it is P3_DYNAMIC, then
+** the string is freed using sqliteFree() when the vdbe is finished with
+** it. Otherwise, N bytes of zName are copied.
+*/
+int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
+ int rc;
+ Mem *pColName;
+ assert( idx<(2*p->nResColumn) );
+ if( sqlite3_malloc_failed ) return SQLITE_NOMEM;
+ assert( p->aColName!=0 );
+ pColName = &(p->aColName[idx]);
+ if( N==P3_DYNAMIC || N==P3_STATIC ){
+ rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
+ }else{
+ rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
+ }
+ if( rc==SQLITE_OK && N==P3_DYNAMIC ){
+ pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
+ pColName->xDel = 0;
+ }
+ return rc;
+}
+
+/*
+** A read or write transaction may or may not be active on database handle
+** db. If a transaction is active, commit it. If there is a
+** write-transaction spanning more than one database file, this routine
+** takes care of the master journal trickery.
+*/
+static int vdbeCommit(sqlite3 *db){
+ int i;
+ int nTrans = 0; /* Number of databases with an active write-transaction */
+ int rc = SQLITE_OK;
+ int needXcommit = 0;
+
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt && sqlite3BtreeIsInTrans(pBt) ){
+ needXcommit = 1;
+ if( i!=1 ) nTrans++;
+ }
+ }
+
+ /* If there are any write-transactions at all, invoke the commit hook */
+ if( needXcommit && db->xCommitCallback ){
+ int rc;
+ sqlite3SafetyOff(db);
+ rc = db->xCommitCallback(db->pCommitArg);
+ sqlite3SafetyOn(db);
+ if( rc ){
+ return SQLITE_CONSTRAINT;
+ }
+ }
+
+ /* The simple case - no more than one database file (not counting the
+ ** TEMP database) has a transaction active. There is no need for the
+ ** master-journal.
+ **
+ ** If the return value of sqlite3BtreeGetFilename() is a zero length
+ ** string, it means the main database is :memory:. In that case we do
+ ** not support atomic multi-file commits, so use the simple case then
+ ** too.
+ */
+ if( 0==strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){
+ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ rc = sqlite3BtreeSync(pBt, 0);
+ }
+ }
+
+ /* Do the commit only if all databases successfully synced */
+ if( rc==SQLITE_OK ){
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ sqlite3BtreeCommit(pBt);
+ }
+ }
+ }
+ }
+
+ /* The complex case - There is a multi-file write-transaction active.
+ ** This requires a master journal file to ensure the transaction is
+ ** committed atomicly.
+ */
+#ifndef SQLITE_OMIT_DISKIO
+ else{
+ char *zMaster = 0; /* File-name for the master journal */
+ char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
+ OsFile master;
+
+ /* Select a master journal file name */
+ do {
+ u32 random;
+ sqliteFree(zMaster);
+ sqlite3Randomness(sizeof(random), &random);
+ zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff);
+ if( !zMaster ){
+ return SQLITE_NOMEM;
+ }
+ }while( sqlite3OsFileExists(zMaster) );
+
+ /* Open the master journal. */
+ memset(&master, 0, sizeof(master));
+ rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
+ if( rc!=SQLITE_OK ){
+ sqliteFree(zMaster);
+ return rc;
+ }
+
+ /* Write the name of each database file in the transaction into the new
+ ** master journal file. If an error occurs at this point close
+ ** and delete the master journal file. All the individual journal files
+ ** still have 'null' as the master journal pointer, so they will roll
+ ** back independently if a failure occurs.
+ */
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( i==1 ) continue; /* Ignore the TEMP database */
+ if( pBt && sqlite3BtreeIsInTrans(pBt) ){
+ char const *zFile = sqlite3BtreeGetJournalname(pBt);
+ if( zFile[0]==0 ) continue; /* Ignore :memory: databases */
+ rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1);
+ if( rc!=SQLITE_OK ){
+ sqlite3OsClose(&master);
+ sqlite3OsDelete(zMaster);
+ sqliteFree(zMaster);
+ return rc;
+ }
+ }
+ }
+
+
+ /* Sync the master journal file. Before doing this, open the directory
+ ** the master journal file is store in so that it gets synced too.
+ */
+ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
+ rc = sqlite3OsOpenDirectory(zMainFile, &master);
+ if( rc!=SQLITE_OK || (rc = sqlite3OsSync(&master))!=SQLITE_OK ){
+ sqlite3OsClose(&master);
+ sqlite3OsDelete(zMaster);
+ sqliteFree(zMaster);
+ return rc;
+ }
+
+ /* Sync all the db files involved in the transaction. The same call
+ ** sets the master journal pointer in each individual journal. If
+ ** an error occurs here, do not delete the master journal file.
+ **
+ ** If the error occurs during the first call to sqlite3BtreeSync(),
+ ** then there is a chance that the master journal file will be
+ ** orphaned. But we cannot delete it, in case the master journal
+ ** file name was written into the journal file before the failure
+ ** occured.
+ */
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt && sqlite3BtreeIsInTrans(pBt) ){
+ rc = sqlite3BtreeSync(pBt, zMaster);
+ if( rc!=SQLITE_OK ){
+ sqlite3OsClose(&master);
+ sqliteFree(zMaster);
+ return rc;
+ }
+ }
+ }
+ sqlite3OsClose(&master);
+
+ /* Delete the master journal file. This commits the transaction. After
+ ** doing this the directory is synced again before any individual
+ ** transaction files are deleted.
+ */
+ rc = sqlite3OsDelete(zMaster);
+ assert( rc==SQLITE_OK );
+ sqliteFree(zMaster);
+ zMaster = 0;
+ rc = sqlite3OsSyncDirectory(zMainFile);
+ if( rc!=SQLITE_OK ){
+ /* This is not good. The master journal file has been deleted, but
+ ** the directory sync failed. There is no completely safe course of
+ ** action from here. The individual journals contain the name of the
+ ** master journal file, but there is no way of knowing if that
+ ** master journal exists now or if it will exist after the operating
+ ** system crash that may follow the fsync() failure.
+ */
+ return rc;
+ }
+
+ /* All files and directories have already been synced, so the following
+ ** calls to sqlite3BtreeCommit() are only closing files and deleting
+ ** journals. If something goes wrong while this is happening we don't
+ ** really care. The integrity of the transaction is already guaranteed,
+ ** but some stray 'cold' journals may be lying around. Returning an
+ ** error code won't help matters.
+ */
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ sqlite3BtreeCommit(pBt);
+ }
+ }
+ }
+#endif
+
+ return rc;
+}
+
+/*
+** Find every active VM other than pVdbe and change its status to
+** aborted. This happens when one VM causes a rollback due to an
+** ON CONFLICT ROLLBACK clause (for example). The other VMs must be
+** aborted so that they do not have data rolled out from underneath
+** them leading to a segfault.
+*/
+static void abortOtherActiveVdbes(Vdbe *pVdbe){
+ Vdbe *pOther;
+ for(pOther=pVdbe->db->pVdbe; pOther; pOther=pOther->pNext){
+ if( pOther==pVdbe ) continue;
+ if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue;
+ closeAllCursors(pOther);
+ pOther->aborted = 1;
+ }
+}
+
+/*
+** This routine checks that the sqlite3.activeVdbeCnt count variable
+** matches the number of vdbe's in the list sqlite3.pVdbe that are
+** currently active. An assertion fails if the two counts do not match.
+** This is an internal self-check only - it is not an essential processing
+** step.
+**
+** This is a no-op if NDEBUG is defined.
+*/
+#ifndef NDEBUG
+static void checkActiveVdbeCnt(sqlite3 *db){
+ Vdbe *p;
+ int cnt = 0;
+ p = db->pVdbe;
+ while( p ){
+ if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
+ cnt++;
+ }
+ p = p->pNext;
+ }
+ assert( cnt==db->activeVdbeCnt );
+}
+#else
+#define checkActiveVdbeCnt(x)
+#endif
+
+/*
+** This routine is called the when a VDBE tries to halt. If the VDBE
+** has made changes and is in autocommit mode, then commit those
+** changes. If a rollback is needed, then do the rollback.
+**
+** This routine is the only way to move the state of a VM from
+** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.
+**
+** Return an error code. If the commit could not complete because of
+** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it
+** means the close did not happen and needs to be repeated.
+*/
+int sqlite3VdbeHalt(Vdbe *p){
+ sqlite3 *db = p->db;
+ int i;
+ int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */
+
+ if( p->magic!=VDBE_MAGIC_RUN ){
+ /* Already halted. Nothing to do. */
+ assert( p->magic==VDBE_MAGIC_HALT );
+ return SQLITE_OK;
+ }
+ closeAllCursors(p);
+ checkActiveVdbeCnt(db);
+ if( p->pc<0 ){
+ /* No commit or rollback needed if the program never started */
+ }else if( db->autoCommit && db->activeVdbeCnt==1 ){
+ if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
+ /* The auto-commit flag is true, there are no other active queries
+ ** using this handle and the vdbe program was successful or hit an
+ ** 'OR FAIL' constraint. This means a commit is required.
+ */
+ int rc = vdbeCommit(db);
+ if( rc==SQLITE_BUSY ){
+ return SQLITE_BUSY;
+ }else if( rc!=SQLITE_OK ){
+ p->rc = rc;
+ xFunc = sqlite3BtreeRollback;
+ }
+ }else{
+ xFunc = sqlite3BtreeRollback;
+ }
+ }else{
+ if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
+ xFunc = sqlite3BtreeCommitStmt;
+ }else if( p->errorAction==OE_Abort ){
+ xFunc = sqlite3BtreeRollbackStmt;
+ }else{
+ xFunc = sqlite3BtreeRollback;
+ db->autoCommit = 1;
+ abortOtherActiveVdbes(p);
+ }
+ }
+
+ /* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
+ ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
+ ** each backend. If an error occurs and the return code is still
+ ** SQLITE_OK, set the return code to the new error value.
+ */
+ for(i=0; xFunc && i<db->nDb; i++){
+ int rc;
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ rc = xFunc(pBt);
+ if( p->rc==SQLITE_OK ) p->rc = rc;
+ }
+ }
+
+ /* If this was an INSERT, UPDATE or DELETE, set the change counter. */
+ if( p->changeCntOn && p->pc>=0 ){
+ if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
+ sqlite3VdbeSetChanges(db, p->nChange);
+ }else{
+ sqlite3VdbeSetChanges(db, 0);
+ }
+ p->nChange = 0;
+ }
+
+ /* Rollback or commit any schema changes that occurred. */
+ if( p->rc!=SQLITE_OK ){
+ sqlite3RollbackInternalChanges(db);
+ }else if( db->flags & SQLITE_InternChanges ){
+ sqlite3CommitInternalChanges(db);
+ }
+
+ /* We have successfully halted and closed the VM. Record this fact. */
+ if( p->pc>=0 ){
+ db->activeVdbeCnt--;
+ }
+ p->magic = VDBE_MAGIC_HALT;
+ checkActiveVdbeCnt(db);
+
+ return SQLITE_OK;
+}
+
+/*
+** Clean up a VDBE after execution but do not delete the VDBE just yet.
+** Write any error messages into *pzErrMsg. Return the result code.
+**
+** After this routine is run, the VDBE should be ready to be executed
+** again.
+**
+** To look at it another way, this routine resets the state of the
+** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
+** VDBE_MAGIC_INIT.
+*/
+int sqlite3VdbeReset(Vdbe *p){
+ if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
+ sqlite3Error(p->db, SQLITE_MISUSE, 0);
+ return SQLITE_MISUSE;
+ }
+
+ /* If the VM did not run to completion or if it encountered an
+ ** error, then it might not have been halted properly. So halt
+ ** it now.
+ */
+ sqlite3VdbeHalt(p);
+
+ /* If the VDBE has be run even partially, then transfer the error code
+ ** and error message from the VDBE into the main database structure. But
+ ** if the VDBE has just been set to run but has not actually executed any
+ ** instructions yet, leave the main database error information unchanged.
+ */
+ if( p->pc>=0 ){
+ if( p->zErrMsg ){
+ sqlite3Error(p->db, p->rc, "%s", p->zErrMsg);
+ sqliteFree(p->zErrMsg);
+ p->zErrMsg = 0;
+ }else if( p->rc ){
+ sqlite3Error(p->db, p->rc, 0);
+ }else{
+ sqlite3Error(p->db, SQLITE_OK, 0);
+ }
+ }else if( p->rc && p->expired ){
+ /* The expired flag was set on the VDBE before the first call
+ ** to sqlite3_step(). For consistency (since sqlite3_step() was
+ ** called), set the database error in this case as well.
+ */
+ sqlite3Error(p->db, p->rc, 0);
+ }
+
+ /* Reclaim all memory used by the VDBE
+ */
+ Cleanup(p);
+
+ /* Save profiling information from this VDBE run.
+ */
+ assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 );
+#ifdef VDBE_PROFILE
+ {
+ FILE *out = fopen("vdbe_profile.out", "a");
+ if( out ){
+ int i;
+ fprintf(out, "---- ");
+ for(i=0; i<p->nOp; i++){
+ fprintf(out, "%02x", p->aOp[i].opcode);
+ }
+ fprintf(out, "\n");
+ for(i=0; i<p->nOp; i++){
+ fprintf(out, "%6d %10lld %8lld ",
+ p->aOp[i].cnt,
+ p->aOp[i].cycles,
+ p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
+ );
+ sqlite3VdbePrintOp(out, i, &p->aOp[i]);
+ }
+ fclose(out);
+ }
+ }
+#endif
+ p->magic = VDBE_MAGIC_INIT;
+ p->aborted = 0;
+ if( p->rc==SQLITE_SCHEMA ){
+ sqlite3ResetInternalSchema(p->db, 0);
+ }
+ return p->rc;
+}
+
+/*
+** Clean up and delete a VDBE after execution. Return an integer which is
+** the result code. Write any error message text into *pzErrMsg.
+*/
+int sqlite3VdbeFinalize(Vdbe *p){
+ int rc = SQLITE_OK;
+
+ if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
+ rc = sqlite3VdbeReset(p);
+ }else if( p->magic!=VDBE_MAGIC_INIT ){
+ return SQLITE_MISUSE;
+ }
+ sqlite3VdbeDelete(p);
+ return rc;
+}
+
+/*
+** Call the destructor for each auxdata entry in pVdbeFunc for which
+** the corresponding bit in mask is clear. Auxdata entries beyond 31
+** are always destroyed. To destroy all auxdata entries, call this
+** routine with mask==0.
+*/
+void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
+ int i;
+ for(i=0; i<pVdbeFunc->nAux; i++){
+ struct AuxData *pAux = &pVdbeFunc->apAux[i];
+ if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
+ if( pAux->xDelete ){
+ pAux->xDelete(pAux->pAux);
+ }
+ pAux->pAux = 0;
+ }
+ }
+}
+
+/*
+** Delete an entire VDBE.
+*/
+void sqlite3VdbeDelete(Vdbe *p){
+ int i;
+ if( p==0 ) return;
+ Cleanup(p);
+ if( p->pPrev ){
+ p->pPrev->pNext = p->pNext;
+ }else{
+ assert( p->db->pVdbe==p );
+ p->db->pVdbe = p->pNext;
+ }
+ if( p->pNext ){
+ p->pNext->pPrev = p->pPrev;
+ }
+ if( p->aOp ){
+ for(i=0; i<p->nOp; i++){
+ Op *pOp = &p->aOp[i];
+ if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
+ sqliteFree(pOp->p3);
+ }
+ if( pOp->p3type==P3_VDBEFUNC ){
+ VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
+ sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
+ sqliteFree(pVdbeFunc);
+ }
+ if( pOp->p3type==P3_MEM ){
+ sqlite3ValueFree((sqlite3_value*)pOp->p3);
+ }
+ }
+ sqliteFree(p->aOp);
+ }
+ releaseMemArray(p->aVar, p->nVar);
+ sqliteFree(p->aLabel);
+ sqliteFree(p->aStack);
+ releaseMemArray(p->aColName, p->nResColumn*2);
+ sqliteFree(p->aColName);
+ p->magic = VDBE_MAGIC_DEAD;
+ sqliteFree(p);
+}
+
+/*
+** If a MoveTo operation is pending on the given cursor, then do that
+** MoveTo now. Return an error code. If no MoveTo is pending, this
+** routine does nothing and returns SQLITE_OK.
+*/
+int sqlite3VdbeCursorMoveto(Cursor *p){
+ if( p->deferredMoveto ){
+ int res, rc;
+ extern int sqlite3_search_count;
+ assert( p->isTable );
+ if( p->isTable ){
+ rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
+ }else{
+ rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
+ sizeof(i64),&res);
+ }
+ if( rc ) return rc;
+ *p->pIncrKey = 0;
+ p->lastRowid = keyToInt(p->movetoTarget);
+ p->rowidIsValid = res==0;
+ if( res<0 ){
+ rc = sqlite3BtreeNext(p->pCursor, &res);
+ if( rc ) return rc;
+ }
+ sqlite3_search_count++;
+ p->deferredMoveto = 0;
+ p->cacheValid = 0;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** The following functions:
+**
+** sqlite3VdbeSerialType()
+** sqlite3VdbeSerialTypeLen()
+** sqlite3VdbeSerialRead()
+** sqlite3VdbeSerialLen()
+** sqlite3VdbeSerialWrite()
+**
+** encapsulate the code that serializes values for storage in SQLite
+** data and index records. Each serialized value consists of a
+** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
+** integer, stored as a varint.
+**
+** In an SQLite index record, the serial type is stored directly before
+** the blob of data that it corresponds to. In a table record, all serial
+** types are stored at the start of the record, and the blobs of data at
+** the end. Hence these functions allow the caller to handle the
+** serial-type and data blob seperately.
+**
+** The following table describes the various storage classes for data:
+**
+** serial type bytes of data type
+** -------------- --------------- ---------------
+** 0 0 NULL
+** 1 1 signed integer
+** 2 2 signed integer
+** 3 3 signed integer
+** 4 4 signed integer
+** 5 6 signed integer
+** 6 8 signed integer
+** 7 8 IEEE float
+** 8-11 reserved for expansion
+** N>=12 and even (N-12)/2 BLOB
+** N>=13 and odd (N-13)/2 text
+**
+*/
+
+/*
+** Return the serial-type for the value stored in pMem.
+*/
+u32 sqlite3VdbeSerialType(Mem *pMem){
+ int flags = pMem->flags;
+
+ if( flags&MEM_Null ){
+ return 0;
+ }
+ if( flags&MEM_Int ){
+ /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
+# define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
+ i64 i = pMem->i;
+ u64 u = i<0 ? -i : i;
+ if( u<=127 ) return 1;
+ if( u<=32767 ) return 2;
+ if( u<=8388607 ) return 3;
+ if( u<=2147483647 ) return 4;
+ if( u<=MAX_6BYTE ) return 5;
+ return 6;
+ }
+ if( flags&MEM_Real ){
+ return 7;
+ }
+ if( flags&MEM_Str ){
+ int n = pMem->n;
+ assert( n>=0 );
+ return ((n*2) + 13);
+ }
+ if( flags&MEM_Blob ){
+ return (pMem->n*2 + 12);
+ }
+ return 0;
+}
+
+/*
+** Return the length of the data corresponding to the supplied serial-type.
+*/
+int sqlite3VdbeSerialTypeLen(u32 serial_type){
+ if( serial_type>=12 ){
+ return (serial_type-12)/2;
+ }else{
+ static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
+ return aSize[serial_type];
+ }
+}
+
+/*
+** Write the serialized data blob for the value stored in pMem into
+** buf. It is assumed that the caller has allocated sufficient space.
+** Return the number of bytes written.
+*/
+int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
+ u32 serial_type = sqlite3VdbeSerialType(pMem);
+ int len;
+
+ /* NULL */
+ if( serial_type==0 ){
+ return 0;
+ }
+
+ /* Integer and Real */
+ if( serial_type<=7 ){
+ u64 v;
+ int i;
+ if( serial_type==7 ){
+ v = *(u64*)&pMem->r;
+ }else{
+ v = *(u64*)&pMem->i;
+ }
+ len = i = sqlite3VdbeSerialTypeLen(serial_type);
+ while( i-- ){
+ buf[i] = (v&0xFF);
+ v >>= 8;
+ }
+ return len;
+ }
+
+ /* String or blob */
+ assert( serial_type>=12 );
+ len = sqlite3VdbeSerialTypeLen(serial_type);
+ memcpy(buf, pMem->z, len);
+ return len;
+}
+
+/*
+** Deserialize the data blob pointed to by buf as serial type serial_type
+** and store the result in pMem. Return the number of bytes read.
+*/
+int sqlite3VdbeSerialGet(
+ const unsigned char *buf, /* Buffer to deserialize from */
+ u32 serial_type, /* Serial type to deserialize */
+ Mem *pMem /* Memory cell to write value into */
+){
+ switch( serial_type ){
+ case 8: /* Reserved for future use */
+ case 9: /* Reserved for future use */
+ case 10: /* Reserved for future use */
+ case 11: /* Reserved for future use */
+ case 0: { /* NULL */
+ pMem->flags = MEM_Null;
+ break;
+ }
+ case 1: { /* 1-byte signed integer */
+ pMem->i = (signed char)buf[0];
+ pMem->flags = MEM_Int;
+ return 1;
+ }
+ case 2: { /* 2-byte signed integer */
+ pMem->i = (((signed char)buf[0])<<8) | buf[1];
+ pMem->flags = MEM_Int;
+ return 2;
+ }
+ case 3: { /* 3-byte signed integer */
+ pMem->i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
+ pMem->flags = MEM_Int;
+ return 3;
+ }
+ case 4: { /* 4-byte signed integer */
+ pMem->i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
+ pMem->flags = MEM_Int;
+ return 4;
+ }
+ case 5: { /* 6-byte signed integer */
+ u64 x = (((signed char)buf[0])<<8) | buf[1];
+ u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
+ x = (x<<32) | y;
+ pMem->i = *(i64*)&x;
+ pMem->flags = MEM_Int;
+ return 6;
+ }
+ case 6: /* 6-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];
+ x = (x<<32) | y;
+ if( serial_type==6 ){
+ pMem->i = *(i64*)&x;
+ pMem->flags = MEM_Int;
+ }else{
+ pMem->r = *(double*)&x;
+ pMem->flags = MEM_Real;
+ }
+ return 8;
+ }
+ default: {
+ int len = (serial_type-12)/2;
+ pMem->z = (char *)buf;
+ pMem->n = len;
+ pMem->xDel = 0;
+ if( serial_type&0x01 ){
+ pMem->flags = MEM_Str | MEM_Ephem;
+ }else{
+ pMem->flags = MEM_Blob | MEM_Ephem;
+ }
+ return len;
+ }
+ }
+ return 0;
+}
+
+/*
+** This function compares the two table rows or index records specified by
+** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
+** or positive integer if {nKey1, pKey1} is less than, equal to or
+** greater than {nKey2, pKey2}. Both Key1 and Key2 must be byte strings
+** composed by the OP_MakeRecord opcode of the VDBE.
+*/
+int sqlite3VdbeRecordCompare(
+ void *userData,
+ int nKey1, const void *pKey1,
+ int nKey2, const void *pKey2
+){
+ KeyInfo *pKeyInfo = (KeyInfo*)userData;
+ u32 d1, d2; /* Offset into aKey[] of next data element */
+ u32 idx1, idx2; /* Offset into aKey[] of next header element */
+ u32 szHdr1, szHdr2; /* Number of bytes in header */
+ int i = 0;
+ int nField;
+ int rc = 0;
+ const unsigned char *aKey1 = (const unsigned char *)pKey1;
+ const unsigned char *aKey2 = (const unsigned char *)pKey2;
+
+ Mem mem1;
+ Mem mem2;
+ mem1.enc = pKeyInfo->enc;
+ mem2.enc = pKeyInfo->enc;
+
+ idx1 = sqlite3GetVarint32(pKey1, &szHdr1);
+ d1 = szHdr1;
+ idx2 = sqlite3GetVarint32(pKey2, &szHdr2);
+ d2 = szHdr2;
+ nField = pKeyInfo->nField;
+ while( idx1<szHdr1 && idx2<szHdr2 ){
+ u32 serial_type1;
+ u32 serial_type2;
+
+ /* Read the serial types for the next element in each key. */
+ idx1 += sqlite3GetVarint32(&aKey1[idx1], &serial_type1);
+ if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
+ idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);
+ if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
+
+ /* Assert that there is enough space left in each key for the blob of
+ ** data to go with the serial type just read. This assert may fail if
+ ** the file is corrupted. Then read the value from each key into mem1
+ ** and mem2 respectively.
+ */
+ d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
+ d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
+
+ rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
+ if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
+ if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
+ if( rc!=0 ){
+ break;
+ }
+ i++;
+ }
+
+ /* One of the keys ran out of fields, but all the fields up to that point
+ ** were equal. If the incrKey flag is true, then the second key is
+ ** treated as larger.
+ */
+ if( rc==0 ){
+ if( pKeyInfo->incrKey ){
+ rc = -1;
+ }else if( d1<nKey1 ){
+ rc = 1;
+ }else if( d2<nKey2 ){
+ rc = -1;
+ }
+ }
+
+ if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){
+ rc = -rc;
+ }
+
+ return rc;
+}
+
+/*
+** The argument is an index entry composed using the OP_MakeRecord opcode.
+** The last entry in this record should be an integer (specifically
+** an integer rowid). This routine returns the number of bytes in
+** that integer.
+*/
+int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){
+ u32 szHdr; /* Size of the header */
+ u32 typeRowid; /* Serial type of the rowid */
+
+ sqlite3GetVarint32(aKey, &szHdr);
+ sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid);
+ return sqlite3VdbeSerialTypeLen(typeRowid);
+}
+
+
+/*
+** pCur points at an index entry created using the OP_MakeRecord opcode.
+** Read the rowid (the last field in the record) and store it in *rowid.
+** Return SQLITE_OK if everything works, or an error code otherwise.
+*/
+int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
+ i64 nCellKey;
+ int rc;
+ u32 szHdr; /* Size of the header */
+ u32 typeRowid; /* Serial type of the rowid */
+ u32 lenRowid; /* Size of the rowid */
+ Mem m, v;
+
+ sqlite3BtreeKeySize(pCur, &nCellKey);
+ if( nCellKey<=0 ){
+ return SQLITE_CORRUPT;
+ }
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
+ if( rc ){
+ return rc;
+ }
+ sqlite3GetVarint32(m.z, &szHdr);
+ sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid);
+ lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
+ sqlite3VdbeSerialGet(&m.z[m.n-lenRowid], typeRowid, &v);
+ *rowid = v.i;
+ sqlite3VdbeMemRelease(&m);
+ return SQLITE_OK;
+}
+
+/*
+** Compare the key of the index entry that cursor pC is point to against
+** the key string in pKey (of length nKey). Write into *pRes a number
+** that is negative, zero, or positive if pC is less than, equal to,
+** or greater than pKey. Return SQLITE_OK on success.
+**
+** pKey is either created without a rowid or is truncated so that it
+** omits the rowid at the end. The rowid at the end of the index entry
+** is ignored as well.
+*/
+int sqlite3VdbeIdxKeyCompare(
+ Cursor *pC, /* The cursor to compare against */
+ int nKey, const u8 *pKey, /* The key to compare */
+ int *res /* Write the comparison result here */
+){
+ i64 nCellKey;
+ int rc;
+ BtCursor *pCur = pC->pCursor;
+ int lenRowid;
+ Mem m;
+
+ sqlite3BtreeKeySize(pCur, &nCellKey);
+ if( nCellKey<=0 ){
+ *res = 0;
+ return SQLITE_OK;
+ }
+ rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
+ if( rc ){
+ return rc;
+ }
+ lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z);
+ *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
+ sqlite3VdbeMemRelease(&m);
+ return SQLITE_OK;
+}
+
+/*
+** This routine sets the value to be returned by subsequent calls to
+** sqlite3_changes() on the database handle 'db'.
+*/
+void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
+ db->nChange = nChange;
+ db->nTotalChange += nChange;
+}
+
+/*
+** Set a flag in the vdbe to update the change counter when it is finalised
+** or reset.
+*/
+void sqlite3VdbeCountChanges(Vdbe *v){
+ v->changeCntOn = 1;
+}
+
+/*
+** Mark every prepared statement associated with a database connection
+** as expired.
+**
+** An expired statement means that recompilation of the statement is
+** recommend. Statements expire when things happen that make their
+** programs obsolete. Removing user-defined functions or collating
+** sequences, or changing an authorization function are the types of
+** things that make prepared statements obsolete.
+*/
+void sqlite3ExpirePreparedStatements(sqlite3 *db){
+ Vdbe *p;
+ for(p = db->pVdbe; p; p=p->pNext){
+ p->expired = 1;
+ }
+}
+
+/*
+** Return the database associated with the Vdbe.
+*/
+sqlite3 *sqlite3VdbeDb(Vdbe *v){
+ return v->db;
+}
diff --git a/src/sqlite/vdbemem.c b/src/sqlite/vdbemem.c
new file mode 100644
index 0000000..f08671f
--- /dev/null
+++ b/src/sqlite/vdbemem.c
@@ -0,0 +1,806 @@
+/*
+** 2004 May 26
+**
+** 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 use to manipulate "Mem" structure. A "Mem"
+** stores a single value in the VDBE. Mem is an opaque structure visible
+** only within the VDBE. Interface routines refer to a Mem using the
+** name sqlite_value
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include "vdbeInt.h"
+
+/*
+** If pMem is an object with a valid string representation, this routine
+** ensures the internal encoding for the string representation is
+** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
+**
+** If pMem is not a string object, or the encoding of the string
+** representation is already stored using the requested encoding, then this
+** routine is a no-op.
+**
+** SQLITE_OK is returned if the conversion is successful (or not required).
+** SQLITE_NOMEM may be returned if a malloc() fails during conversion
+** between formats.
+*/
+int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
+ int rc;
+ if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
+ return SQLITE_OK;
+ }
+#ifdef SQLITE_OMIT_UTF16
+ return SQLITE_ERROR;
+#else
+ rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);
+ if( rc==SQLITE_NOMEM ){
+ sqlite3VdbeMemRelease(pMem);
+ pMem->flags = MEM_Null;
+ pMem->z = 0;
+ }
+ return rc;
+#endif
+}
+
+/*
+** Make the given Mem object MEM_Dyn.
+**
+** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
+*/
+int sqlite3VdbeMemDynamicify(Mem *pMem){
+ int n = pMem->n;
+ u8 *z;
+ if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
+ return SQLITE_OK;
+ }
+ assert( (pMem->flags & MEM_Dyn)==0 );
+ assert( pMem->flags & (MEM_Str|MEM_Blob) );
+ z = sqliteMallocRaw( n+2 );
+ if( z==0 ){
+ return SQLITE_NOMEM;
+ }
+ pMem->flags |= MEM_Dyn|MEM_Term;
+ pMem->xDel = 0;
+ memcpy(z, pMem->z, n );
+ z[n] = 0;
+ z[n+1] = 0;
+ pMem->z = z;
+ pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
+ return SQLITE_OK;
+}
+
+/*
+** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes
+** of the Mem.z[] array can be modified.
+**
+** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
+*/
+int sqlite3VdbeMemMakeWriteable(Mem *pMem){
+ int n;
+ u8 *z;
+ if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
+ return SQLITE_OK;
+ }
+ assert( (pMem->flags & MEM_Dyn)==0 );
+ assert( pMem->flags & (MEM_Str|MEM_Blob) );
+ if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
+ z = pMem->zShort;
+ pMem->flags |= MEM_Short|MEM_Term;
+ }else{
+ z = sqliteMallocRaw( n+2 );
+ if( z==0 ){
+ return SQLITE_NOMEM;
+ }
+ pMem->flags |= MEM_Dyn|MEM_Term;
+ pMem->xDel = 0;
+ }
+ memcpy(z, pMem->z, n );
+ z[n] = 0;
+ z[n+1] = 0;
+ pMem->z = z;
+ pMem->flags &= ~(MEM_Ephem|MEM_Static);
+ return SQLITE_OK;
+}
+
+/*
+** Make sure the given Mem is \u0000 terminated.
+*/
+int sqlite3VdbeMemNulTerminate(Mem *pMem){
+ /* In SQLite, a string without a nul terminator occurs when a string
+ ** is loaded from disk (in this case the memory management is ephemeral),
+ ** or when it is supplied by the user as a bound variable or function
+ ** return value. Therefore, the memory management of the string must be
+ ** either ephemeral, static or controlled by a user-supplied destructor.
+ */
+ assert(
+ !(pMem->flags&MEM_Str) || /* it's not a string, or */
+ (pMem->flags&MEM_Term) || /* it's nul term. already, or */
+ (pMem->flags&(MEM_Ephem|MEM_Static)) || /* it's static or ephem, or */
+ (pMem->flags&MEM_Dyn && pMem->xDel) /* external management */
+ );
+ if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
+ return SQLITE_OK; /* Nothing to do */
+ }
+
+ if( pMem->flags & (MEM_Static|MEM_Ephem) ){
+ return sqlite3VdbeMemMakeWriteable(pMem);
+ }else{
+ char *z = sqliteMalloc(pMem->n+2);
+ if( !z ) return SQLITE_NOMEM;
+ memcpy(z, pMem->z, pMem->n);
+ z[pMem->n] = 0;
+ z[pMem->n+1] = 0;
+ pMem->xDel(pMem->z);
+ pMem->xDel = 0;
+ pMem->z = z;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Add MEM_Str to the set of representations for the given Mem. Numbers
+** are converted using sqlite3_snprintf(). Converting a BLOB to a string
+** is a no-op.
+**
+** Existing representations MEM_Int and MEM_Real are *not* invalidated.
+**
+** A MEM_Null value will never be passed to this function. This function is
+** used for converting values to text for returning to the user (i.e. via
+** sqlite3_value_text()), or for ensuring that values to be used as btree
+** keys are strings. In the former case a NULL pointer is returned the
+** user and the later is an internal programming error.
+*/
+int sqlite3VdbeMemStringify(Mem *pMem, int enc){
+ int rc = SQLITE_OK;
+ int fg = pMem->flags;
+ u8 *z = pMem->zShort;
+
+ assert( !(fg&(MEM_Str|MEM_Blob)) );
+ assert( fg&(MEM_Int|MEM_Real) );
+
+ /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
+ ** string representation of the value. Then, if the required encoding
+ ** is UTF-16le or UTF-16be do a translation.
+ **
+ ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
+ */
+ if( fg & MEM_Real ){
+ sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
+ }else{
+ assert( fg & MEM_Int );
+ sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
+ }
+ pMem->n = strlen(z);
+ pMem->z = z;
+ pMem->enc = SQLITE_UTF8;
+ pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
+ sqlite3VdbeChangeEncoding(pMem, enc);
+ return rc;
+}
+
+/*
+** Release any memory held by the Mem. This may leave the Mem in an
+** inconsistent state, for example with (Mem.z==0) and
+** (Mem.type==SQLITE_TEXT).
+*/
+void sqlite3VdbeMemRelease(Mem *p){
+ if( p->flags & MEM_Dyn ){
+ if( p->xDel ){
+ p->xDel((void *)p->z);
+ }else{
+ sqliteFree(p->z);
+ }
+ p->z = 0;
+ p->xDel = 0;
+ }
+}
+
+/*
+** Return some kind of integer value which is the best we can do
+** at representing the value that *pMem describes as an integer.
+** If pMem is an integer, then the value is exact. If pMem is
+** a floating-point then the value returned is the integer part.
+** If pMem is a string or blob, then we make an attempt to convert
+** it into a integer and return that. If pMem is NULL, return 0.
+**
+** If pMem is a string, its encoding might be changed.
+*/
+i64 sqlite3VdbeIntValue(Mem *pMem){
+ int flags = pMem->flags;
+ if( flags & MEM_Int ){
+ return pMem->i;
+ }else if( flags & MEM_Real ){
+ return (i64)pMem->r;
+ }else if( flags & (MEM_Str|MEM_Blob) ){
+ i64 value;
+ if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
+ || sqlite3VdbeMemNulTerminate(pMem) ){
+ return SQLITE_NOMEM;
+ }
+ assert( pMem->z );
+ sqlite3atoi64(pMem->z, &value);
+ return value;
+ }else{
+ return 0;
+ }
+}
+
+/*
+** Convert pMem to type integer. Invalidate any prior representations.
+*/
+int sqlite3VdbeMemIntegerify(Mem *pMem){
+ pMem->i = sqlite3VdbeIntValue(pMem);
+ sqlite3VdbeMemRelease(pMem);
+ pMem->flags = MEM_Int;
+ return SQLITE_OK;
+}
+
+/*
+** Return the best representation of pMem that we can get into a
+** double. If pMem is already a double or an integer, return its
+** value. If it is a string or blob, try to convert it to a double.
+** If it is a NULL, return 0.0.
+*/
+double sqlite3VdbeRealValue(Mem *pMem){
+ if( pMem->flags & MEM_Real ){
+ return pMem->r;
+ }else if( pMem->flags & MEM_Int ){
+ return (double)pMem->i;
+ }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
+ if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
+ || sqlite3VdbeMemNulTerminate(pMem) ){
+ return SQLITE_NOMEM;
+ }
+ assert( pMem->z );
+ return sqlite3AtoF(pMem->z, 0);
+ }else{
+ return 0.0;
+ }
+}
+
+/*
+** Convert pMem so that it is of type MEM_Real. Invalidate any
+** prior representations.
+*/
+int sqlite3VdbeMemRealify(Mem *pMem){
+ pMem->r = sqlite3VdbeRealValue(pMem);
+ sqlite3VdbeMemRelease(pMem);
+ pMem->flags = MEM_Real;
+ return SQLITE_OK;
+}
+
+/*
+** Delete any previous value and set the value stored in *pMem to NULL.
+*/
+void sqlite3VdbeMemSetNull(Mem *pMem){
+ sqlite3VdbeMemRelease(pMem);
+ pMem->flags = MEM_Null;
+ pMem->type = SQLITE_NULL;
+}
+
+/*
+** Delete any previous value and set the value stored in *pMem to val,
+** manifest type INTEGER.
+*/
+void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
+ sqlite3VdbeMemRelease(pMem);
+ pMem->i = val;
+ pMem->flags = MEM_Int;
+ pMem->type = SQLITE_INTEGER;
+}
+
+/*
+** Delete any previous value and set the value stored in *pMem to val,
+** manifest type REAL.
+*/
+void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
+ sqlite3VdbeMemRelease(pMem);
+ pMem->r = val;
+ pMem->flags = MEM_Real;
+ pMem->type = SQLITE_FLOAT;
+}
+
+/*
+** Make an shallow copy of pFrom into pTo. Prior contents of
+** pTo are overwritten. The pFrom->z field is not duplicated. If
+** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
+** and flags gets srcType (either MEM_Ephem or MEM_Static).
+*/
+void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
+ memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort));
+ pTo->xDel = 0;
+ if( pTo->flags & (MEM_Str|MEM_Blob) ){
+ pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem);
+ assert( srcType==MEM_Ephem || srcType==MEM_Static );
+ pTo->flags |= srcType;
+ }
+}
+
+/*
+** Make a full copy of pFrom into pTo. Prior contents of pTo are
+** freed before the copy is made.
+*/
+int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
+ int rc;
+ if( pTo->flags & MEM_Dyn ){
+ sqlite3VdbeMemRelease(pTo);
+ }
+ sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
+ if( pTo->flags & MEM_Ephem ){
+ rc = sqlite3VdbeMemMakeWriteable(pTo);
+ }else{
+ rc = SQLITE_OK;
+ }
+ return rc;
+}
+
+/*
+** Transfer the contents of pFrom to pTo. Any existing value in pTo is
+** freed. If pFrom contains ephemeral data, a copy is made.
+**
+** pFrom contains an SQL NULL when this routine returns. SQLITE_NOMEM
+** might be returned if pFrom held ephemeral data and we were unable
+** to allocate enough space to make a copy.
+*/
+int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
+ int rc;
+ if( pTo->flags & MEM_Dyn ){
+ sqlite3VdbeMemRelease(pTo);
+ }
+ memcpy(pTo, pFrom, sizeof(Mem));
+ if( pFrom->flags & MEM_Short ){
+ pTo->z = pTo->zShort;
+ }
+ pFrom->flags = MEM_Null;
+ pFrom->xDel = 0;
+ if( pTo->flags & MEM_Ephem ){
+ rc = sqlite3VdbeMemMakeWriteable(pTo);
+ }else{
+ rc = SQLITE_OK;
+ }
+ return rc;
+}
+
+/*
+** Change the value of a Mem to be a string or a BLOB.
+*/
+int sqlite3VdbeMemSetStr(
+ Mem *pMem, /* Memory cell to set to string value */
+ const char *z, /* String pointer */
+ int n, /* Bytes in string, or negative */
+ u8 enc, /* Encoding of z. 0 for BLOBs */
+ void (*xDel)(void*) /* Destructor function */
+){
+ sqlite3VdbeMemRelease(pMem);
+ if( !z ){
+ pMem->flags = MEM_Null;
+ pMem->type = SQLITE_NULL;
+ return SQLITE_OK;
+ }
+
+ pMem->z = (char *)z;
+ if( xDel==SQLITE_STATIC ){
+ pMem->flags = MEM_Static;
+ }else if( xDel==SQLITE_TRANSIENT ){
+ pMem->flags = MEM_Ephem;
+ }else{
+ pMem->flags = MEM_Dyn;
+ pMem->xDel = xDel;
+ }
+
+ pMem->enc = enc;
+ pMem->type = enc==0 ? SQLITE_BLOB : SQLITE_TEXT;
+ pMem->n = n;
+
+ assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE
+ || enc==SQLITE_UTF16BE );
+ switch( enc ){
+ case 0:
+ pMem->flags |= MEM_Blob;
+ break;
+
+ case SQLITE_UTF8:
+ pMem->flags |= MEM_Str;
+ if( n<0 ){
+ pMem->n = strlen(z);
+ pMem->flags |= MEM_Term;
+ }
+ break;
+
+#ifndef SQLITE_OMIT_UTF16
+ case SQLITE_UTF16LE:
+ case SQLITE_UTF16BE:
+ pMem->flags |= MEM_Str;
+ if( pMem->n<0 ){
+ pMem->n = sqlite3utf16ByteLen(pMem->z,-1);
+ pMem->flags |= MEM_Term;
+ }
+ if( sqlite3VdbeMemHandleBom(pMem) ){
+ return SQLITE_NOMEM;
+ }
+#endif /* SQLITE_OMIT_UTF16 */
+ }
+ if( pMem->flags&MEM_Ephem ){
+ return sqlite3VdbeMemMakeWriteable(pMem);
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Compare the values contained by the two memory cells, returning
+** negative, zero or positive if pMem1 is less than, equal to, or greater
+** than pMem2. Sorting order is NULL's first, followed by numbers (integers
+** and reals) sorted numerically, followed by text ordered by the collating
+** sequence pColl and finally blob's ordered by memcmp().
+**
+** Two NULL values are considered equal by this function.
+*/
+int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
+ int rc;
+ int f1, f2;
+ int combined_flags;
+
+ /* Interchange pMem1 and pMem2 if the collating sequence specifies
+ ** DESC order.
+ */
+ f1 = pMem1->flags;
+ f2 = pMem2->flags;
+ combined_flags = f1|f2;
+
+ /* If one value is NULL, it is less than the other. If both values
+ ** are NULL, return 0.
+ */
+ if( combined_flags&MEM_Null ){
+ return (f2&MEM_Null) - (f1&MEM_Null);
+ }
+
+ /* If one value is a number and the other is not, the number is less.
+ ** If both are numbers, compare as reals if one is a real, or as integers
+ ** if both values are integers.
+ */
+ if( combined_flags&(MEM_Int|MEM_Real) ){
+ if( !(f1&(MEM_Int|MEM_Real)) ){
+ return 1;
+ }
+ if( !(f2&(MEM_Int|MEM_Real)) ){
+ return -1;
+ }
+ if( (f1 & f2 & MEM_Int)==0 ){
+ double r1, r2;
+ if( (f1&MEM_Real)==0 ){
+ r1 = pMem1->i;
+ }else{
+ r1 = pMem1->r;
+ }
+ if( (f2&MEM_Real)==0 ){
+ r2 = pMem2->i;
+ }else{
+ r2 = pMem2->r;
+ }
+ if( r1<r2 ) return -1;
+ if( r1>r2 ) return 1;
+ return 0;
+ }else{
+ assert( f1&MEM_Int );
+ assert( f2&MEM_Int );
+ if( pMem1->i < pMem2->i ) return -1;
+ if( pMem1->i > pMem2->i ) return 1;
+ return 0;
+ }
+ }
+
+ /* If one value is a string and the other is a blob, the string is less.
+ ** If both are strings, compare using the collating functions.
+ */
+ if( combined_flags&MEM_Str ){
+ if( (f1 & MEM_Str)==0 ){
+ return 1;
+ }
+ if( (f2 & MEM_Str)==0 ){
+ return -1;
+ }
+
+ assert( pMem1->enc==pMem2->enc );
+ assert( pMem1->enc==SQLITE_UTF8 ||
+ pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
+
+ /* This assert may fail if the collation sequence is deleted after this
+ ** vdbe program is compiled. The documentation defines this as an
+ ** undefined condition. A crash is usual result.
+ */
+ assert( !pColl || pColl->xCmp );
+
+ if( pColl ){
+ if( pMem1->enc==pColl->enc ){
+ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
+ }else{
+ u8 origEnc = pMem1->enc;
+ rc = pColl->xCmp(
+ pColl->pUser,
+ sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc),
+ sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc),
+ sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc),
+ sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc)
+ );
+ sqlite3ValueBytes((sqlite3_value*)pMem1, origEnc);
+ sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
+ sqlite3ValueBytes((sqlite3_value*)pMem2, origEnc);
+ sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
+ return rc;
+ }
+ }
+ /* If a NULL pointer was passed as the collate function, fall through
+ ** to the blob case and use memcmp(). */
+ }
+
+ /* Both values must be blobs. Compare using memcmp(). */
+ rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
+ if( rc==0 ){
+ rc = pMem1->n - pMem2->n;
+ }
+ return rc;
+}
+
+/*
+** Move data out of a btree key or data field and into a Mem structure.
+** The data or key is taken from the entry that pCur is currently pointing
+** to. offset and amt determine what portion of the data or key to retrieve.
+** key is true to get the key or false to get data. The result is written
+** into the pMem element.
+**
+** The pMem structure is assumed to be uninitialized. Any prior content
+** is overwritten without being freed.
+**
+** If this routine fails for any reason (malloc returns NULL or unable
+** to read from the disk) then the pMem is left in an inconsistent state.
+*/
+int sqlite3VdbeMemFromBtree(
+ BtCursor *pCur, /* Cursor pointing at record to retrieve. */
+ int offset, /* Offset from the start of data to return bytes from. */
+ int amt, /* Number of bytes to return. */
+ int key, /* If true, retrieve from the btree key, not data. */
+ Mem *pMem /* OUT: Return data in this Mem structure. */
+){
+ char *zData; /* Data from the btree layer */
+ int available; /* Number of bytes available on the local btree page */
+
+ if( key ){
+ zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
+ }else{
+ zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
+ }
+
+ pMem->n = amt;
+ if( offset+amt<=available ){
+ pMem->z = &zData[offset];
+ pMem->flags = MEM_Blob|MEM_Ephem;
+ }else{
+ int rc;
+ if( amt>NBFS-2 ){
+ zData = (char *)sqliteMallocRaw(amt+2);
+ if( !zData ){
+ return SQLITE_NOMEM;
+ }
+ pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
+ pMem->xDel = 0;
+ }else{
+ zData = &(pMem->zShort[0]);
+ pMem->flags = MEM_Blob|MEM_Short|MEM_Term;
+ }
+ pMem->z = zData;
+ pMem->enc = 0;
+ pMem->type = SQLITE_BLOB;
+
+ if( key ){
+ rc = sqlite3BtreeKey(pCur, offset, amt, zData);
+ }else{
+ rc = sqlite3BtreeData(pCur, offset, amt, zData);
+ }
+ zData[amt] = 0;
+ zData[amt+1] = 0;
+ if( rc!=SQLITE_OK ){
+ if( amt>NBFS-2 ){
+ assert( zData!=pMem->zShort );
+ assert( pMem->flags & MEM_Dyn );
+ sqliteFree(zData);
+ } else {
+ assert( zData==pMem->zShort );
+ assert( pMem->flags & MEM_Short );
+ }
+ return rc;
+ }
+ }
+
+ return SQLITE_OK;
+}
+
+#ifndef NDEBUG
+/*
+** Perform various checks on the memory cell pMem. An assert() will
+** fail if pMem is internally inconsistent.
+*/
+void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){
+ int flags = pMem->flags;
+ assert( flags!=0 ); /* Must define some type */
+ if( pMem->flags & (MEM_Str|MEM_Blob) ){
+ int x = pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
+ assert( x!=0 ); /* Strings must define a string subtype */
+ assert( (x & (x-1))==0 ); /* Only one string subtype can be defined */
+ assert( pMem->z!=0 ); /* Strings must have a value */
+ /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
+ assert( (pMem->flags & MEM_Short)==0 || pMem->z==pMem->zShort );
+ assert( (pMem->flags & MEM_Short)!=0 || pMem->z!=pMem->zShort );
+ /* No destructor unless there is MEM_Dyn */
+ assert( pMem->xDel==0 || (pMem->flags & MEM_Dyn)!=0 );
+
+ if( (flags & MEM_Str) ){
+ assert( pMem->enc==SQLITE_UTF8 ||
+ pMem->enc==SQLITE_UTF16BE ||
+ pMem->enc==SQLITE_UTF16LE
+ );
+ /* If the string is UTF-8 encoded and nul terminated, then pMem->n
+ ** must be the length of the string. (Later:) If the database file
+ ** has been corrupted, '\000' characters might have been inserted
+ ** into the middle of the string. In that case, the strlen() might
+ ** be less.
+ */
+ if( pMem->enc==SQLITE_UTF8 && (flags & MEM_Term) ){
+ assert( strlen(pMem->z)<=pMem->n );
+ assert( pMem->z[pMem->n]==0 );
+ }
+ }
+ }else{
+ /* Cannot define a string subtype for non-string objects */
+ assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
+ assert( pMem->xDel==0 );
+ }
+ /* 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 );
+ }
+}
+#endif
+
+/* This function is only available internally, it is not part of the
+** external API. It works in a similar way to sqlite3_value_text(),
+** except the data returned is in the encoding specified by the second
+** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
+** SQLITE_UTF8.
+*/
+const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
+ if( !pVal ) return 0;
+ assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8);
+
+ if( pVal->flags&MEM_Null ){
+ return 0;
+ }
+ if( pVal->flags&MEM_Str ){
+ sqlite3VdbeChangeEncoding(pVal, enc);
+ }else if( !(pVal->flags&MEM_Blob) ){
+ sqlite3VdbeMemStringify(pVal, enc);
+ }
+ return (const void *)(pVal->z);
+}
+
+/*
+** Create a new sqlite3_value object.
+*/
+sqlite3_value* sqlite3ValueNew(){
+ Mem *p = sqliteMalloc(sizeof(*p));
+ if( p ){
+ p->flags = MEM_Null;
+ p->type = SQLITE_NULL;
+ }
+ return p;
+}
+
+/*
+** Create a new sqlite3_value object, containing the value of pExpr.
+**
+** This only works for very simple expressions that consist of one constant
+** token (i.e. "5", "5.1", "NULL", "'a string'"). If the expression can
+** be converted directly into a value, then the value is allocated and
+** a pointer written to *ppVal. The caller is responsible for deallocating
+** the value by passing it to sqlite3ValueFree() later on. If the expression
+** cannot be converted to a value, then *ppVal is set to NULL.
+*/
+int sqlite3ValueFromExpr(
+ Expr *pExpr,
+ u8 enc,
+ u8 affinity,
+ sqlite3_value **ppVal
+){
+ int op;
+ char *zVal = 0;
+ sqlite3_value *pVal = 0;
+
+ if( !pExpr ){
+ *ppVal = 0;
+ return SQLITE_OK;
+ }
+ op = pExpr->op;
+
+ if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
+ zVal = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
+ pVal = sqlite3ValueNew();
+ if( !zVal || !pVal ) goto no_mem;
+ sqlite3Dequote(zVal);
+ sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, sqlite3FreeX);
+ if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
+ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);
+ }else{
+ sqlite3ValueApplyAffinity(pVal, affinity, enc);
+ }
+ }else if( op==TK_UMINUS ) {
+ if( SQLITE_OK==sqlite3ValueFromExpr(pExpr->pLeft, enc, affinity, &pVal) ){
+ pVal->i = -1 * pVal->i;
+ pVal->r = -1.0 * pVal->r;
+ }
+ }
+#ifndef SQLITE_OMIT_BLOB_LITERAL
+ else if( op==TK_BLOB ){
+ int nVal;
+ pVal = sqlite3ValueNew();
+ zVal = sqliteStrNDup(pExpr->token.z+1, pExpr->token.n-1);
+ if( !zVal || !pVal ) goto no_mem;
+ sqlite3Dequote(zVal);
+ nVal = strlen(zVal)/2;
+ sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(zVal), nVal, 0, sqlite3FreeX);
+ sqliteFree(zVal);
+ }
+#endif
+
+ *ppVal = pVal;
+ return SQLITE_OK;
+
+no_mem:
+ sqliteFree(zVal);
+ sqlite3ValueFree(pVal);
+ *ppVal = 0;
+ return SQLITE_NOMEM;
+}
+
+/*
+** Change the string value of an sqlite3_value object
+*/
+void sqlite3ValueSetStr(
+ sqlite3_value *v,
+ int n,
+ const void *z,
+ u8 enc,
+ void (*xDel)(void*)
+){
+ if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
+}
+
+/*
+** Free an sqlite3_value object
+*/
+void sqlite3ValueFree(sqlite3_value *v){
+ if( !v ) return;
+ sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
+ sqliteFree(v);
+}
+
+/*
+** Return the number of bytes in the sqlite3_value object assuming
+** that it uses the encoding "enc"
+*/
+int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
+ Mem *p = (Mem*)pVal;
+ if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
+ return p->n;
+ }
+ return 0;
+}
diff --git a/src/sqlite/where.c b/src/sqlite/where.c
new file mode 100644
index 0000000..a6cf2e7
--- /dev/null
+++ b/src/sqlite/where.c
@@ -0,0 +1,1439 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This module contains C code that generates VDBE code used to process
+** the WHERE clause of SQL statements. This module is reponsible for
+** generating the code that loops through a table looking for applicable
+** rows. Indices are selected and used to speed the search when doing
+** so is applicable. Because this module is responsible for selecting
+** indices, you might also think of this module as the "query optimizer".
+**
+** $Id: where.c,v 1.1.1.1 2006/02/03 20:35:19 hoganrobert Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** 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.
+**
+** 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.
+**
+** prereqLeft, 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
+** bits that will fit in a Bitmask. The VDBE cursor numbers might be
+** spread out over the non-negative integers. For example, the cursor
+** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The ExprMaskSet
+** translates these sparse cursor numbers into consecutive integers
+** 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:
+**
+** <column> <op> <expr>
+**
+** Where <column> is a simple column name and <op> 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 */
+ Bitmask prereqAll; /* Bitmask of tables referenced by p */
+};
+
+/*
+** An instance of the following structure keeps track of a mapping
+** between VDBE cursor numbers and bits of the bitmasks in ExprInfo.
+**
+** The VDBE cursor numbers are small integers contained in
+** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE
+** clause, the cursor numbers might not begin with 0 and they might
+** contain gaps in the numbering sequence. But we want to make maximum
+** use of the bits in our bitmasks. This structure provides a mapping
+** from the sparse cursor numbers into consecutive integers beginning
+** with 0.
+**
+** If ExprMaskSet.ix[A]==B it means that The A-th bit of a Bitmask
+** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<<A.
+**
+** For example, if the WHERE clause expression used these VDBE
+** cursors: 4, 5, 8, 29, 57, 73. Then the ExprMaskSet structure
+** would map those cursor numbers into bits 0 through 5.
+**
+** Note that the mapping is not necessarily ordered. In the example
+** above, the mapping might go like this: 4->3, 5->1, 8->2, 29->0,
+** 57->5, 73->4. Or one of 719 other combinations might be used. It
+** does not really matter. What is important is that sparse cursor
+** numbers all get mapped into bit numbers that begin with 0 and contain
+** no gaps.
+*/
+typedef struct ExprMaskSet ExprMaskSet;
+struct ExprMaskSet {
+ int n; /* Number of assigned cursor values */
+ int ix[sizeof(Bitmask)*8]; /* Cursor assigned to each bit */
+};
+
+/*
+** Determine the number of elements in an array.
+*/
+#define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0]))
+
+/*
+** 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:
+**
+** 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.
+**
+** 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.
+*/
+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);
+ }else{
+ cnt = exprSplit(nSlot, aSlot, pExpr->pLeft);
+ cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight);
+ }
+ return cnt;
+}
+
+/*
+** Initialize an expression mask set
+*/
+#define initMaskSet(P) memset(P, 0, sizeof(*P))
+
+/*
+** Return the bitmask for the given cursor number. Return 0 if
+** iCursor is not in the set.
+*/
+static Bitmask getMask(ExprMaskSet *pMaskSet, int iCursor){
+ int i;
+ for(i=0; i<pMaskSet->n; i++){
+ if( pMaskSet->ix[i]==iCursor ){
+ return ((Bitmask)1)<<i;
+ }
+ }
+ return 0;
+}
+
+/*
+** Create a new mask for cursor iCursor.
+*/
+static void createMask(ExprMaskSet *pMaskSet, int iCursor){
+ if( 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
+** tree.
+**
+** In order for this routine to work, the calling function must have
+** previously invoked sqlite3ExprResolveNames() on the expression. See
+** 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.
+*/
+static Bitmask exprListTableUsage(ExprMaskSet *, ExprList *);
+static Bitmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
+ Bitmask mask = 0;
+ if( p==0 ) return 0;
+ if( p->op==TK_COLUMN ){
+ mask = getMask(pMaskSet, p->iTable);
+ return mask;
+ }
+ mask = exprTableUsage(pMaskSet, p->pRight);
+ mask |= exprTableUsage(pMaskSet, p->pLeft);
+ mask |= exprListTableUsage(pMaskSet, p->pList);
+ if( p->pSelect ){
+ Select *pS = p->pSelect;
+ mask |= exprListTableUsage(pMaskSet, pS->pEList);
+ mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
+ mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
+ mask |= exprTableUsage(pMaskSet, pS->pWhere);
+ mask |= exprTableUsage(pMaskSet, pS->pHaving);
+ }
+ return mask;
+}
+static Bitmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){
+ int i;
+ Bitmask mask = 0;
+ if( pList ){
+ for(i=0; i<pList->nExpr; i++){
+ mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
+ }
+ }
+ return mask;
+}
+
+/*
+** Return TRUE if the given operator is one of the operators that is
+** allowed for an indexable WHERE clause term. The allowed operators are
+** "=", "<", ">", "<=", ">=", 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);
+ return op==TK_IN || (op>=TK_EQ && op<=TK_GE);
+}
+
+/*
+** Swap two objects of type T.
+*/
+#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.
+**
+** 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){
+ int i;
+ struct SrcList_item *pItem;
+ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
+ if( pItem->iCursor==iCur ) return i;
+ }
+ return -1;
+}
+
+/*
+** 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
+** structure.
+*/
+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;
+ }
+ if( pExpr->pLeft->op==TK_COLUMN ){
+ pInfo->idxLeft = pExpr->pLeft->iTable;
+ pInfo->indexable = 1;
+ }
+ }
+ 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)<tableOrder(pSrc,pInfo->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_GT<TK_LE );
+ assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
+ pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
+ }
+ SWAP(unsigned, pInfo->prereqLeft, pInfo->prereqRight);
+ SWAP(short int, pInfo->idxLeft, pInfo->idxRight);
+ }
+ }
+
+}
+
+/*
+** 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
+** ORDER BY clause, this routine returns 0.
+**
+** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the
+** left-most table in the FROM clause of that same SELECT statement and
+** the table has a cursor number of "base". pIdx is an index on pTab.
+**
+** nEqCol is the number of columns of pIdx that are used as equality
+** 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
+** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
+** the ORDER BY clause is all ASC.
+*/
+static int isSortingIndex(
+ Parse *pParse, /* Parsing context */
+ Index *pIdx, /* The index we are testing */
+ Table *pTab, /* The table to be sorted */
+ int base, /* Cursor number for pTab */
+ ExprList *pOrderBy, /* The ORDER BY clause */
+ int nEqCol, /* Number of index columns with == constraints */
+ int *pbRev /* Set to 1 if ORDER BY is DESC */
+){
+ int i, j; /* Loop counters */
+ int sortOrder; /* Which direction we are sorting */
+ int nTerm; /* Number of ORDER BY terms */
+ struct ExprList_item *pTerm; /* A term of the ORDER BY clause */
+ sqlite3 *db = pParse->db;
+
+ assert( pOrderBy!=0 );
+ nTerm = pOrderBy->nExpr;
+ assert( nTerm>0 );
+
+ /* Match terms of the ORDER BY clause against columns of
+ ** the index.
+ */
+ for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){
+ Expr *pExpr; /* The expression of the ORDER BY pTerm */
+ CollSeq *pColl; /* The collating sequence of pExpr */
+
+ pExpr = pTerm->pExpr;
+ if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
+ /* Can not use an index sort on anything that is not a column in the
+ ** left-most table of the FROM clause */
+ return 0;
+ }
+ pColl = sqlite3ExprCollSeq(pParse, pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ if( pExpr->iColumn!=pIdx->aiColumn[i] || pColl!=pIdx->keyInfo.aColl[i] ){
+ /* Term j of the ORDER BY clause does not match column i of the index */
+ if( i<nEqCol ){
+ /* If an index column that is constrained by == fails to match an
+ ** ORDER BY term, that is OK. Just ignore that column of the index
+ */
+ continue;
+ }else{
+ /* If an index column fails to match and is not constrained by ==
+ ** then the index cannot satisfy the ORDER BY constraint.
+ */
+ return 0;
+ }
+ }
+ if( i>nEqCol ){
+ if( pTerm->sortOrder!=sortOrder ){
+ /* Indices can only be used if all ORDER BY terms past the
+ ** equality constraints are all either DESC or ASC. */
+ return 0;
+ }
+ }else{
+ sortOrder = pTerm->sortOrder;
+ }
+ j++;
+ pTerm++;
+ }
+
+ /* 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.
+ */
+ if( j>=nTerm || (i>=pIdx->nColumn && pIdx->onError!=OE_None) ){
+ *pbRev = sortOrder==SQLITE_SO_DESC;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+** Check table to see if the ORDER BY clause in pOrderBy can be satisfied
+** by sorting in order of ROWID. Return true if so and set *pbRev to be
+** true for reverse ROWID and false for forward ROWID order.
+*/
+static int sortableByRowid(
+ int base, /* Cursor number for table to be sorted */
+ ExprList *pOrderBy, /* The ORDER BY clause */
+ int *pbRev /* Set to 1 if ORDER BY is DESC */
+){
+ Expr *p;
+
+ assert( pOrderBy!=0 );
+ assert( pOrderBy->nExpr>0 );
+ p = pOrderBy->a[0].pExpr;
+ if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 ){
+ *pbRev = pOrderBy->a[0].sortOrder;
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+** Disable a term in the WHERE clause. Except, do not disable the term
+** if it controls a LEFT OUTER JOIN and it did not originate in the ON
+** or USING clause of that join.
+**
+** Consider the term t2.z='ok' in the following queries:
+**
+** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
+** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
+** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
+**
+** The t2.z='ok' is disabled in the in (2) because it originates
+** in the ON clause. The term is disabled in (3) because it is not part
+** of a LEFT OUTER JOIN. In (1), the term is not disabled.
+**
+** Disabling a term causes that term to not be tested in the inner loop
+** of the join. Disabling is an optimization. We would get the correct
+** results if nothing were ever disabled, but joins might run a little
+** slower. The trick is to disable as much as we can without disabling
+** too much. If we disabled in (1), we'd get the wrong answer.
+** See ticket #813.
+*/
+static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
+ Expr *pExpr = *ppExpr;
+ if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
+ *ppExpr = 0;
+ }
+}
+
+/*
+** Generate code that builds a probe for an index. Details:
+**
+** * Check the top nColumn entries on the stack. If any
+** of those entries are NULL, jump immediately to brk,
+** which is the loop exit, since no index entry will match
+** if any part of the key is NULL.
+**
+** * Construct a probe entry from the top nColumn entries in
+** the stack with affinities appropriate for index pIdx.
+*/
+static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){
+ sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
+ sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
+ sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ 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.
+*/
+static void codeEqualityTerm(
+ Parse *pParse, /* The parsing context */
+ ExprInfo *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;
+ if( pX->op!=TK_IN ){
+ assert( pX->op==TK_EQ );
+ sqlite3ExprCode(pParse, pX->pRight);
+#ifndef SQLITE_OMIT_SUBQUERY
+ }else{
+ int iTab;
+ 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;
+#endif
+ }
+ disableTerm(pLevel, &pTerm->p);
+}
+
+/*
+** The number of bits in a Bitmask
+*/
+#define BMS (sizeof(Bitmask)*8-1)
+
+
+/*
+** Generate the beginning of the loop used for WHERE clause processing.
+** The return value is a pointer to an opaque structure that contains
+** information needed to terminate the loop. Later, the calling routine
+** should invoke sqlite3WhereEnd() with the return value of this function
+** in order to complete the WHERE clause processing.
+**
+** If an error occurs, this routine returns NULL.
+**
+** The basic idea is to do a nested loop, one loop for each table in
+** the FROM clause of a select. (INSERT and UPDATE statements are the
+** same as a SELECT with only a single table in the FROM clause.) For
+** example, if the SQL is this:
+**
+** SELECT * FROM t1, t2, t3 WHERE ...;
+**
+** Then the code generated is conceptually like the following:
+**
+** foreach row1 in t1 do \ Code generated
+** foreach row2 in t2 do |-- by sqlite3WhereBegin()
+** foreach row3 in t3 do /
+** ...
+** end \ Code generated
+** end |-- by sqlite3WhereEnd()
+** end /
+**
+** 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
+** and sqlite3WhereEnd() generates the code to close them.
+**
+** The code that sqlite3WhereBegin() generates leaves the cursors named
+** in pTabList pointing at their appropriate entries. The [...] code
+** can use OP_Column and OP_Rowid opcodes on these cursors to extract
+** data from the various tables of the loop.
+**
+** If the WHERE clause is empty, the foreach loops must each scan their
+** entire tables. Thus a three-way join is an O(N^3) operation. But if
+** the tables have indices and there are terms in the WHERE clause that
+** refer to those indices, a complete table scan can be avoided and the
+** code will run much faster. Most of the work of this routine is checking
+** to see if there are indices that can be used to speed up the loop.
+**
+** Terms of the WHERE clause are also used to limit which rows actually
+** make it to the "..." in the middle of the loop. After each "foreach",
+** terms of the WHERE clause that use only terms in that loop and outer
+** loops are evaluated and if false a jump is made around all subsequent
+** inner loops (or around the "..." if the test occurs within the inner-
+** most loop)
+**
+** OUTER JOINS
+**
+** An outer join of tables t1 and t2 is conceptally coded as follows:
+**
+** foreach row1 in t1 do
+** flag = 0
+** foreach row2 in t2 do
+** start:
+** ...
+** flag = 1
+** end
+** if flag==0 then
+** move the row2 cursor to a null row
+** goto start
+** fi
+** end
+**
+** ORDER BY CLAUSE PROCESSING
+**
+** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
+** if there is one. If there is no ORDER BY clause or if this routine
+** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
+**
+** If an index can be used so that the natural output order of the table
+** scan is correct for the ORDER BY clause, then that index is used and
+** *ppOrderBy is set to NULL. This is an optimization that prevents an
+** unnecessary sort of the result set if an index appropriate for the
+** ORDER BY clause already exists.
+**
+** If the where clause loops cannot be arranged to provide the correct
+** output order, then the *ppOrderBy is unchanged.
+*/
+WhereInfo *sqlite3WhereBegin(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* A list of all tables to be scanned */
+ Expr *pWhere, /* The WHERE clause */
+ ExprList **ppOrderBy /* An ORDER BY clause, or NULL */
+){
+ int i; /* Loop counter */
+ 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 ROWID<X or ROWID<=X */
+ int iDirectGt[BMS]; /* Term of the form ROWID>X or ROWID>=X */
+ ExprInfo aExpr[101]; /* 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 */
+
+ /* The number of terms 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);
+ 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.
+ */
+ 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;
+ }
+
+ /* 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;
+ }
+ pWInfo->pParse = pParse;
+ pWInfo->pTabList = pTabList;
+ pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
+
+ /* Special case: a WHERE clause that is constant. Evaluate the
+ ** expression and either jump over all of the code or fall thru.
+ */
+ if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstant(pWhere)) ){
+ sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
+ pWhere = 0;
+ }
+
+ /* Analyze all of the subexpressions.
+ */
+ for(i=0; i<pTabList->nSrc; i++){
+ createMask(&maskSet, pTabList->a[i].iCursor);
+ }
+ for(pTerm=aExpr, i=0; i<nExpr; i++, pTerm++){
+ exprAnalyze(pTabList, &maskSet, pTerm);
+ }
+
+ /* Figure out what index to use (if any) for each nested loop.
+ ** Make pWInfo->a[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.
+ **
+ ** 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.
+ **
+ ** 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.
+ */
+ loopMask = 0;
+ pTabItem = pTabList->a;
+ pLevel = pWInfo->a;
+ for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++,pTabItem++,pLevel++){
+ int j;
+ int iCur = pTabItem->iCursor; /* 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 ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.
+ ** For terms like ROWID>expr 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; j<nExpr; j++, pTerm++){
+ Expr *pX = pTerm->p;
+ 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 "<expr> 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; j<nExpr; j++, pTerm++){
+ Expr *pX = pTerm->p;
+ 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; k<pIdx->nColumn; 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)<<k;
+ break;
+ }
+ case TK_LE:
+ case TK_LT: {
+ ltMask |= ((Bitmask)1)<<k;
+ break;
+ }
+ case TK_GE:
+ case TK_GT: {
+ gtMask |= ((Bitmask)1)<<k;
+ break;
+ }
+ default: {
+ /* CANT_HAPPEN */
+ assert( 0 );
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* The following loop ends with nEq set to the number of columns
+ ** on the left of the index with == constraints.
+ */
+ for(nEq=0; nEq<pIdx->nColumn; nEq++){
+ m = (((Bitmask)1)<<(nEq+1))-1;
+ if( (m & eqMask)!=m ) break;
+ }
+
+ /* Begin assemblying the score
+ */
+ score = nEq*32; /* Base score is 32 times number of == constraints */
+ m = ((Bitmask)1)<<nEq;
+ if( m & ltMask ) score+=4; /* Increase score for a < constraint */
+ if( m & gtMask ) score+=8; /* Increase score for a > 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;
+ }
+ }
+
+ /* Check to see if we can get away with using just the index without
+ ** ever reading the table. If that is the case, then add one bonus
+ ** point to the score.
+ */
+ if( score && pTabItem->colUsed < (((Bitmask)1)<<(BMS-1)) ){
+ for(m=0, j=0; j<pIdx->nColumn; j++){
+ int x = pIdx->aiColumn[j];
+ if( x<BMS-1 ){
+ m |= ((Bitmask)1)<<x;
+ }
+ }
+ if( (pTabItem->colUsed & 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;
+ }
+ }
+ pLevel->pIdx = pBestIdx;
+ pLevel->score = bestScore;
+ pLevel->bRev = bestRev;
+ loopMask |= mask;
+ if( pBestIdx ){
+ pLevel->iIdxCur = pParse->nTab++;
+ }
+ }
+
+ /* Check to see if the ORDER BY clause is or can be satisfied by the
+ ** use of an index on the first table.
+ */
+ 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;
+ }
+ }
+
+ /* Open all tables in the pTabList and any indices selected for
+ ** searching those tables.
+ */
+ sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
+ pLevel = pWInfo->a;
+ for(i=0, pTabItem=pTabList->a; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
+ Table *pTab;
+ Index *pIx;
+ int iIdxCur = pLevel->iIdxCur;
+
+ pTab = pTabItem->pTab;
+ if( pTab->isTransient || pTab->pSelect ) continue;
+ if( (pLevel->score & 1)==0 ){
+ sqlite3OpenTableForReading(v, pTabItem->iCursor, pTab);
+ }
+ pLevel->iTabCur = pTabItem->iCursor;
+ if( (pIx = pLevel->pIdx)!=0 ){
+ sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
+ sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
+ (char*)&pIx->keyInfo, P3_KEYINFO);
+ }
+ if( (pLevel->score & 1)!=0 ){
+ sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
+ }
+ sqlite3CodeVerifySchema(pParse, pTab->iDb);
+ }
+ pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
+
+ /* Generate the code to do the search
+ */
+ loopMask = 0;
+ pLevel = pWInfo->a;
+ pTabItem = pTabList->a;
+ for(i=0; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
+ int j, k;
+ 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 */
+
+ pIdx = pLevel->pIdx;
+ iIdxCur = pLevel->iIdxCur;
+ pLevel->inOp = OP_Noop;
+
+ /* Check to see if it is appropriate to omit the use of the table
+ ** here and use its index instead.
+ */
+ omitTable = (pLevel->score&1)!=0;
+
+ /* 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( !pParse->nMem ) pParse->nMem++;
+ pLevel->iLeftJoin = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
+ VdbeComment((v, "# init LEFT JOIN no-match flag"));
+ }
+
+ if( i<ARRAYSIZE(iDirectEq) && (k = iDirectEq[i])>=0 ){
+ /* 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( k<nExpr );
+ pTerm = &aExpr[k];
+ assert( pTerm->p!=0 );
+ assert( pTerm->idxLeft==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; j<nColumn; j++){
+ for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
+ Expr *pX = pTerm->p;
+ 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<ARRAYSIZE(iDirectLt) && (iDirectLt[i]>=0 || iDirectGt[i]>=0) ){
+ /* Case 3: We have an inequality comparison against the ROWID field.
+ */
+ int testOp = OP_Noop;
+ int start;
+ int bRev = pLevel->bRev;
+
+ assert( omitTable==0 );
+ brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
+ cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
+ if( bRev ){
+ int t = iDirectGt[i];
+ iDirectGt[i] = iDirectLt[i];
+ iDirectLt[i] = t;
+ }
+ if( iDirectGt[i]>=0 ){
+ Expr *pX;
+ k = iDirectGt[i];
+ assert( k<nExpr );
+ pTerm = &aExpr[k];
+ pX = pTerm->p;
+ assert( pX!=0 );
+ assert( pTerm->idxLeft==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);
+ }else{
+ sqlite3VdbeAddOp(v, bRev ? OP_Last : OP_Rewind, iCur, brk);
+ }
+ if( iDirectLt[i]>=0 ){
+ Expr *pX;
+ k = iDirectLt[i];
+ assert( k<nExpr );
+ pTerm = &aExpr[k];
+ pX = pTerm->p;
+ assert( pX!=0 );
+ assert( pTerm->idxLeft==iCur );
+ sqlite3ExprCode(pParse, pX->pRight);
+ pLevel->iMem = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
+ if( pX->op==TK_LT || pX->op==TK_GT ){
+ testOp = bRev ? OP_Le : OP_Ge;
+ }else{
+ testOp = bRev ? OP_Lt : OP_Gt;
+ }
+ disableTerm(pLevel, &pTerm->p);
+ }
+ start = sqlite3VdbeCurrentAddr(v);
+ pLevel->op = bRev ? OP_Prev : OP_Next;
+ pLevel->p1 = iCur;
+ pLevel->p2 = start;
+ if( testOp!=OP_Noop ){
+ sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
+ 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
+ ** 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.
+ **
+ ** 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 leFlag=0, geFlag=0;
+ int testOp;
+
+ /* Evaluate the equality constraints
+ */
+ for(j=0; j<nEqColumn; j++){
+ int iIdxCol = pIdx->aiColumn[j];
+ for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
+ Expr *pX = pTerm->p;
+ 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;
+ }
+ }
+ }
+
+ /* 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; j<nEqColumn; j++){
+ sqlite3VdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
+ }
+
+ /* Labels for the beginning and end of the loop
+ */
+ cont = pLevel->cont = 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.
+ **
+ ** 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; k<nExpr; k++, pTerm++){
+ Expr *pX = pTerm->p;
+ 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;
+ }
+ }
+ testOp = OP_IdxGE;
+ }else{
+ testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop;
+ leFlag = 1;
+ }
+ if( testOp!=OP_Noop ){
+ int nCol = nEqColumn + ((score & 4)!=0);
+ pLevel->iMem = pParse->nMem++;
+ buildIndexProbe(v, nCol, brk, pIdx);
+ if( pLevel->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 ){
+ sqlite3VdbeAddOp(v, OP_Last, iIdxCur, brk);
+ }
+
+ /* Generate the start key. This is the key that defines the lower
+ ** bound on the search. There is no start key if there are no
+ ** equality terms and if there is no "X>..." term. In
+ ** that case, generate a "Rewind" instruction in place of the
+ ** start key search.
+ **
+ ** 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; k<nExpr; k++, pTerm++){
+ Expr *pX = pTerm->p;
+ 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;
+ }
+ }
+ }else{
+ geFlag = 1;
+ }
+ if( nEqColumn>0 || (score&8)!=0 ){
+ int nCol = nEqColumn + ((score&8)!=0);
+ buildIndexProbe(v, nCol, brk, pIdx);
+ if( pLevel->bRev ){
+ pLevel->iMem = pParse->nMem++;
+ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
+ testOp = OP_IdxLT;
+ }else{
+ int op = geFlag ? OP_MoveGe : OP_MoveGt;
+ sqlite3VdbeAddOp(v, op, iIdxCur, brk);
+ }
+ }else if( pLevel->bRev ){
+ testOp = OP_Noop;
+ }else{
+ sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, brk);
+ }
+
+ /* Generate the the top of the loop. If there is a termination
+ ** key we have to test for that key and abort at the top of the
+ ** loop.
+ */
+ start = sqlite3VdbeCurrentAddr(v);
+ if( testOp!=OP_Noop ){
+ sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
+ sqlite3VdbeAddOp(v, testOp, iIdxCur, brk);
+ if( (leFlag && !pLevel->bRev) || (!geFlag && pLevel->bRev) ){
+ sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
+ sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont);
+ if( !omitTable ){
+ sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
+ sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
+ }
+
+ /* Record the instruction used to terminate the loop.
+ */
+ pLevel->op = pLevel->bRev ? OP_Prev : OP_Next;
+ pLevel->p1 = iIdxCur;
+ pLevel->p2 = start;
+ }
+ loopMask |= 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; j<nExpr; j++, pTerm++){
+ if( pTerm->p==0 ) continue;
+ if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;
+ if( pLevel->iLeftJoin && !ExprHasProperty(pTerm->p,EP_FromJoin) ){
+ continue;
+ }
+ sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1);
+ pTerm->p = 0;
+ }
+ 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.
+ */
+ if( pLevel->iLeftJoin ){
+ pLevel->top = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
+ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
+ VdbeComment((v, "# record LEFT JOIN hit"));
+ for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
+ if( pTerm->p==0 ) continue;
+ if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;
+ sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1);
+ pTerm->p = 0;
+ }
+ }
+ }
+ pWInfo->iContinue = cont;
+ freeMaskSet(&maskSet);
+ return pWInfo;
+}
+
+/*
+** Generate the end of the WHERE loop. See comments on
+** sqlite3WhereBegin() for additional information.
+*/
+void sqlite3WhereEnd(WhereInfo *pWInfo){
+ Vdbe *v = pWInfo->pParse->pVdbe;
+ int i;
+ WhereLevel *pLevel;
+ SrcList *pTabList = pWInfo->pTabList;
+ struct SrcList_item *pTabItem;
+
+ /* Generate loop termination code.
+ */
+ for(i=pTabList->nSrc-1; i>=0; i--){
+ pLevel = &pWInfo->a[i];
+ sqlite3VdbeResolveLabel(v, pLevel->cont);
+ if( pLevel->op!=OP_Noop ){
+ 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->iLeftJoin ){
+ int addr;
+ addr = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
+ sqlite3VdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iIdxCur>=0));
+ sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
+ if( pLevel->iIdxCur>=0 ){
+ sqlite3VdbeAddOp(v, OP_NullRow, pLevel->iIdxCur, 0);
+ }
+ sqlite3VdbeAddOp(v, OP_Goto, 0, pLevel->top);
+ }
+ }
+
+ /* The "break" point is here, just past the end of the outer loop.
+ ** Set it.
+ */
+ sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
+
+ /* Close all of the cursors that were opend by sqlite3WhereBegin.
+ */
+ pLevel = pWInfo->a;
+ pTabItem = pTabList->a;
+ for(i=0; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
+ Table *pTab = pTabItem->pTab;
+ assert( pTab!=0 );
+ if( pTab->isTransient || pTab->pSelect ) continue;
+ if( (pLevel->score & 1)==0 ){
+ sqlite3VdbeAddOp(v, OP_Close, pTabItem->iCursor, 0);
+ }
+ if( pLevel->pIdx!=0 ){
+ sqlite3VdbeAddOp(v, OP_Close, pLevel->iIdxCur, 0);
+ }
+
+ /* Make cursor substitutions for cases where we want to use
+ ** just the index and never reference the table.
+ **
+ ** Calls to the code generator in between sqlite3WhereBegin and
+ ** sqlite3WhereEnd will have created code that references the table
+ ** directly. This loop scans all that code looking for opcodes
+ ** that reference the table and converts them into opcodes that
+ ** reference the index.
+ */
+ if( pLevel->score & 1 ){
+ int i, j, last;
+ VdbeOp *pOp;
+ Index *pIdx = pLevel->pIdx;
+
+ assert( pIdx!=0 );
+ pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
+ last = sqlite3VdbeCurrentAddr(v);
+ for(i=pWInfo->iTop; i<last; i++, pOp++){
+ if( pOp->p1!=pLevel->iTabCur ) continue;
+ if( pOp->opcode==OP_Column ){
+ pOp->p1 = pLevel->iIdxCur;
+ for(j=0; j<pIdx->nColumn; j++){
+ if( pOp->p2==pIdx->aiColumn[j] ){
+ pOp->p2 = j;
+ break;
+ }
+ }
+ }else if( pOp->opcode==OP_Rowid ){
+ pOp->p1 = pLevel->iIdxCur;
+ pOp->opcode = OP_IdxRowid;
+ }else if( pOp->opcode==OP_NullRow ){
+ pOp->opcode = OP_Noop;
+ }
+ }
+ }
+ }
+
+ /* Final cleanup
+ */
+ sqliteFree(pWInfo);
+ return;
+}